KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > test > server > appserver > war > AbstractWar


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.test.server.appserver.war;
5
6 import org.apache.commons.io.FileUtils;
7
8 import com.tc.test.server.appserver.unit.TCServletFilter;
9 import com.tc.util.Assert;
10
11 import java.io.ByteArrayOutputStream JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.FileInputStream JavaDoc;
14 import java.io.FileOutputStream JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.InputStream JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashSet JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.jar.JarOutputStream JavaDoc;
24 import java.util.jar.Manifest JavaDoc;
25 import java.util.regex.Pattern JavaDoc;
26 import java.util.zip.CRC32 JavaDoc;
27 import java.util.zip.ZipEntry JavaDoc;
28
29 /**
30  * This class knows the contents and structure of a J2EE 2.0 compliant WAR (Web Application Resource). It assembles
31  * artifacts such as XML descriptors, libraries, classfiles, and servlets into an uncompressed JAR (as the spec
32  * requires). The web.xml file is updated to reflect the servlet mappings of this WAR. See implementations:
33  * {@link WebXxml} for details.
34  */

35 public abstract class AbstractWar implements War {
36
37   protected final String JavaDoc appName;
38   private final WebXml webXml;
39   private final List JavaDoc containerXml;
40   private final List JavaDoc servlets;
41   private final List JavaDoc listeners;
42   private final List JavaDoc filters;
43   private final List JavaDoc libraries;
44   private final List JavaDoc classes;
45   private final CRC32 JavaDoc crc32;
46   private final HashSet JavaDoc dirSet = new HashSet JavaDoc();
47   private final HashSet JavaDoc classSet = new HashSet JavaDoc();
48
49   private static final String JavaDoc WEB_INF = "WEB-INF/";
50   private static final String JavaDoc CLASSES = "WEB-INF/classes/";
51   private static final String JavaDoc LIB = "WEB-INF/lib/";
52
53   public AbstractWar(String JavaDoc appName, WebXml webXml) {
54     Assert.assertNotBlank(appName);
55     this.appName = appName;
56     this.webXml = webXml;
57     this.containerXml = new ArrayList JavaDoc();
58     this.servlets = new ArrayList JavaDoc();
59     this.listeners = new ArrayList JavaDoc();
60     this.filters = new ArrayList JavaDoc();
61     this.libraries = new ArrayList JavaDoc();
62     this.classes = new ArrayList JavaDoc();
63     this.crc32 = new CRC32 JavaDoc();
64   }
65
66   public final String JavaDoc addServlet(Class JavaDoc servletClass) {
67     Assert.assertNotNull(servletClass);
68     servlets.add(servletClass);
69     return webXml.addServlet(servletClass);
70   }
71
72   public final void addListener(Class JavaDoc listenerClass) {
73     Assert.assertNotNull(listenerClass);
74     listeners.add(listenerClass);
75     webXml.addListener(listenerClass);
76   }
77
78   public final void addFilter(Class JavaDoc filterClass, String JavaDoc pattern, Map JavaDoc initParams) {
79     Assert.assertNotNull(filterClass);
80     if (filters.size() == 0) addClass(TCServletFilter.class);
81     filters.add(filterClass);
82     webXml.addFilter(filterClass, pattern, initParams);
83   }
84
85   public final void addClass(Class JavaDoc clazz) {
86     Assert.assertNotNull(clazz);
87     classes.add(clazz);
88   }
89
90   public final void addContainerSpecificXml(String JavaDoc fileName, byte[] containerXmlBytes) {
91     containerXml.add(new ContainerXmlValues(fileName, containerXmlBytes));
92   }
93
94   private class ContainerXmlValues {
95     private String JavaDoc fileName;
96     private byte[] bytes;
97
98     private ContainerXmlValues(String JavaDoc fileName, byte[] bytes) {
99       this.bytes = bytes;
100       this.fileName = fileName;
101     }
102   }
103
104   public final String JavaDoc writeWarFileToDirectory(File JavaDoc directory) throws IOException JavaDoc {
105     Assert.assertNotNull(directory);
106     File JavaDoc warFile = new File JavaDoc(directory + File.separator + appName + ".war");
107     JarOutputStream JavaDoc jout = null;
108     IOException JavaDoc exception = null;
109     try {
110       jout = new JarOutputStream JavaDoc(new FileOutputStream JavaDoc(warFile), new Manifest JavaDoc());
111       jout.setMethod(ZipEntry.STORED);
112       jout.setLevel(ZipEntry.STORED);
113
114       putEntry(jout, WEB_INF);
115       putEntry(jout, CLASSES);
116       putEntry(jout, LIB);
117       putEntry(jout, WEB_INF + webXml.getFileName(), webXml.getBytes());
118       putClasses(jout, servlets);
119       putClasses(jout, listeners);
120       putClasses(jout, filters);
121       putClasses(jout, classes);
122       putLibraries(jout);
123       putContainerSpecificXmlFiles(jout);
124
125     } catch (IOException JavaDoc ioe) {
126       exception = ioe;
127     } finally {
128       try {
129         if (jout != null) jout.close();
130       } catch (IOException JavaDoc ioe2) {
131         // ignore
132
}
133     }
134     if (exception != null) {
135       FileUtils.cleanDirectory(directory);
136       exception.printStackTrace();
137       throw new IOException JavaDoc("Unable to create war file.");
138     }
139
140     return appName + ".war";
141   }
142
143   public final void addLibrary(File JavaDoc lib) {
144     Assert.assertNotNull(lib);
145     if (!lib.isDirectory() && !lib.getName().endsWith("jar")) { throw new RuntimeException JavaDoc(
146                                                                                            "Library must be either a directory or a .jar file"); }
147     libraries.add(lib);
148   }
149
150   private void putClasses(JarOutputStream JavaDoc jout, List JavaDoc classList) throws IOException JavaDoc {
151     Class JavaDoc clazz;
152     String JavaDoc[] parts;
153     String JavaDoc currentPath;
154     String JavaDoc className;
155
156     for (Iterator JavaDoc iter = classList.iterator(); iter.hasNext();) {
157       clazz = (Class JavaDoc) iter.next();
158       parts = clazz.getName().split("\\.");
159       className = parts[parts.length - 1];
160       currentPath = CLASSES;
161
162       for (int i = 0; i < (parts.length - 1); i++) {
163         currentPath += parts[i] + File.separator;
164         if (!dirSet.contains(currentPath)) {
165           putEntry(jout, currentPath);
166           dirSet.add(currentPath);
167         }
168       }
169
170       String JavaDoc[] outerClass = className.split("\\$");
171       URL JavaDoc servletURL = clazz.getResource(className + ".class");
172       String JavaDoc[] files = new File JavaDoc(servletURL.getPath()).getParentFile().list();
173       for (int i = 0; i < files.length; i++) {
174         if (Pattern.matches(outerClass[0] + "(\\$.*)?\\.class", files[i])) {
175           if (!classSet.contains(files[i])) {
176             InputStream JavaDoc in = clazz.getResourceAsStream(files[i]);
177             byte[] servletBytes = new byte[in.available()];
178             in.read(servletBytes);
179             putEntry(jout, currentPath + files[i], servletBytes);
180             classSet.add(files[i]);
181           }
182         }
183       }
184     }
185   }
186
187   private void putContainerSpecificXmlFiles(JarOutputStream JavaDoc jout) throws IOException JavaDoc {
188     ContainerXmlValues values;
189     for (Iterator JavaDoc iter = containerXml.iterator(); iter.hasNext();) {
190       values = (ContainerXmlValues) iter.next();
191       putEntry(jout, WEB_INF + values.fileName, values.bytes);
192     }
193   }
194
195   private void putLibraries(JarOutputStream JavaDoc jout) throws IOException JavaDoc {
196     File JavaDoc lib;
197     for (Iterator JavaDoc iter = libraries.iterator(); iter.hasNext();) {
198       lib = (File JavaDoc) iter.next();
199       if (lib.getName().endsWith("jar")) {
200         InputStream JavaDoc in = new FileInputStream JavaDoc(lib);
201         byte[] bytes = new byte[in.available()];
202         in.read(bytes);
203         putEntry(jout, LIB + lib.getName(), bytes);
204
205       } else {
206         createLibraryJar(jout, lib);
207       }
208     }
209   }
210
211   private void createLibraryJar(JarOutputStream JavaDoc jout, File JavaDoc lib) throws IOException JavaDoc {
212     List JavaDoc relativePath = new ArrayList JavaDoc();
213     ByteArrayOutputStream JavaDoc bout = new ByteArrayOutputStream JavaDoc();
214     JarOutputStream JavaDoc newj = new JarOutputStream JavaDoc(bout, new Manifest JavaDoc());
215     newj.setMethod(ZipEntry.STORED);
216     newj.setLevel(ZipEntry.STORED);
217
218     String JavaDoc[] contents = lib.list();
219     File JavaDoc dir;
220     for (int i = 0; i < contents.length; i++) {
221       dir = new File JavaDoc(lib.getPath() + File.separator + contents[i]);
222       recurseLibTree(newj, dir, relativePath);
223     }
224     if (newj != null) newj.close();
225     putEntry(jout, LIB + lib.getName() + ".jar", bout.toByteArray());
226   }
227
228   private void recurseLibTree(JarOutputStream JavaDoc newj, File JavaDoc file, List JavaDoc relativePath) throws IOException JavaDoc {
229     if (file.isDirectory()) {
230       putEntry(newj, makePath(relativePath, file.getName()) + "/");
231       String JavaDoc[] contents = file.list();
232       if (contents.length > 0) relativePath.add(file.getName());
233       for (int i = 0; i < contents.length; i++) {
234         recurseLibTree(newj, new File JavaDoc(file.getPath() + File.separator + contents[i]), relativePath);
235       }
236       relativePath.remove(relativePath.size() - 1);
237
238     } else {
239       InputStream JavaDoc in = new FileInputStream JavaDoc(file);
240       byte[] bytes = new byte[in.available()];
241       in.read(bytes);
242       putEntry(newj, makePath(relativePath, file.getName()), bytes);
243     }
244   }
245
246   private String JavaDoc makePath(List JavaDoc path, String JavaDoc file) {
247     String JavaDoc url = "";
248     for (Iterator JavaDoc iter = path.iterator(); iter.hasNext();) {
249       url += (String JavaDoc) iter.next() + "/";
250     }
251     if (url.equals("")) return file;
252     return url + file;
253   }
254
255   private void putEntry(JarOutputStream JavaDoc jout, String JavaDoc file) throws IOException JavaDoc {
256     ZipEntry JavaDoc entry = new ZipEntry JavaDoc(file + "/");
257     entry.setSize(0);
258     entry.setCrc(0);
259     jout.putNextEntry(entry);
260   }
261
262   private void putEntry(JarOutputStream JavaDoc jout, String JavaDoc file, byte[] bytes) throws IOException JavaDoc {
263     ZipEntry JavaDoc entry = new ZipEntry JavaDoc(file);
264     entry.setSize(bytes.length);
265     entry.setCrc(getCrc32(bytes));
266     jout.putNextEntry(entry);
267     jout.write(bytes, 0, bytes.length);
268   }
269
270   private long getCrc32(byte[] bytes) {
271     crc32.update(bytes);
272     long checksum = crc32.getValue();
273     crc32.reset();
274     return checksum;
275   }
276 }
Popular Tags