1 package dolda.jsvc.j2ee;
6 import java.util.zip.*;
7 import java.util.jar.*;
10 private Properties props = defprops();
11 private JarOutputStream zipout = null;
12 private final OutputStream realout;
14 public Archive(OutputStream out) {
18 private void initzip() throws IOException {
19 Manifest man = new Manifest();
20 man.getMainAttributes().put(new Attributes.Name("Manifest-Version"), "1.0");
21 man.getMainAttributes().put(new Attributes.Name("Created-By"), "jsvc");
22 JarOutputStream zip = new JarOutputStream(realout, man);
23 zip.putNextEntry(new ZipEntry("WEB-INF/"));
24 zip.putNextEntry(new ZipEntry("WEB-INF/lib/"));
28 private ZipOutputStream zip() throws IOException {
34 public void putprop(String key, String val) {
38 public void loadprops(InputStream in) throws IOException {
42 public void jarprops(String[] jars, String propres) throws IOException {
43 URL[] urls = new URL[jars.length];
45 for(int i = 0; i < jars.length; i++)
46 urls[i] = new URL("file", "", jars[i]);
47 } catch(MalformedURLException e) {
50 ClassLoader cl = new URLClassLoader(urls);
51 InputStream in = cl.getResourceAsStream(propres);
61 private static Properties defprops() {
62 Properties props = new Properties();
63 props.put("jsvc.j2ee.webxml.coding", "UTF-8");
67 private static void cpstream(InputStream in, OutputStream out) throws IOException {
68 byte[] buf = new byte[4096];
70 int ret = in.read(buf, 0, buf.length);
73 out.write(buf, 0, ret);
77 private static String subst(String ln, Properties props) {
79 while((p = ln.indexOf("${", p)) >= 0) {
80 int p2 = ln.indexOf('}', p + 2);
81 String pn = ln.substring(p + 2, p2);
82 String pv = (String)props.get(pn);
84 throw(new RuntimeException("Missing required property " + pn));
85 ln = ln.substring(0, p) + pv + ln.substring(p2 + 1);
91 private void writewebxml() throws IOException {
92 zip().putNextEntry(new ZipEntry("WEB-INF/web.xml"));
93 InputStream tmpl = Archive.class.getResourceAsStream("web.xml.template");
94 String cs = (String)props.get("jsvc.j2ee.webxml.coding");
96 BufferedReader r = new BufferedReader(new InputStreamReader(tmpl, "US-ASCII"));
97 BufferedWriter w = new BufferedWriter(new OutputStreamWriter(zip(), cs));
99 while((ln = r.readLine()) != null) {
100 w.write(subst(ln, props));
109 public void addcode(String name, InputStream in) throws IOException {
110 zip().putNextEntry(new ZipEntry("WEB-INF/classes/" + name));
114 private static String basename(String fn) {
115 int p = fn.lastIndexOf('/');
117 return(fn.substring(p + 1));
121 public void addjars(String[] jars) throws IOException {
122 jarprops(jars, "/jsvc.properties");
123 ZipOutputStream zip = zip();
124 for(String jar : jars) {
125 zip.putNextEntry(new ZipEntry("WEB-INF/lib/" + basename(jar)));
126 InputStream jarin = new FileInputStream(jar);
128 cpstream(jarin, zip);
135 public void finish() throws IOException {
139 private static void usage(PrintStream out) {
140 out.println("usage: dolda.jsvc.j2ee.Archive [-h] [-p PROPFILE] [-n DISPLAY-NAME] [(-c CODE-FILE)...] WAR-FILE JAR-FILE...");
143 public static void main(String[] args) throws IOException {
144 PosixArgs opt = PosixArgs.getopt(args, "hp:n:c:");
149 if(opt.rest.length < 2) {
153 String war = opt.rest[0];
154 String[] jars = Arrays.copyOfRange(opt.rest, 1, opt.rest.length);
156 OutputStream out = new FileOutputStream(war);
158 Archive ar = new Archive(out);
160 for(char c : opt.parsed()) {
164 InputStream in = new FileInputStream(opt.arg);
173 ar.putprop("jsvc.j2ee.appname", opt.arg);
177 InputStream in = new FileInputStream(opt.arg);
179 ar.addcode(basename(opt.arg), in);