Searching Jars with Java Closures (original) (raw)

(Ed's note: see this post for a better example of closures. This one is intended for direct contrast with a Groovy script: the resulting Java is awkward.)

The last post has a "Hello World", of sorts, for Neal Gafter's closure proposal.

In it, I mentioned that I have converted a Groovy jar searcher into pure Java, using Neal Gafter's prototype.

Here is the code. It is probably best to understand the previous post before looking into this. I may also be instructive to understand the Groovy code first.

The code is documented but here is a view from space:

(Btw, if you find the example less-than-elegant, blame me, not closures. The intent is not to introduce closures, per se, but instead to illustrate the new Java syntax by leveraging a simple-yet-useful program implemented in Groovy.)

import java.io.;
import java.util.jar.
;
import java.util.Enumeration;

public class JarSearcher {

private String target;
private String fileName;

// This closure checks a JarEntry's name for a target string
// @param jarEntry
// @return boolean true if found
// @free target the string we're looking for
// ('free' is my way of denoting a free variable)

private { JarEntry => boolean } myEntryChecker = {
JarEntry jarEntry =>
// expression! no return statement or semi-colon
// Thanks to Christian Ullenboom for the simpler version
jarEntry.getName().contains(target)
};

// This closure iterates over the entries in a jar file and
// checks each one for a target string (via another closure)
// @param file
// @return int # of occurences
// @throws IOException
// @free myEntryChecker
// ('free' is my way of denoting a free variable)

private { File => int throws IOException } myFileChecker = {
File file =>
int count = 0;

fileName = file.getName();

if( fileName.indexOf(".jar") != -1 ) {

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( myEntryChecker.invoke(entry) ) {
count++;
}
}
}

// expression! no return statement
count
};

// This method lists the files in a directory and
// uses a closure to check each file for a target
// string (if it is a jar file)
// @param args[]
// @throws IOException (because the closure declares it)

public void run(String[] args) throws IOException {
String searchDirStr = args[0];
target = args[1];

File searchDir = new File(searchDirStr);

// NOTE: Neal has a proposal that would make this
// iteration much easier
for(File file : searchDir.listFiles() ) {
int count = myFileChecker.invoke(file);

if( count != 0 ) {
System.out.println(
"found " + count + " match(es) in " + fileName );
}
}
}

public static void main(String[] args) {
try {
JarSearcher jarSearcher = new JarSearcher();
jarSearcher.run(args);
} catch(Exception ex) {
// TODO
}
}
}