1 7 package winstone; 8 9 import java.io.File ; 10 import java.io.FileOutputStream ; 11 import java.io.IOException ; 12 import java.io.InputStream ; 13 import java.io.OutputStream ; 14 import java.util.ArrayList ; 15 import java.util.Enumeration ; 16 import java.util.HashSet ; 17 import java.util.Hashtable ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 import java.util.jar.JarEntry ; 23 import java.util.jar.JarFile ; 24 25 import org.w3c.dom.Document ; 26 import org.w3c.dom.Node ; 27 28 35 public class HostConfiguration implements Runnable { 36 37 private static final long FLUSH_PERIOD = 60000L; 38 39 private static final String WEB_INF = "WEB-INF"; 40 private static final String WEB_XML = "web.xml"; 41 42 private String hostname; 43 private Map args; 44 private Map webapps; 45 private Cluster cluster; 46 private ObjectPool objectPool; 47 private ClassLoader commonLibCL; 48 private File commonLibCLPaths[]; 49 50 private Thread thread; 51 52 public HostConfiguration(String hostname, Cluster cluster, ObjectPool objectPool, ClassLoader commonLibCL, 53 File commonLibCLPaths[], Map args, String webappsDirName) throws IOException { 54 this.hostname = hostname; 55 this.args = args; 56 this.webapps = new Hashtable (); 57 this.cluster = cluster; 58 this.objectPool = objectPool; 59 this.commonLibCL = commonLibCL; 60 this.commonLibCLPaths = commonLibCLPaths; 61 62 String warfile = (String ) args.get("warfile"); 64 String webroot = (String ) args.get("webroot"); 65 66 if ((webappsDirName == null) && ((warfile != null) || (webroot != null))) { 68 String prefix = (String ) 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 err) { 75 Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err); 76 } 77 } 78 else { 80 initMultiWebappDir(webappsDirName); 81 } 82 Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.InitComplete", 83 new String [] {this.webapps.size() + "", this.webapps.keySet() + ""}); 84 85 86 this.thread = new Thread (this, "WinstoneHostConfigurationMgmt:" + this.hostname); 87 this.thread.setDaemon(true); 88 this.thread.start(); 89 } 90 91 public WebAppConfiguration getWebAppByURI(String 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 decoded = WinstoneRequest.decodeURLToken(uri); 98 String 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 prefix, File webRoot, 112 String contextName) throws IOException { 113 Node webXMLParentNode = null; 114 File webInfFolder = new File (webRoot, WEB_INF); 115 if (webInfFolder.exists()) { 116 File webXmlFile = new File (webInfFolder, WEB_XML); 117 if (webXmlFile.exists()) { 118 Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.ParsingWebXml"); 119 Document 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 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 getHostname() { 138 return this.hostname; 139 } 140 141 147 private void destroyWebApp(String 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 prefixes = new HashSet (this.webapps.keySet()); 157 for (Iterator i = prefixes.iterator(); i.hasNext(); ) { 158 destroyWebApp((String ) i.next()); 159 } 160 if (this.thread != null) { 161 this.thread.interrupt(); 162 } 163 } 164 165 public void invalidateExpiredSessions() { 166 Set webapps = new HashSet (this.webapps.values()); 167 for (Iterator 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 err) { 179 interrupted = true; 180 } 181 } 182 this.thread = null; 183 } 184 185 public void reloadWebApp(String prefix) throws IOException { 186 WebAppConfiguration webAppConfig = (WebAppConfiguration) this.webapps.get(prefix); 187 if (webAppConfig != null) { 188 String webRoot = webAppConfig.getWebroot(); 189 String contextName = webAppConfig.getContextName(); 190 destroyWebApp(prefix); 191 try { 192 this.webapps.put(prefix, initWebApp(prefix, new File (webRoot), contextName)); 193 } catch (Throwable 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 206 protected File getWebRoot(String requestedWebroot, String warfileName) throws IOException { 207 if (warfileName != null) { 208 Logger.log(Logger.INFO, Launcher.RESOURCES, 209 "HostConfig.BeginningWarExtraction"); 210 211 File warfileRef = new File (warfileName); 213 if (!warfileRef.exists() || !warfileRef.isFile()) 214 throw new WinstoneException(Launcher.RESOURCES.getString( 215 "HostConfig.WarFileInvalid", warfileName)); 216 217 File unzippedDir = null; 219 if (requestedWebroot != null) { 220 unzippedDir = new File (requestedWebroot); 221 } else { 222 File tempFile = File.createTempFile("dummy", "dummy"); 223 unzippedDir = new File (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 JarFile warArchive = new JarFile (warfileRef); 240 for (Enumeration e = warArchive.entries(); e.hasMoreElements();) { 241 JarEntry element = (JarEntry ) e.nextElement(); 242 if (element.isDirectory()) { 243 continue; 244 } 245 String elemName = element.getName(); 246 247 File outFile = new File (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 InputStream inContent = warArchive.getInputStream(element); 257 OutputStream outStream = new FileOutputStream (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 unzippedDir; 269 } else { 270 return new File (requestedWebroot); 271 } 272 } 273 274 protected void initMultiWebappDir(String webappsDirName) throws IOException { 275 if (webappsDirName == null) { 276 webappsDirName = "webapps"; 277 } 278 File webappsDir = new File (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 children[] = webappsDir.listFiles(); 285 for (int n = 0; n < children.length; n++) { 286 String childName = children[n].getName(); 287 288 if (children[n].isDirectory()) { 290 File matchingWarFile = new File (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 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 err) { 301 Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err); 302 } 303 } 304 } 305 } else if (childName.endsWith(".war")) { 306 String outputName = childName.substring(0, childName.lastIndexOf(".war")); 307 String prefix = outputName.equalsIgnoreCase("ROOT") ? "" : "/" + outputName; 308 309 if (!this.webapps.containsKey(prefix)) { 310 File outputDir = new File (webappsDir, outputName); 311 outputDir.mkdirs(); 312 try { 313 WebAppConfiguration webAppConfig = initWebApp(prefix, 314 getWebRoot(new File (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 err) { 319 Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err); 320 } 321 } 322 } 323 } 324 } 325 } 326 327 public WebAppConfiguration getWebAppBySessionKey(String sessionKey) { 328 List allwebapps = new ArrayList (this.webapps.values()); 329 for (Iterator 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 |