[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Thu Nov 23 19:28:59 UTC 2006


gordonp
Thu Nov 23 14:28:59 EST 2006
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util
In directory dev.open-bio.org:/tmp/cvs-serv24794/src/main/ca/ucalgary/seahawk/util

Modified Files:
	MinJarMaker.java 
Log Message:
Improvements to Minnow completeness (grabbing extra specified files to the JAR from file or other JARs)
moby-live/Java/src/main/ca/ucalgary/seahawk/util MinJarMaker.java,1.2,1.3
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/MinJarMaker.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/MinJarMaker.java	2006/11/01 23:45:36	1.2
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/seahawk/util/MinJarMaker.java	2006/11/23 19:28:58	1.3
@@ -5,6 +5,7 @@
 import java.util.*;
 import java.util.jar.*;
 import java.net.URL;
+import java.util.regex.Pattern;
 
 /**
  * This class should be called from the command line using a "clean" JVM
@@ -51,7 +52,7 @@
 	// Check arguments
 	if (args.length < 2) {
 	    System.err.println("Usage:\n\n");
-	    System.err.println("java -cp /dir/containing/only/the/MinJarMaker/class/file -Djarmaker.class.path=$CLASSPATH MinJarMaker main_output.jar [-s | -sw indexoutfile.xml] Program [args...]");
+	    System.err.println("java -cp /dir/containing/only/the/MinJarMaker/class/file -Djarmaker.class.extras=\"extra/classes/to/include.class\" -Djarmaker.class.path=$CLASSPATH MinJarMaker main_output.jar [-s | -sw indexoutfile.xml] Program [args...]");
 	    System.err.println("Where -s causes the creation of secondary jar files for each package that doesn't");
 	    System.err.println("have all of its classes loaded (i.e. may be loaded in further program execution)");
 	    System.err.println("Where -sw also creates a Web Start document fragment describing the location of");
@@ -439,6 +440,147 @@
 	jout.closeEntry();
     }
 
+    protected void addExtraClasses(Set classes){
+	StringTokenizer extraClassesTokens = new StringTokenizer(System.getProperty("jarmaker.class.extras"), 
+								 File.pathSeparator);
+	while(extraClassesTokens.hasMoreElements()){
+	    String classPathElement = extraClassesTokens.nextToken();
+	    // A literal class to include, not a pattern
+	    if(classPathElement.indexOf("*") == -1){
+		byte[] classBytes = null;
+		try{
+		    classBytes = getClassBytes(classPathElement);
+		}
+		catch(Exception e){
+		    System.err.println("While trying to get extra class " + classPathElement);
+		    e.printStackTrace();
+		}
+		if(classBytes == null){
+		    System.err.println("Could not find the specified extra class: " + 
+				       classPathElement);
+		    continue;
+		}
+		classes.add(classPathElement);
+	    }
+	    // A class pattern that we must find all matches for
+	    else{
+		Set matchedClasses = getMatchingClasses(classPathElement);
+		if(matchedClasses == null || matchedClasses.size() == 0){
+		    System.err.println("Could not find any classes matching the pattern specified for extra class: " + 
+				       classPathElement);
+		    continue;
+		}
+		classes.addAll(matchedClasses);
+	    }
+	}
+    }
+
+    protected Set findDirMatches(String pathPrefix, File dir, Pattern p, boolean recursive){
+	Set matches = new HashSet();
+
+	String[] files = dir.list();
+	for(int i = 0; i < files.length; i++){
+	    if(files[i].indexOf(".") == 0){
+		// skip hidden UNIX files, current dir, parent dir
+		continue;
+	    }
+	    File file = new File(dir, files[i]);
+	    if(recursive && file.isDirectory()){
+		matches.addAll(findDirMatches(pathPrefix, file, p, recursive));
+	    }
+	    else if(p.matcher(files[i]).matches()){
+		// This will mess up on windows, because the file separator \ will be an escape...
+		matches.add(file.getPath().replace(pathPrefix, ""));
+	    }
+	}
+
+	return matches;
+    }
+
+    /**
+     * The pattern may have the form of an Ant path specification, i.e. "*" matches anything in a directory, 
+     * and "**" matches anything in any subdirectory.
+     */
+    protected Set getMatchingClasses(String pattern){
+	Set results = new HashSet();
+
+	// This code largely copied from the getResourceURL method, with mods for asterisk handling
+	StringTokenizer classPathTokens = new StringTokenizer(System.getProperty("jarmaker.class.path"), 
+							      File.pathSeparator);
+	while(classPathTokens.hasMoreElements()){
+	    String pathElement = classPathTokens.nextToken();
+	    String path = pathElement + File.separator + pattern;
+	    String parentPattern = "";
+	    if(pattern.indexOf(File.separator) != -1 &&
+	       pattern.indexOf(File.separator) != pattern.length()-1){
+		parentPattern = pattern.substring(0, pattern.lastIndexOf(File.separator)+1);
+	    }
+
+	    boolean recursive = false;
+	    if(path.indexOf("**"+File.separator) != -1){
+		recursive = true;
+		path = path.replaceAll("\\*\\*"+File.separator, "");
+		parentPattern = parentPattern.replaceAll("\\*\\*"+File.separator, "(.*/)?");
+	    }
+
+	    File pathPattern = new File(path);
+	    File pathParent = pathPattern.getParentFile();
+
+	    // For now, we only take * or ** in the last part of the pattern 
+	    // (i.e. specific subdirectories cannot be specified after an asterisk, unless it's in a jar)
+	    String patternWildcard = pathPattern.getName();
+	    // Turn the asterisked patterns into into regexs
+	    if(patternWildcard.indexOf("**") != -1 && !recursive){
+		recursive = true;
+	    }
+	    patternWildcard = patternWildcard.replaceAll("\\.", "\\\\."); // turn all periods into literal periods
+	    patternWildcard = patternWildcard.replaceFirst("\\Q$\\E", "\\\\\\$"); // turn any $ into a literal one
+	    patternWildcard = patternWildcard.replaceAll("\\*{1,2}", ".*");
+	    // Must match the entirety of the name (anchor start and end of regex 
+	    // to start and end of the file name to be compared to)
+	    Pattern filep = Pattern.compile("^"+patternWildcard+"$");
+	    Pattern jarp = Pattern.compile("^"+parentPattern+ 
+					   (recursive ? "(.*/)?" : "") + 
+					   patternWildcard.replaceAll(File.separator, "/")+"$");
+
+	    // The path exists in the file system
+	    if(pathParent == null || pathParent.isDirectory()){
+		results.addAll(findDirMatches(pathElement + File.separator, pathParent, filep, recursive));
+	    }
+	    else{
+
+		// If it's not a valid file system path, maybe it's in a JAR
+		File f = new File(pathElement);
+		if(f.isFile()){
+		    JarFile jarFile = null;
+		    try{
+			jarFile = new JarFile(f);
+		    }
+		    catch(Exception e){
+			System.err.println("Class path element " + pathElement + 
+					   " was not a directory, or a valid JAR file");
+			continue;
+		    }
+		    
+		    for(Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) {
+			JarEntry entry = entries.nextElement();
+			if(jarp.matcher(entry.getName()).matches()){
+			    results.add(entry.getName());
+			}
+		    }
+		    
+		    try{
+			jarFile.close();
+		    }
+		    catch(IOException ioe){
+			System.err.println("Couldn't close JAR file: " + pathElement);
+		    }
+		} //end if file (jar)
+	    }  //end else if not dir
+	}  //end for extra class path elements
+	return results;
+    }
+
     protected void dumpJar( String jarfile )
 	throws IOException {
 	// Get the list of classes
@@ -447,6 +589,8 @@
         corePackages = new Hashtable();
 	int partId = 1;  //ID for part names in JNLP file (shorter than full package name to save space)
 	
+	addExtraClasses(loadedClasses);
+
 	synchronized( loadedClasses ) {
 	    // Open up a new JAR file
 	    FileOutputStream fout = new FileOutputStream( jarfile );




More information about the MOBY-guts mailing list