KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > winstone > HostConfiguration


1 /*
2  * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
3  * Distributed under the terms of either:
4  * - the common development and distribution license (CDDL), v1.0; or
5  * - the GNU Lesser General Public License, v2.1 or later
6  */

7 package winstone;
8
9 import java.io.File JavaDoc;
10 import java.io.FileOutputStream JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.InputStream JavaDoc;
13 import java.io.OutputStream JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Hashtable JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22 import java.util.jar.JarEntry JavaDoc;
23 import java.util.jar.JarFile JavaDoc;
24
25 import org.w3c.dom.Document JavaDoc;
26 import org.w3c.dom.Node JavaDoc;
27
28 /**
29  * Manages the references to individual webapps within the container. This object handles
30  * the mapping of url-prefixes to webapps, and init and shutdown of any webapps it manages.
31  *
32  * @author <a HREF="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
33  * @version $Id: HostConfiguration.java,v 1.7 2006/08/12 07:33:12 rickknowles Exp $
34  */

35 public class HostConfiguration implements Runnable JavaDoc {
36     
37     private static final long FLUSH_PERIOD = 60000L;
38     
39     private static final String JavaDoc WEB_INF = "WEB-INF";
40     private static final String JavaDoc WEB_XML = "web.xml";
41
42     private String JavaDoc hostname;
43     private Map JavaDoc args;
44     private Map JavaDoc webapps;
45     private Cluster cluster;
46     private ObjectPool objectPool;
47     private ClassLoader JavaDoc commonLibCL;
48     private File JavaDoc commonLibCLPaths[];
49     
50     private Thread JavaDoc thread;
51     
52     public HostConfiguration(String JavaDoc hostname, Cluster cluster, ObjectPool objectPool, ClassLoader JavaDoc commonLibCL,
53             File JavaDoc commonLibCLPaths[], Map JavaDoc args, String JavaDoc webappsDirName) throws IOException JavaDoc {
54         this.hostname = hostname;
55         this.args = args;
56         this.webapps = new Hashtable JavaDoc();
57         this.cluster = cluster;
58         this.objectPool = objectPool;
59         this.commonLibCL = commonLibCL;
60         this.commonLibCLPaths = commonLibCLPaths;
61         
62         // Is this the single or multiple configuration ? Check args
63
String JavaDoc warfile = (String JavaDoc) args.get("warfile");
64         String JavaDoc webroot = (String JavaDoc) args.get("webroot");
65         
66         // If single-webapp mode
67
if ((webappsDirName == null) && ((warfile != null) || (webroot != null))) {
68             String JavaDoc prefix = (String JavaDoc) args.get("prefix");
69             if (prefix == null) {
70                 prefix = "";
71             }
72             try {
73                 this.webapps.put(prefix, initWebApp(prefix, getWebRoot(webroot, warfile), "webapp"));
74             } catch (Throwable JavaDoc err) {
75                 Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
76             }
77         }
78         // Otherwise multi-webapp mode
79
else {
80             initMultiWebappDir(webappsDirName);
81         }
82         Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.InitComplete",
83                 new String JavaDoc[] {this.webapps.size() + "", this.webapps.keySet() + ""});
84         
85         
86         this.thread = new Thread JavaDoc(this, "WinstoneHostConfigurationMgmt:" + this.hostname);
87         this.thread.setDaemon(true);
88         this.thread.start();
89     }
90
91     public WebAppConfiguration getWebAppByURI(String JavaDoc uri) {
92         if (uri == null) {
93             return null;
94         } else if (uri.equals("/") || uri.equals("")) {
95             return (WebAppConfiguration) this.webapps.get("");
96         } else if (uri.startsWith("/")) {
97             String JavaDoc decoded = WinstoneRequest.decodeURLToken(uri);
98             String JavaDoc noLeadingSlash = decoded.substring(1);
99             int slashPos = noLeadingSlash.indexOf("/");
100             if (slashPos == -1) {
101                 return (WebAppConfiguration) this.webapps.get(decoded);
102             } else {
103                 return (WebAppConfiguration) this.webapps.get(
104                         decoded.substring(0, slashPos + 1));
105             }
106         } else {
107             return null;
108         }
109     }
110     
111     protected WebAppConfiguration initWebApp(String JavaDoc prefix, File JavaDoc webRoot,
112             String JavaDoc contextName) throws IOException JavaDoc {
113         Node JavaDoc webXMLParentNode = null;
114         File JavaDoc webInfFolder = new File JavaDoc(webRoot, WEB_INF);
115         if (webInfFolder.exists()) {
116             File JavaDoc webXmlFile = new File JavaDoc(webInfFolder, WEB_XML);
117             if (webXmlFile.exists()) {
118                 Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.ParsingWebXml");
119                 Document JavaDoc webXMLDoc = new WebXmlParser(this.commonLibCL)
120                         .parseStreamToXML(webXmlFile);
121                 if (webXMLDoc != null) {
122                     webXMLParentNode = webXMLDoc.getDocumentElement();
123                     Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.WebXmlParseComplete");
124                 } else {
125                     Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.WebXmlParseFailed");
126                 }
127             }
128         }
129
130         // Instantiate the webAppConfig
131
return new WebAppConfiguration(this, this.cluster, webRoot
132                 .getCanonicalPath(), prefix, this.objectPool, this.args,
133                 webXMLParentNode, this.commonLibCL,
134                 this.commonLibCLPaths, contextName);
135     }
136     
137     public String JavaDoc getHostname() {
138         return this.hostname;
139     }
140     
141     /**
142      * Destroy this webapp instance. Kills the webapps, plus any servlets,
143      * attributes, etc
144      *
145      * @param webApp The webapp to destroy
146      */

147     private void destroyWebApp(String JavaDoc prefix) {
148         WebAppConfiguration webAppConfig = (WebAppConfiguration) this.webapps.get(prefix);
149         if (webAppConfig != null) {
150             webAppConfig.destroy();
151             this.webapps.remove(prefix);
152         }
153     }
154     
155     public void destroy() {
156         Set JavaDoc prefixes = new HashSet JavaDoc(this.webapps.keySet());
157         for (Iterator JavaDoc i = prefixes.iterator(); i.hasNext(); ) {
158             destroyWebApp((String JavaDoc) i.next());
159         }
160         if (this.thread != null) {
161             this.thread.interrupt();
162         }
163     }
164     
165     public void invalidateExpiredSessions() {
166         Set JavaDoc webapps = new HashSet JavaDoc(this.webapps.values());
167         for (Iterator JavaDoc i = webapps.iterator(); i.hasNext(); ) {
168             ((WebAppConfiguration) i.next()).invalidateExpiredSessions();
169         }
170     }
171
172     public void run() {
173         boolean interrupted = false;
174         while (!interrupted) {
175             try {
176                 Thread.sleep(FLUSH_PERIOD);
177                 invalidateExpiredSessions();
178             } catch (InterruptedException JavaDoc err) {
179                 interrupted = true;
180             }
181         }
182         this.thread = null;
183     }
184     
185     public void reloadWebApp(String JavaDoc prefix) throws IOException JavaDoc {
186         WebAppConfiguration webAppConfig = (WebAppConfiguration) this.webapps.get(prefix);
187         if (webAppConfig != null) {
188             String JavaDoc webRoot = webAppConfig.getWebroot();
189             String JavaDoc contextName = webAppConfig.getContextName();
190             destroyWebApp(prefix);
191             try {
192                 this.webapps.put(prefix, initWebApp(prefix, new File JavaDoc(webRoot), contextName));
193             } catch (Throwable JavaDoc err) {
194                 Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
195             }
196         } else {
197             throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.PrefixUnknown", prefix));
198         }
199     }
200     
201     /**
202      * Setup the webroot. If a warfile is supplied, extract any files that the
203      * war file is newer than. If none is supplied, use the default temp
204      * directory.
205      */

206     protected File JavaDoc getWebRoot(String JavaDoc requestedWebroot, String JavaDoc warfileName) throws IOException JavaDoc {
207         if (warfileName != null) {
208             Logger.log(Logger.INFO, Launcher.RESOURCES,
209                     "HostConfig.BeginningWarExtraction");
210
211             // open the war file
212
File JavaDoc warfileRef = new File JavaDoc(warfileName);
213             if (!warfileRef.exists() || !warfileRef.isFile())
214                 throw new WinstoneException(Launcher.RESOURCES.getString(
215                         "HostConfig.WarFileInvalid", warfileName));
216
217             // Get the webroot folder (or a temp dir if none supplied)
218
File JavaDoc unzippedDir = null;
219             if (requestedWebroot != null) {
220                 unzippedDir = new File JavaDoc(requestedWebroot);
221             } else {
222                 File JavaDoc tempFile = File.createTempFile("dummy", "dummy");
223                 unzippedDir = new File JavaDoc(tempFile.getParent(), "winstone/" + warfileRef.getName());
224                 tempFile.delete();
225             }
226             if (unzippedDir.exists()) {
227                 if (!unzippedDir.isDirectory()) {
228                     throw new WinstoneException(Launcher.RESOURCES.getString(
229                             "HostConfig.WebRootNotDirectory", unzippedDir.getPath()));
230                 } else {
231                     Logger.log(Logger.DEBUG, Launcher.RESOURCES,
232                             "HostConfig.WebRootExists", unzippedDir.getCanonicalPath());
233                 }
234             } else {
235                 unzippedDir.mkdirs();
236             }
237
238             // Iterate through the files
239
JarFile JavaDoc warArchive = new JarFile JavaDoc(warfileRef);
240             for (Enumeration JavaDoc e = warArchive.entries(); e.hasMoreElements();) {
241                 JarEntry JavaDoc element = (JarEntry JavaDoc) e.nextElement();
242                 if (element.isDirectory()) {
243                     continue;
244                 }
245                 String JavaDoc elemName = element.getName();
246
247                 // If archive date is newer than unzipped file, overwrite
248
File JavaDoc outFile = new File JavaDoc(unzippedDir, elemName);
249                 if (outFile.exists() && (outFile.lastModified() > warfileRef.lastModified())) {
250                     continue;
251                 }
252                 outFile.getParentFile().mkdirs();
253                 byte buffer[] = new byte[8192];
254
255                 // Copy out the extracted file
256
InputStream JavaDoc inContent = warArchive.getInputStream(element);
257                 OutputStream JavaDoc outStream = new FileOutputStream JavaDoc(outFile);
258                 int readBytes = inContent.read(buffer);
259                 while (readBytes != -1) {
260                     outStream.write(buffer, 0, readBytes);
261                     readBytes = inContent.read(buffer);
262                 }
263                 inContent.close();
264                 outStream.close();
265             }
266
267             // Return webroot
268
return unzippedDir;
269         } else {
270             return new File JavaDoc(requestedWebroot);
271         }
272     }
273     
274     protected void initMultiWebappDir(String JavaDoc webappsDirName) throws IOException JavaDoc {
275         if (webappsDirName == null) {
276             webappsDirName = "webapps";
277         }
278         File JavaDoc webappsDir = new File JavaDoc(webappsDirName);
279         if (!webappsDir.exists()) {
280             throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.WebAppDirNotFound", webappsDirName));
281         } else if (!webappsDir.isDirectory()) {
282             throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.WebAppDirIsNotDirectory", webappsDirName));
283         } else {
284             File JavaDoc children[] = webappsDir.listFiles();
285             for (int n = 0; n < children.length; n++) {
286                 String JavaDoc childName = children[n].getName();
287                 
288                 // Check any directories for warfiles that match, and skip: only deploy the war file
289
if (children[n].isDirectory()) {
290                     File JavaDoc matchingWarFile = new File JavaDoc(webappsDir, children[n].getName() + ".war");
291                     if (matchingWarFile.exists() && matchingWarFile.isFile()) {
292                         Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.SkippingWarfileDir", childName);
293                     } else {
294                         String JavaDoc prefix = childName.equalsIgnoreCase("ROOT") ? "" : "/" + childName;
295                         if (!this.webapps.containsKey(prefix)) {
296                             try {
297                                 WebAppConfiguration webAppConfig = initWebApp(prefix, children[n], childName);
298                                 this.webapps.put(webAppConfig.getContextPath(), webAppConfig);
299                                 Logger.log(Logger.INFO, Launcher.RESOURCES, "HostConfig.DeployingWebapp", childName);
300                             } catch (Throwable JavaDoc err) {
301                                 Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
302                             }
303                         }
304                     }
305                 } else if (childName.endsWith(".war")) {
306                     String JavaDoc outputName = childName.substring(0, childName.lastIndexOf(".war"));
307                     String JavaDoc prefix = outputName.equalsIgnoreCase("ROOT") ? "" : "/" + outputName;
308                     
309                     if (!this.webapps.containsKey(prefix)) {
310                         File JavaDoc outputDir = new File JavaDoc(webappsDir, outputName);
311                         outputDir.mkdirs();
312                         try {
313                             WebAppConfiguration webAppConfig = initWebApp(prefix,
314                                             getWebRoot(new File JavaDoc(webappsDir, outputName).getCanonicalPath(),
315                                                     children[n].getCanonicalPath()), outputName);
316                             this.webapps.put(webAppConfig.getContextPath(), webAppConfig);
317                             Logger.log(Logger.INFO, Launcher.RESOURCES, "HostConfig.DeployingWebapp", childName);
318                         } catch (Throwable JavaDoc err) {
319                             Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
320                         }
321                     }
322                 }
323             }
324         }
325     }
326     
327     public WebAppConfiguration getWebAppBySessionKey(String JavaDoc sessionKey) {
328         List JavaDoc allwebapps = new ArrayList JavaDoc(this.webapps.values());
329         for (Iterator JavaDoc i = allwebapps.iterator(); i.hasNext(); ) {
330             WebAppConfiguration webapp = (WebAppConfiguration) i.next();
331             WinstoneSession session = webapp.getSessionById(sessionKey, false);
332             if (session != null) {
333                 return webapp;
334             }
335         }
336         return null;
337     }
338 }
339
Popular Tags