KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snipsnap > server > ApplicationLoader


1 /*
2  * This file is part of "SnipSnap Wiki/Weblog".
3  *
4  * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel
5  * All Rights Reserved.
6  *
7  * Please visit http://snipsnap.org/ for updates and contact.
8  *
9  * --LICENSE NOTICE--
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  * --LICENSE NOTICE--
24  */

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 JavaDoc;
38 import java.io.FileInputStream JavaDoc;
39 import java.io.IOException JavaDoc;
40 import java.net.InetAddress JavaDoc;
41 import java.net.URL JavaDoc;
42 import java.net.UnknownHostException JavaDoc;
43 import java.util.Collection JavaDoc;
44 import java.util.HashMap JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.Map JavaDoc;
47 import java.util.Properties JavaDoc;
48
49 /**
50  * Application Server handler that loads, starts, stops and unloads applications.
51  *
52  * @author Matthias L. Jugel
53  * @version $Id: ApplicationLoader.java 1792 2004-12-15 09:15:25Z leo $
54  */

55 public class ApplicationLoader {
56   private final static String JavaDoc WEBINF = "__WEBINF";
57   protected static Map JavaDoc applications = new HashMap JavaDoc();
58   protected static int errors = 0;
59
60   /**
61    * Create a new application load that uses the given jetty server and searches for applications in
62    * the root directory specified.
63    *
64    * @param root the root directory of a number of applications
65    */

66   public static int loadApplications(String JavaDoc root) {
67     File JavaDoc rootDir = new File JavaDoc(root);
68     if (rootDir.exists() && rootDir.isDirectory()) {
69       File JavaDoc files[] = rootDir.listFiles();
70       for (int i = 0; i < files.length; i++) {
71         if (files[i].isDirectory()) {
72           try {
73             Properties JavaDoc config = getGlobals(root, files[i].getName());
74             if (config != null) {
75               loadApplication(config);
76             }
77           } catch (Exception JavaDoc e) {
78             errors++;
79             e.printStackTrace();
80             System.out.println("WARNING: unable to load application '" + files[i].getName() + "': " + e.getMessage());
81           } catch (Error JavaDoc 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 JavaDoc getName(Properties JavaDoc config) {
93     String JavaDoc host = config.getProperty(Globals.APP_HOST) == null ? "" : config.getProperty(Globals.APP_HOST);
94     String JavaDoc port = config.getProperty(Globals.APP_PORT) == null ? "8668" : config.getProperty(Globals.APP_PORT);
95     String JavaDoc 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 JavaDoc normalize(String JavaDoc name) {
103     return name.replace(' ', '_');
104   }
105
106   private static Properties JavaDoc getGlobals(String JavaDoc root, String JavaDoc name) throws IOException JavaDoc {
107     File JavaDoc rootDir = new File JavaDoc(root);
108     if (rootDir.exists() && rootDir.isDirectory()) {
109       File JavaDoc appDir = new File JavaDoc(rootDir, normalize(name));
110       if (appDir.isDirectory()) {
111         File JavaDoc configFile = new File JavaDoc(appDir, "WEB-INF/application.conf");
112         if (!configFile.exists()) {
113           configFile = new File JavaDoc(appDir, "webapp/WEB-INF/application.conf");
114         }
115
116         if (configFile.exists()) {
117           Properties JavaDoc config = new Properties JavaDoc();
118           config.load(new FileInputStream JavaDoc(configFile));
119           config.setProperty(WEBINF, configFile.getParentFile().getCanonicalPath());
120           return config;
121         }
122       }
123     }
124     return null;
125   }
126
127   public static Properties JavaDoc reloadApplication(String JavaDoc root, String JavaDoc name) throws Exception JavaDoc {
128     Properties JavaDoc 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 JavaDoc loadApplication(String JavaDoc root, String JavaDoc name) throws Exception JavaDoc {
138     Properties JavaDoc 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 JavaDoc root, String JavaDoc name) throws Exception JavaDoc {
147     Properties JavaDoc 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 JavaDoc config) throws Exception JavaDoc {
163     String JavaDoc appName = getName(config);
164     if (applications.get(appName) != null) {
165       WebApplicationContext context = (WebApplicationContext) applications.get(appName);
166       if (context.isStarted()) {
167         throw new Exception JavaDoc("ApplicationLoader: '" + appName + "' already started");
168       }
169     }
170
171     String JavaDoc host = config.getProperty(Globals.APP_HOST) == null ? "" : config.getProperty(Globals.APP_HOST);
172     String JavaDoc port = config.getProperty(Globals.APP_PORT) == null ? "8668" : config.getProperty(Globals.APP_PORT);
173     String JavaDoc contextPath = config.getProperty(Globals.APP_PATH);
174     if (contextPath == null || contextPath.length() == 0) {
175       contextPath = "/";
176     }
177
178     File JavaDoc appRoot = new File JavaDoc(config.getProperty(WEBINF)).getParentFile();
179     boolean extract = appRoot.getName().equals("webapp");
180     if (extract) {
181       appRoot = appRoot.getParentFile();
182     }
183
184     String JavaDoc snipsnapWar = "lib/snipsnap.war";
185     if (!(new File JavaDoc(snipsnapWar).exists())) {
186       URL JavaDoc 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 JavaDoc(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 JavaDoc config) {
210     String JavaDoc appName = getName(config);
211     try {
212       WebApplicationContext context = (WebApplicationContext) applications.get(appName);
213       context.stop();
214       context.destroy();
215     } catch (Exception JavaDoc 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 JavaDoc host, String JavaDoc port, String JavaDoc path) throws IOException JavaDoc {
223     //System.out.print("Scanning for " + host + ":" + port + path);
224
Collection JavaDoc httpServers = Server.getHttpServers();
225
226     // try exact match first (host AND port)
227
HttpServer httpServer = findHost(httpServers, host, port);
228     //System.out.print(httpServer != null ? "<!>" : "<?>");
229
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 JavaDoc("unable to start HTTP Server: " + e.getMessage());
237       }
238       //System.out.print("(new server)");
239

240       try {
241         httpServer.addListener(port).start();
242       } catch (Exception JavaDoc e) {
243         e.printStackTrace();
244         throw new IOException JavaDoc("Unable to create port listener: " + e.getMessage());
245       }
246       //System.out.print("(port " + port + ")");
247
} else {
248       if (getContext(httpServer, host, path) != null) {
249         throw new IOException JavaDoc("Conflicting HTTP Server configuration found: '" + host + ":" + port + path + "/'");
250       }
251     }
252     //System.out.println();
253
return (Server) httpServer;
254   }
255
256   private static HttpServer findHost(Collection JavaDoc servers, String JavaDoc host, String JavaDoc port) {
257     host = (host == null ? "" : host);
258
259     //System.out.println("{" + host + ":" + port + "}");
260

261     Iterator JavaDoc 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 JavaDoc listenerHost = listener[i].getHost();
267         listenerHost = (listenerHost == null || listenerHost.equals(InetAddrPort.__0_0_0_0) ? "" : listenerHost);
268         String JavaDoc listenerPort = "" + listener[i].getPort();
269         if (port != null) {
270           //System.out.print("[" + listenerHost + ":" + listenerPort);
271
if (listenerHost.equals(host) && listenerPort.equals(port)) {
272             //System.out.println("!]");
273
return server;
274           }
275         } else {
276           //System.out.print("[" + listenerHost);
277
if (listenerHost.equals(host)) {
278             System.out.print("!]");
279             return server;
280           }
281         }
282         //System.out.print("]");
283
}
284     }
285     return null;
286   }
287
288   private static HttpContext getContext(HttpServer httpServer, String JavaDoc host, String JavaDoc path) {
289     HttpContext contexts[] = httpServer.getContexts();
290     for (int i = 0; i < contexts.length; i++) {
291       HttpContext context = contexts[i];
292       String JavaDoc contextPath = context.getContextPath();
293       //System.out.print("{" + contextPath + "}");
294
if (contextPath.equals(path) || contextPath.equals(path + "/*")) {
295         String JavaDoc[] 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   /**
307    * Return base url to Snipsnap instance
308    */

309   public static String JavaDoc getUrl(Properties JavaDoc config) {
310     String JavaDoc host = config.getProperty(Globals.APP_HOST);
311     String JavaDoc port = config.getProperty(Globals.APP_PORT);
312     String JavaDoc path = config.getProperty(Globals.APP_PATH);
313
314     StringBuffer JavaDoc tmp = new StringBuffer JavaDoc();
315     tmp.append("http://");
316     try {
317       tmp.append(host == null || host.length() == 0 || "localhost".equals(host) ? InetAddress.getLocalHost().getHostName() : host);
318     } catch (UnknownHostException JavaDoc 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