1 25 package org.snipsnap.server; 26 27 import org.mortbay.http.HttpContext; 28 import org.mortbay.http.HttpListener; 29 import org.mortbay.http.HttpServer; 30 import org.mortbay.jetty.Server; 31 import org.mortbay.jetty.servlet.WebApplicationContext; 32 import org.mortbay.util.InetAddrPort; 33 import org.mortbay.util.MultiException; 34 import org.snipsnap.config.Globals; 35 import org.snipsnap.config.ServerConfiguration; 36 37 import java.io.File ; 38 import java.io.FileInputStream ; 39 import java.io.IOException ; 40 import java.net.InetAddress ; 41 import java.net.URL ; 42 import java.net.UnknownHostException ; 43 import java.util.Collection ; 44 import java.util.HashMap ; 45 import java.util.Iterator ; 46 import java.util.Map ; 47 import java.util.Properties ; 48 49 55 public class ApplicationLoader { 56 private final static String WEBINF = "__WEBINF"; 57 protected static Map applications = new HashMap (); 58 protected static int errors = 0; 59 60 66 public static int loadApplications(String root) { 67 File rootDir = new File (root); 68 if (rootDir.exists() && rootDir.isDirectory()) { 69 File files[] = rootDir.listFiles(); 70 for (int i = 0; i < files.length; i++) { 71 if (files[i].isDirectory()) { 72 try { 73 Properties config = getGlobals(root, files[i].getName()); 74 if (config != null) { 75 loadApplication(config); 76 } 77 } catch (Exception e) { 78 errors++; 79 e.printStackTrace(); 80 System.out.println("WARNING: unable to load application '" + files[i].getName() + "': " + e.getMessage()); 81 } catch (Error err) { 82 errors++; 83 err.printStackTrace(); 84 System.out.println("FATAL: unable to load application: '" + files[i].getName() + "': " + err.getMessage()); 85 } 86 } 87 } 88 } 89 return errors; 90 } 91 92 private static String getName(Properties config) { 93 String host = config.getProperty(Globals.APP_HOST) == null ? "" : config.getProperty(Globals.APP_HOST); 94 String port = config.getProperty(Globals.APP_PORT) == null ? "8668" : config.getProperty(Globals.APP_PORT); 95 String contextPath = config.getProperty(Globals.APP_PATH); 96 if (contextPath == null || contextPath.length() == 0) { 97 contextPath = ""; 98 } 99 return normalize(host + port + contextPath).replace('/', '_'); 100 } 101 102 private static String normalize(String name) { 103 return name.replace(' ', '_'); 104 } 105 106 private static Properties getGlobals(String root, String name) throws IOException { 107 File rootDir = new File (root); 108 if (rootDir.exists() && rootDir.isDirectory()) { 109 File appDir = new File (rootDir, normalize(name)); 110 if (appDir.isDirectory()) { 111 File configFile = new File (appDir, "WEB-INF/application.conf"); 112 if (!configFile.exists()) { 113 configFile = new File (appDir, "webapp/WEB-INF/application.conf"); 114 } 115 116 if (configFile.exists()) { 117 Properties config = new Properties (); 118 config.load(new FileInputStream (configFile)); 119 config.setProperty(WEBINF, configFile.getParentFile().getCanonicalPath()); 120 return config; 121 } 122 } 123 } 124 return null; 125 } 126 127 public static Properties reloadApplication(String root, String name) throws Exception { 128 Properties config = getGlobals(root, name); 129 if (config != null) { 130 unloadApplication(config); 131 loadApplication(config); 132 return config; 133 } 134 return null; 135 } 136 137 public static Properties loadApplication(String root, String name) throws Exception { 138 Properties config = getGlobals(root, name); 139 if (config != null) { 140 loadApplication(config); 141 return config; 142 } 143 return null; 144 } 145 146 public static void unloadApplication(String root, String name) throws Exception { 147 Properties config = getGlobals(root, name); 148 if (config != null) { 149 unloadApplication(config); 150 } 151 } 152 153 154 public static int getApplicationErrorCount() { 155 return errors; 156 } 157 158 public static int getApplicationCount() { 159 return applications.size(); 160 } 161 162 private static WebApplicationContext loadApplication(Properties config) throws Exception { 163 String appName = getName(config); 164 if (applications.get(appName) != null) { 165 WebApplicationContext context = (WebApplicationContext) applications.get(appName); 166 if (context.isStarted()) { 167 throw new Exception ("ApplicationLoader: '" + appName + "' already started"); 168 } 169 } 170 171 String host = config.getProperty(Globals.APP_HOST) == null ? "" : config.getProperty(Globals.APP_HOST); 172 String port = config.getProperty(Globals.APP_PORT) == null ? "8668" : config.getProperty(Globals.APP_PORT); 173 String contextPath = config.getProperty(Globals.APP_PATH); 174 if (contextPath == null || contextPath.length() == 0) { 175 contextPath = "/"; 176 } 177 178 File appRoot = new File (config.getProperty(WEBINF)).getParentFile(); 179 boolean extract = appRoot.getName().equals("webapp"); 180 if (extract) { 181 appRoot = appRoot.getParentFile(); 182 } 183 184 String snipsnapWar = "lib/snipsnap.war"; 185 if (!(new File (snipsnapWar).exists())) { 186 URL warFile = ApplicationLoader.class.getResource("/snipsnap.war"); 187 if (warFile != null) { 188 snipsnapWar = warFile.toString(); 189 } 190 } 191 Server server = findOrCreateServer(host, port, contextPath); 192 WebApplicationContext context = 193 server.addWebApplication(null, contextPath, 194 extract ? snipsnapWar : appRoot.getCanonicalPath()); 195 196 if (extract) { 197 context.setTempDirectory(appRoot.getCanonicalFile()); 198 context.setExtractWAR(true); 199 } 200 context.setAttribute(ServerConfiguration.INIT_PARAM, new File (config.getProperty(WEBINF), "application.conf").getCanonicalPath()); 201 context.start(); 202 203 applications.put(appName, context); 204 System.out.println("Started '" + appName + "' at " + getUrl(config)); 205 206 return context; 207 } 208 209 private static void unloadApplication(Properties config) { 210 String appName = getName(config); 211 try { 212 WebApplicationContext context = (WebApplicationContext) applications.get(appName); 213 context.stop(); 214 context.destroy(); 215 } catch (Exception e) { 216 System.out.println("Unable to stop '" + appName + "': " + e); 217 e.printStackTrace(); 218 } 219 System.out.println("Stopped application '" + appName + "'"); 220 } 221 222 private static Server findOrCreateServer(String host, String port, String path) throws IOException { 223 Collection httpServers = Server.getHttpServers(); 225 226 HttpServer httpServer = findHost(httpServers, host, port); 228 if (null == httpServer) { 230 httpServer = new Server(); 231 ((Server) httpServer).setRootWebApp("/"); 232 try { 233 httpServer.start(); 234 } catch (MultiException e) { 235 e.printStackTrace(); 236 throw new IOException ("unable to start HTTP Server: " + e.getMessage()); 237 } 238 240 try { 241 httpServer.addListener(port).start(); 242 } catch (Exception e) { 243 e.printStackTrace(); 244 throw new IOException ("Unable to create port listener: " + e.getMessage()); 245 } 246 } else { 248 if (getContext(httpServer, host, path) != null) { 249 throw new IOException ("Conflicting HTTP Server configuration found: '" + host + ":" + port + path + "/'"); 250 } 251 } 252 return (Server) httpServer; 254 } 255 256 private static HttpServer findHost(Collection servers, String host, String port) { 257 host = (host == null ? "" : host); 258 259 261 Iterator it = servers.iterator(); 262 while (it.hasNext()) { 263 HttpServer server = (HttpServer) it.next(); 264 HttpListener listener[] = server.getListeners(); 265 for (int i = 0; i < listener.length; i++) { 266 String listenerHost = listener[i].getHost(); 267 listenerHost = (listenerHost == null || listenerHost.equals(InetAddrPort.__0_0_0_0) ? "" : listenerHost); 268 String listenerPort = "" + listener[i].getPort(); 269 if (port != null) { 270 if (listenerHost.equals(host) && listenerPort.equals(port)) { 272 return server; 274 } 275 } else { 276 if (listenerHost.equals(host)) { 278 System.out.print("!]"); 279 return server; 280 } 281 } 282 } 284 } 285 return null; 286 } 287 288 private static HttpContext getContext(HttpServer httpServer, String host, String path) { 289 HttpContext contexts[] = httpServer.getContexts(); 290 for (int i = 0; i < contexts.length; i++) { 291 HttpContext context = contexts[i]; 292 String contextPath = context.getContextPath(); 293 if (contextPath.equals(path) || contextPath.equals(path + "/*")) { 295 String [] vhosts = context.getVirtualHosts(); 296 for (int j = 0; j < vhosts.length; j++) { 297 if (vhosts[j].equals(host)) { 298 return context; 299 } 300 } 301 } 302 } 303 return null; 304 } 305 306 309 public static String getUrl(Properties config) { 310 String host = config.getProperty(Globals.APP_HOST); 311 String port = config.getProperty(Globals.APP_PORT); 312 String path = config.getProperty(Globals.APP_PATH); 313 314 StringBuffer tmp = new StringBuffer (); 315 tmp.append("http://"); 316 try { 317 tmp.append(host == null || host.length() == 0 || "localhost".equals(host) ? InetAddress.getLocalHost().getHostName() : host); 318 } catch (UnknownHostException e) { 319 tmp.append(System.getProperty("host", "localhost")); 320 } 321 if (port != null && !"80".equals(port)) { 322 tmp.append(":"); 323 tmp.append(port); 324 } 325 tmp.append(path != null ? path : ""); 326 return tmp.toString(); 327 } 328 329 } 330 | Popular Tags |