Unfortunately, as Neal pointed out, the resulting Java file wasn't very closure-esque. Here is the same idea, cleaned up.
The new file does this:
- Accepts a search directory and a target string
- Recursively traverses the search directory and, for each file found, applies a concept
- The concept is, in essence, a closure. In this case, the concept is to (a) check to see if the file is a jar and, if so, (b) check the entry list of the jar for a target string
- The key is that we now have an algorithm that calls a block of code. The block of code is bundled with any local state that it needs to process the input parameters.
import java.io.*;
import java.util.jar.*;
import java.util.Enumeration;
import java.util.*;
class FileExtension {
private String dirStr = null;
public FileExtension(String dirStr) {
this.dirStr = dirStr;
}
// @param block a closure
// @throws IOException (because the closure declares it)
// This method will recursively traverse a directory
// structure and call block for every file found.
public void eachFileRecurse(
{ File => void throws IOException } block
) throws IOException {
File file = new File(dirStr);
for( File thisFile : file.listFiles() ) {
if( thisFile.isFile() ) {
// file
block.invoke( thisFile );
} else {
// dir
FileExtension subFileExtension =
new FileExtension( thisFile.toString() );
subFileExtension.eachFileRecurse( block );
}
}
}
}
public class JarSearcher2 {
static final private String JAR = ".jar";
static private String target;
// closure block
// Iterates through a directory tree and applies the
// closure to each file
// @param file an input file
// @free JAR used as an extension
// @free a target string in a jar's list of entries
// @throws IOException
static private { File => void throws IOException } myClosure =
{ File file =>
String fileName = file.getName();
if( fileName.contains(JAR) ) {
JarFile jarFile = new JarFile(file);
// old-style Enumeration
// don't blame me or closures!
for( Enumeration e = jarFile.entries() ;
e.hasMoreElements() ; ) {
JarEntry entry = (JarEntry) e.nextElement();
if( entry.getName().contains(target) ) {
System.out.println("found " + target
+ " in: " + file.toString() );
}
}
}
};
// iterates through a directory tree and applies the
// closure to each file
// @param args[]
// @throws IOException
public static void main(String[] args) throws IOException {
String searchDirStr = args[0];
target = args[1];
(new FileExtension(searchDirStr)).eachFileRecurse( myClosure );
}
}
When dealing with Enumerations a static utility method is quite useful.
ReplyDeletepublic static Iterable iterate(Enumeration enum) { ... }
Then you can write:
for (File file: iterate(entries)) {
...
}
Peace
-stephan
--
Stephan Schmidt :: stephan@reposita.org
Reposita Open Source - Monitor your software development
http://www.reposita.org
Blog at http://stephan.reposita.org - No signal. No noise.