Wrote an ant task to create jsvc war files.
authorFredrik Tolf <fredrik@dolda2000.com>
Mon, 12 Oct 2009 19:33:27 +0000 (21:33 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Mon, 12 Oct 2009 19:33:27 +0000 (21:33 +0200)
build.xml
src/dolda/jsvc/j2ee/Archive.java

index 309c9b3..c7a3065 100644 (file)
--- a/build.xml
+++ b/build.xml
         <jar destfile="build/jsvc.jar" basedir="build/bin" />
     </target>
     
-    <target name="test-jar" depends="build-env, jsvc-jar">
+    <target name="test-war" depends="build-env, jsvc-jar">
+      <taskdef name="jsvc-war" classname="dolda.jsvc.j2ee.Archive$AntTask" classpath="build/jsvc.jar" />
       <copy tofile="build/test-bin/jsvc.properties" file="etc/test.jsvc.properties" />
       <jar destfile="build/jsvc-test.jar" basedir="build/test-bin" />
+      <jsvc-war destfile="build/jsvc-test.war">
+       <jars dir="build">
+         <include name="jsvc.jar" />
+         <include name="jsvc-test.jar" />
+       </jars>
+      </jsvc-war>
     </target>
     
     <target name="clean">
index c43a156..b5893be 100644 (file)
@@ -39,11 +39,11 @@ public class Archive {
        props.load(in);
     }
 
-    public void jarprops(String[] jars, String propres) throws IOException {
+    public void jarprops(File[] jars, String propres) throws IOException {
        URL[] urls = new URL[jars.length];
        try {
            for(int i = 0; i < jars.length; i++)
-               urls[i] = new URL("file", "", jars[i]);
+               urls[i] = new URL("file", "", jars[i].toString());
        } catch(MalformedURLException e) {
            throw(new Error(e));
        }
@@ -74,6 +74,15 @@ public class Archive {
         }
     }
 
+    private static class MissingPropException extends RuntimeException {
+       public final String prop;
+       
+       private MissingPropException(String prop) {
+           super("Missing required property " + prop);
+           this.prop = prop;
+       }
+    }
+
     private static String subst(String ln, Properties props) {
        int p = 0;
        while((p = ln.indexOf("${", p)) >= 0) {
@@ -81,7 +90,7 @@ public class Archive {
            String pn = ln.substring(p + 2, p2);
            String pv = (String)props.get(pn);
            if(pv == null)
-               throw(new RuntimeException("Missing required property " + pn));
+               throw(new MissingPropException(pn));
            ln = ln.substring(0, p) + pv + ln.substring(p2 + 1);
            p = p + pv.length();
        }
@@ -111,18 +120,11 @@ public class Archive {
        cpstream(in, zip());
     }
 
-    private static String basename(String fn) {
-       int p = fn.lastIndexOf('/');
-       if(p >= 0)
-           return(fn.substring(p + 1));
-       return(fn);
-    }
-
-    public void addjars(String[] jars) throws IOException {
+    public void addjars(File[] jars) throws IOException {
        jarprops(jars, "jsvc.properties");
        ZipOutputStream zip = zip();
-       for(String jar : jars) {
-           zip.putNextEntry(new ZipEntry("WEB-INF/lib/" + basename(jar)));
+       for(File jar : jars) {
+           zip.putNextEntry(new ZipEntry("WEB-INF/lib/" + jar.getName()));
            InputStream jarin = new FileInputStream(jar);
            try {
                cpstream(jarin, zip);
@@ -135,6 +137,117 @@ public class Archive {
     public void finish() throws IOException {
        zip().finish();
     }
+    
+    public static class AntTask extends org.apache.tools.ant.Task {
+       private org.apache.tools.ant.types.FileSet jars, code;
+       private File props, outfile;
+       private String appname;
+       
+       private static File[] getfiles(org.apache.tools.ant.types.FileSet fs) {
+           org.apache.tools.ant.DirectoryScanner ds = fs.getDirectoryScanner();
+           ds.scan();
+           String[] nms = ds.getIncludedFiles();
+           File[] ret = new File[nms.length];
+           for(int i = 0; i < nms.length; i++)
+               ret[i] = new File(ds.getBasedir(), nms[i]);
+           return(ret);
+       }
+
+       private void rebuild(File[] jars, File[] code) throws IOException {
+           OutputStream out = new FileOutputStream(outfile);
+           
+           System.out.println("Building " + outfile);
+           
+           try {
+               Archive ar = new Archive(out);
+               if(appname != null)
+                   ar.putprop("jsvc.j2ee.appname", appname);
+               if(props != null) {
+                   InputStream in = new FileInputStream(props);
+                   try {
+                       ar.loadprops(in);
+                   } finally {
+                       in.close();
+                   }
+               }
+               
+               for(File f : code) {
+                   InputStream in = new FileInputStream(f);
+                   try {
+                       ar.addcode(f.getName(), in);
+                   } finally {
+                       in.close();
+                   }
+               }
+               
+               ar.addjars(jars);
+               ar.writewebxml();
+               
+               ar.finish();
+           } catch(MissingPropException e) {
+               throw(new org.apache.tools.ant.BuildException(e.getMessage(), e));
+           } finally {
+               out.close();
+           }
+       }
+       
+       public void execute() {
+           File[] jars = (this.jars != null)?getfiles(this.jars):new File[0];
+           File[] code = (this.code != null)?getfiles(this.code):new File[0];
+           if(jars.length < 1)
+               throw(new org.apache.tools.ant.BuildException("Must have at least one JAR file", getLocation()));
+           if(outfile == null)
+               throw(new org.apache.tools.ant.BuildException("No output file specified", getLocation()));
+           
+           Collection<File> deps = new LinkedList<File>();
+           deps.addAll(Arrays.asList(jars));
+           deps.addAll(Arrays.asList(code));
+           if(props != null)
+               deps.add(props);
+           
+           boolean rebuild = false;
+           for(File dep : deps) {
+               if(!dep.exists())
+                   throw(new org.apache.tools.ant.BuildException(dep + " does not exist", getLocation()));
+               if(dep.lastModified() > outfile.lastModified()) {
+                   rebuild = true;
+                   break;
+               }
+           }
+           
+           if(rebuild) {
+               try {
+                   rebuild(jars, code);
+               } catch(IOException e) {
+                   throw(new org.apache.tools.ant.BuildException(e));
+               }
+           }
+       }
+
+       public void addJars(org.apache.tools.ant.types.FileSet path) {
+           this.jars = path;
+       }
+       
+       public void setJars(org.apache.tools.ant.types.FileSet path) {
+           this.jars = path;
+       }
+       
+       public void setCode(org.apache.tools.ant.types.FileSet path) {
+           this.code = path;
+       }
+       
+       public void setPropfile(File propfile) {
+           this.props = propfile;
+       }
+       
+       public void setDestfile(File outfile) {
+           this.outfile = outfile;
+       }
+       
+       public void setAppname(String name) {
+           this.appname = name;
+       }
+    }
 
     private static void usage(PrintStream out) {
        out.println("usage: dolda.jsvc.j2ee.Archive [-h] [-p PROPFILE] [-n DISPLAY-NAME] [(-c CODE-FILE)...] WAR-FILE JAR-FILE...");
@@ -151,7 +264,9 @@ public class Archive {
            System.exit(1);
        }
        String war = opt.rest[0];
-       String[] jars = Arrays.copyOfRange(opt.rest, 1, opt.rest.length);
+       File[] jars = new File[opt.rest.length - 1];
+       for(int i = 1; i < opt.rest.length; i++)
+           jars[i - 1] = new File(opt.rest[i]);
        
        OutputStream out = new FileOutputStream(war);
        try {
@@ -174,9 +289,10 @@ public class Archive {
                    break;
                case 'c':
                    {
-                       InputStream in = new FileInputStream(opt.arg);
+                       File f = new File(opt.arg);
+                       InputStream in = new FileInputStream(f);
                        try {
-                           ar.addcode(basename(opt.arg), in);
+                           ar.addcode(f.getName(), in);
                        } finally {
                            in.close();
                        }