[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