Commit | Line | Data |
---|---|---|
f179d8ba FT |
1 | package dolda.jsvc.j2ee; |
2 | ||
3 | import java.util.*; | |
4 | import java.io.*; | |
5 | import java.net.*; | |
6 | import java.util.zip.*; | |
7 | import java.util.jar.*; | |
8 | ||
9 | public 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 | } |