X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fdolda%2Fjsvc%2Fj2ee%2FArchive.java;h=4a4dc01d89ba0cb0255b6d61cab7868ccb4a6bee;hb=7779099a6c15508f2dd214a7555c66a27f8343ed;hp=ee9f26ee180bf32e71aac8a2c3ab058a01c25bd2;hpb=f179d8ba3acb55d1419a9de851d0fcf996798cc4;p=jsvc.git diff --git a/src/dolda/jsvc/j2ee/Archive.java b/src/dolda/jsvc/j2ee/Archive.java index ee9f26e..4a4dc01 100644 --- a/src/dolda/jsvc/j2ee/Archive.java +++ b/src/dolda/jsvc/j2ee/Archive.java @@ -1,5 +1,6 @@ package dolda.jsvc.j2ee; +import dolda.jsvc.util.*; import java.util.*; import java.io.*; import java.net.*; @@ -7,15 +8,43 @@ import java.util.zip.*; import java.util.jar.*; public class Archive { - private static void usage(PrintStream out) { - out.println("usage: dolda.jsvc.j2ee.Archive [-h] [-p PROPFILE] [-n DISPLAY-NAME] WAR-FILE JAR-FILE..."); + private Properties props = defprops(); + private JarOutputStream zipout = null; + private final OutputStream realout; + + public Archive(OutputStream out) { + this.realout = out; + } + + private void initzip() throws IOException { + Manifest man = new Manifest(); + man.getMainAttributes().put(new Attributes.Name("Manifest-Version"), "1.0"); + man.getMainAttributes().put(new Attributes.Name("Created-By"), "jsvc"); + JarOutputStream zip = new JarOutputStream(realout, man); + zip.putNextEntry(new ZipEntry("WEB-INF/")); + zip.putNextEntry(new ZipEntry("WEB-INF/lib/")); + this.zipout = zip; + } + + private ZipOutputStream zip() throws IOException { + if(zipout == null) + initzip(); + return(this.zipout); } - private static void jarprops(String[] jars, String propres, Properties props) throws IOException { + public void putprop(String key, String val) { + props.put(key, val); + } + + public void loadprops(InputStream in) throws IOException { + props.load(in); + } + + 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)); } @@ -36,14 +65,13 @@ public class Archive { return(props); } - private static void cpstream(InputStream in, OutputStream out) throws IOException { - byte[] buf = new byte[4096]; - while(true) { - int ret = in.read(buf, 0, buf.length); - if(ret < 0) - return; - out.write(buf, 0, ret); - } + 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) { @@ -53,19 +81,20 @@ 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(); } return(ln); } - private static void writewebxml(Properties props, OutputStream out) throws IOException { + private void writewebxml() throws IOException { + zip().putNextEntry(new ZipEntry("WEB-INF/web.xml")); InputStream tmpl = Archive.class.getResourceAsStream("web.xml.template"); String cs = (String)props.get("jsvc.j2ee.webxml.coding"); try { BufferedReader r = new BufferedReader(new InputStreamReader(tmpl, "US-ASCII")); - BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out, cs)); + BufferedWriter w = new BufferedWriter(new OutputStreamWriter(zip(), cs)); String ln; while((ln = r.readLine()) != null) { w.write(subst(ln, props)); @@ -77,33 +106,146 @@ public class Archive { } } - public static void makewar(String[] jars, Properties props, OutputStream out) throws IOException { - Manifest man = new Manifest(); - man.getMainAttributes().put(new Attributes.Name("Manifest-Version"), "1.0"); - man.getMainAttributes().put(new Attributes.Name("Created-By"), "jsvc"); - JarOutputStream zip = new JarOutputStream(out, man); - zip.putNextEntry(new ZipEntry("WEB-INF/")); - zip.putNextEntry(new ZipEntry("WEB-INF/lib/")); - for(String jar : jars) { - String bn = jar; - int p = bn.lastIndexOf('/'); - if(p >= 0) - bn = bn.substring(p + 1); - zip.putNextEntry(new ZipEntry("WEB-INF/lib/" + bn)); + public void addcode(String name, InputStream in) throws IOException { + zip().putNextEntry(new ZipEntry("WEB-INF/classes/" + name)); + Misc.cpstream(in, zip()); + } + + public void addjars(File[] jars) throws IOException { + jarprops(jars, "jsvc.properties"); + ZipOutputStream zip = zip(); + for(File jar : jars) { + zip.putNextEntry(new ZipEntry("WEB-INF/lib/" + jar.getName())); InputStream jarin = new FileInputStream(jar); try { - cpstream(jarin, zip); + Misc.cpstream(jarin, zip); } finally { jarin.close(); } } - zip.putNextEntry(new ZipEntry("WEB-INF/web.xml")); - writewebxml(props, zip); - zip.finish(); } + 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 deps = new LinkedList(); + 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..."); + } + public static void main(String[] args) throws IOException { - PosixArgs opt = PosixArgs.getopt(args, "hp:n:"); + PosixArgs opt = PosixArgs.getopt(args, "hp:n:c:"); if(opt == null) { usage(System.err); System.exit(1); @@ -113,35 +255,50 @@ 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]); - Properties props = defprops(); - jarprops(jars, "/jsvc.properties", props); + OutputStream out = new FileOutputStream(war); + try { + Archive ar = new Archive(out); - for(char c : opt.parsed()) { - switch(c) { - case 'p': - { - InputStream in = new FileInputStream(opt.arg); - try { - props.load(in); - } finally { - in.close(); + for(char c : opt.parsed()) { + switch(c) { + case 'p': + { + InputStream in = new FileInputStream(opt.arg); + try { + ar.loadprops(in); + } finally { + in.close(); + } + } + break; + case 'n': + ar.putprop("jsvc.j2ee.appname", opt.arg); + break; + case 'c': + { + File f = new File(opt.arg); + InputStream in = new FileInputStream(f); + try { + ar.addcode(f.getName(), in); + } finally { + in.close(); + } } + break; + case 'h': + usage(System.out); + return; } - break; - case 'n': - props.put("jsvc.j2ee.appname", opt.arg); - break; - case 'h': - usage(System.out); - return; } - } - - OutputStream out = new FileOutputStream(war); - try { - makewar(jars, props, out); + + ar.addjars(jars); + ar.writewebxml(); + + ar.finish(); } finally { out.close(); }