Moved WAR making to an explicit function.
[jsvc.git] / src / dolda / jsvc / j2ee / Archive.java
CommitLineData
f179d8ba
FT
1package dolda.jsvc.j2ee;
2
3import java.util.*;
4import java.io.*;
5import java.net.*;
6import java.util.zip.*;
7import java.util.jar.*;
8
9public class Archive {
10 private static void usage(PrintStream out) {
11 out.println("usage: dolda.jsvc.j2ee.Archive [-h] [-p PROPFILE] [-n DISPLAY-NAME] WAR-FILE JAR-FILE...");
12 }
13
14 private static void jarprops(String[] jars, String propres, Properties props) throws IOException {
15 URL[] urls = new URL[jars.length];
16 try {
17 for(int i = 0; i < jars.length; i++)
18 urls[i] = new URL("file", "", jars[i]);
19 } catch(MalformedURLException e) {
20 throw(new Error(e));
21 }
22 ClassLoader cl = new URLClassLoader(urls);
23 InputStream in = cl.getResourceAsStream(propres);
24 if(in != null) {
25 try {
26 props.load(in);
27 } finally {
28 in.close();
29 }
30 }
31 }
32
33 private static Properties defprops() {
34 Properties props = new Properties();
35 props.put("jsvc.j2ee.webxml.coding", "UTF-8");
36 return(props);
37 }
38
39 private static void cpstream(InputStream in, OutputStream out) throws IOException {
40 byte[] buf = new byte[4096];
41 while(true) {
42 int ret = in.read(buf, 0, buf.length);
43 if(ret < 0)
44 return;
45 out.write(buf, 0, ret);
46 }
47 }
48
49 private static String subst(String ln, Properties props) {
50 int p = 0;
51 while((p = ln.indexOf("${", p)) >= 0) {
52 int p2 = ln.indexOf('}', p + 2);
53 String pn = ln.substring(p + 2, p2);
54 String pv = (String)props.get(pn);
55 if(pv == null)
56 throw(new RuntimeException("Missing required property " + pn));
57 ln = ln.substring(0, p) + pv + ln.substring(p2 + 1);
58 p = p + pv.length();
59 }
60 return(ln);
61 }
62
63 private static void writewebxml(Properties props, OutputStream out) throws IOException {
64 InputStream tmpl = Archive.class.getResourceAsStream("web.xml.template");
65 String cs = (String)props.get("jsvc.j2ee.webxml.coding");
66 try {
67 BufferedReader r = new BufferedReader(new InputStreamReader(tmpl, "US-ASCII"));
68 BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out, cs));
69 String ln;
70 while((ln = r.readLine()) != null) {
71 w.write(subst(ln, props));
72 w.write('\n');
73 }
74 w.flush();
75 } finally {
76 tmpl.close();
77 }
78 }
79
80 public static void makewar(String[] jars, Properties props, OutputStream out) throws IOException {
81 Manifest man = new Manifest();
82 man.getMainAttributes().put(new Attributes.Name("Manifest-Version"), "1.0");
83 man.getMainAttributes().put(new Attributes.Name("Created-By"), "jsvc");
84 JarOutputStream zip = new JarOutputStream(out, man);
85 zip.putNextEntry(new ZipEntry("WEB-INF/"));
86 zip.putNextEntry(new ZipEntry("WEB-INF/lib/"));
87 for(String jar : jars) {
88 String bn = jar;
89 int p = bn.lastIndexOf('/');
90 if(p >= 0)
91 bn = bn.substring(p + 1);
92 zip.putNextEntry(new ZipEntry("WEB-INF/lib/" + bn));
93 InputStream jarin = new FileInputStream(jar);
94 try {
95 cpstream(jarin, zip);
96 } finally {
97 jarin.close();
98 }
99 }
100 zip.putNextEntry(new ZipEntry("WEB-INF/web.xml"));
101 writewebxml(props, zip);
102 zip.finish();
103 }
104
105 public static void main(String[] args) throws IOException {
106 PosixArgs opt = PosixArgs.getopt(args, "hp:n:");
107 if(opt == null) {
108 usage(System.err);
109 System.exit(1);
110 }
111 if(opt.rest.length < 2) {
112 usage(System.err);
113 System.exit(1);
114 }
115 String war = opt.rest[0];
116 String[] jars = Arrays.copyOfRange(opt.rest, 1, opt.rest.length);
117
118 Properties props = defprops();
119 jarprops(jars, "/jsvc.properties", props);
120
121 for(char c : opt.parsed()) {
122 switch(c) {
123 case 'p':
124 {
125 InputStream in = new FileInputStream(opt.arg);
126 try {
127 props.load(in);
128 } finally {
129 in.close();
130 }
131 }
132 break;
133 case 'n':
134 props.put("jsvc.j2ee.appname", opt.arg);
135 break;
136 case 'h':
137 usage(System.out);
138 return;
139 }
140 }
141
142 OutputStream out = new FileOutputStream(war);
143 try {
144 makewar(jars, props, out);
145 } finally {
146 out.close();
147 }
148 }
149}