1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.tools.deploy;
18
19 import java.io.FileInputStream;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.File;
24 import java.nio.channels.FileChannel;
25 import java.util.Enumeration;
26 import java.util.jar.JarFile;
27 import java.util.jar.JarOutputStream;
28 import java.util.zip.ZipEntry;
29
30 import org.jdom.Document;
31 import org.jdom.input.SAXBuilder;
32 import org.jdom.output.Format;
33 import org.jdom.output.XMLOutputter;
34 import org.xml.sax.EntityResolver;
35 import org.xml.sax.InputSource;
36 import org.xml.sax.SAXException;
37
38 /***
39 * Makes a web application Deploy-ready for Jetspeed.
40 *
41 * @author <a href="mailto:taylor@apache.org">Dain Sundstrom </a>
42 * @author <a href="mailto:dsundstrom@gluecode.com">David Sean Taylor </a>
43 * @version $Id: JetspeedDeploy.java 545097 2007-06-07 08:11:56Z ate $
44 */
45 public class JetspeedDeploy implements Deploy
46 {
47 public static void main(String[] args) throws Exception
48 {
49 if (args.length < 2)
50 {
51 printUsage();
52 System.exit(1);
53 return;
54 }
55
56 boolean stripLoggers = false;
57 String version = null;
58 for(int i = 0; i < args.length-2; i++) {
59 String option = args[i];
60 if(option.equals("-s")) {
61 stripLoggers = true;
62 } else if(option.equals("-v") && i < args.length-3) {
63 version = args[i+1];
64 i++;
65 } else {
66
67 printUsage();
68 System.exit(1);
69 return;
70 }
71 }
72
73 new JetspeedDeploy(args[args.length-2], args[args.length-1], stripLoggers, version);
74 }
75
76 private static void printUsage() {
77 System.out.println("Usage: java -jar jetspeed-deploy-tools-<version>.jar [options] INPUT OUTPUT");
78 System.out.println("Options:");
79 System.out.println(" -s: stripLoggers - remove commons-logging[version].jar and/or log4j[version].jar from war");
80 System.out.println(" (required when targetting application servers like JBoss)");
81 System.out.println(" -v VERSION: force servlet specification version to handle web.xml");
82 System.out.println(" (default will automatically determine version)");
83 }
84
85 private final byte[] buffer = new byte[4096];
86
87 public JetspeedDeploy(String inputName, String outputName, boolean stripLoggers) throws Exception {
88 this(inputName, outputName, stripLoggers, null);
89 }
90
91 public JetspeedDeploy(String inputName, String outputName, boolean stripLoggers, String forcedVersion) throws Exception
92 {
93 File tempFile = null;
94 JarFile jin = null;
95 JarOutputStream jout = null;
96 FileChannel srcChannel = null;
97 FileChannel dstChannel = null;
98
99 try
100 {
101 String portletApplicationName = getPortletApplicationName(outputName);
102 tempFile = File.createTempFile(portletApplicationName, "");
103 tempFile.deleteOnExit();
104
105 jin = new JarFile(inputName);
106 jout = new JarOutputStream(new FileOutputStream(tempFile));
107
108
109
110
111 Document webXml = null;
112 Document portletXml = null;
113 Document contextXml = null;
114 boolean taglibFound = false;
115 ZipEntry src;
116 InputStream source;
117 Enumeration zipEntries = jin.entries();
118 while (zipEntries.hasMoreElements())
119 {
120 src = (ZipEntry) zipEntries.nextElement();
121 source = jin.getInputStream(src);
122 try
123 {
124 String target = src.getName();
125 if ("WEB-INF/web.xml".equals(target))
126 {
127 System.out.println("Found web.xml");
128 webXml = parseXml(source);
129 }
130 else if ("WEB-INF/portlet.xml".equals(target))
131 {
132 System.out.println("Found WEB-INF/portlet.xml");
133 portletXml = parseXml(source);
134 }
135 else if ("META-INF/context.xml".equals(target))
136 {
137 System.out.println("Found META-INF/context.xml");
138 contextXml = parseXml(source);
139 }
140 else
141 {
142 if ( stripLoggers && target.endsWith(".jar") &&
143 (target.startsWith("WEB-INF/lib/commons-logging") || target.startsWith("WEB-INF/lib/log4j")))
144 {
145 System.out.println("Stripping logger "+target);
146 continue;
147 }
148 else if ("WEB-INF/tld/portlet.tld".equals(target))
149 {
150 System.out.println("Warning: WEB-INF/tld/portlet.tld already provided, won't be replaced.");
151 taglibFound = true;
152 }
153 addFile(target, source, jout);
154 }
155 }
156 finally
157 {
158 source.close();
159 }
160 }
161
162 if (webXml == null)
163 {
164 throw new IllegalArgumentException("WEB-INF/web.xml");
165 }
166 if (portletXml == null)
167 {
168 throw new IllegalArgumentException("WEB-INF/portlet.xml");
169 }
170
171 JetspeedWebApplicationRewriterFactory webRewriterFactory = new JetspeedWebApplicationRewriterFactory();
172 JetspeedWebApplicationRewriter webRewriter = webRewriterFactory.getInstance(
173 webXml,
174 portletApplicationName,
175 forcedVersion);
176 webRewriter.processWebXML();
177 JetspeedContextRewriter contextRewriter = new JetspeedContextRewriter(contextXml, portletApplicationName);
178 contextRewriter.processContextXML();
179
180
181 addFile("WEB-INF/web.xml", webXml, jout);
182 addFile("WEB-INF/portlet.xml", portletXml, jout);
183 addFile("META-INF/context.xml", contextXml, jout);
184
185 if (!taglibFound)
186 {
187 System.out.println("Attempting to add portlet.tld to war...");
188 InputStream is = this.getClass().getResourceAsStream("/org/apache/jetspeed/tools/deploy/portlet.tld");
189 if (is == null)
190 {
191 System.out.println("Failed to find portlet.tld in classpath");
192 }
193 else
194 {
195 System.out.println("Adding portlet.tld to war...");
196
197 try
198 {
199 addFile("WEB-INF/tld/portlet.tld", is, jout);
200 }
201 finally
202 {
203 is.close();
204 }
205 }
206 }
207
208 jout.close();
209 jin.close();
210 jin = null;
211 jout = null;
212
213 System.out.println("Creating war " + outputName + " ...");
214 System.out.flush();
215
216 srcChannel = new FileInputStream(tempFile).getChannel();
217 dstChannel = new FileOutputStream(outputName).getChannel();
218 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
219 srcChannel.close();
220 srcChannel = null;
221 dstChannel.close();
222 dstChannel = null;
223 tempFile.delete();
224 tempFile = null;
225 System.out.println("War " + outputName + " created");
226 System.out.flush();
227 }
228 finally
229 {
230 if (srcChannel != null && srcChannel.isOpen())
231 {
232 try
233 {
234 srcChannel.close();
235 }
236 catch (IOException e1)
237 {
238
239 }
240 }
241 if (dstChannel != null && dstChannel.isOpen())
242 {
243 try
244 {
245 dstChannel.close();
246 }
247 catch (IOException e1)
248 {
249
250 }
251 }
252 if (jin != null)
253 {
254 try
255 {
256 jin.close();
257 jin = null;
258 }
259 catch (IOException e1)
260 {
261
262 }
263 }
264 if (jout != null)
265 {
266 try
267 {
268 jout.close();
269 jout = null;
270 }
271 catch (IOException e1)
272 {
273
274 }
275 }
276 if (tempFile != null && tempFile.exists())
277 {
278 tempFile.delete();
279 }
280 }
281 }
282
283 protected Document parseXml(InputStream source) throws Exception
284 {
285
286
287 SAXBuilder saxBuilder = new SAXBuilder();
288 saxBuilder.setEntityResolver(new EntityResolver()
289 {
290 public InputSource resolveEntity(java.lang.String publicId, java.lang.String systemId) throws SAXException,
291 java.io.IOException
292 {
293 if (systemId.equals("http://java.sun.com/dtd/web-app_2_3.dtd"))
294 {
295 return new InputSource(getClass().getResourceAsStream("web-app_2_3.dtd"));
296 }
297 return null;
298 }
299 });
300 Document document = saxBuilder.build(source);
301 return document;
302 }
303
304 protected void addFile(String path, InputStream source, JarOutputStream jos) throws IOException
305 {
306 jos.putNextEntry(new ZipEntry(path));
307 try
308 {
309 int count;
310 while ((count = source.read(buffer)) > 0)
311 {
312 jos.write(buffer, 0, count);
313 }
314 }
315 finally
316 {
317 jos.closeEntry();
318 }
319 }
320
321 protected void addFile(String path, Document source, JarOutputStream jos) throws IOException
322 {
323 if (source != null)
324 {
325 jos.putNextEntry(new ZipEntry(path));
326 XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
327 try
328 {
329 xmlOutputter.output(source, jos);
330 }
331 finally
332 {
333 jos.closeEntry();
334 }
335 }
336 }
337
338 protected String getPortletApplicationName(String path)
339 {
340 File file = new File(path);
341 String name = file.getName();
342 String portletApplicationName = name;
343
344 int index = name.lastIndexOf("-infused.war");
345 if (index > -1)
346 {
347 portletApplicationName = name.substring(0, index);
348 }
349 else
350 {
351 index = name.lastIndexOf(".");
352 if (index > -1)
353 {
354 portletApplicationName = name.substring(0, index);
355 }
356 }
357 return portletApplicationName;
358 }
359 }