KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > server > war > EasyBeansContextListener


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: EasyBeansContextListener.java 1141 2006-10-06 09:22:37Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.server.war;
27 import static org.objectweb.easybeans.util.url.URLUtils.fileToURL2;
28
29 import java.io.BufferedReader JavaDoc;
30 import java.io.File JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.InputStreamReader JavaDoc;
33 import java.io.Reader JavaDoc;
34 import java.lang.reflect.InvocationTargetException JavaDoc;
35 import java.lang.reflect.Method JavaDoc;
36 import java.net.URL JavaDoc;
37 import java.net.URLClassLoader JavaDoc;
38 import java.net.URLConnection JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.List JavaDoc;
41
42 import javax.servlet.ServletContext JavaDoc;
43 import javax.servlet.ServletContextEvent JavaDoc;
44 import javax.servlet.ServletContextListener JavaDoc;
45
46 import org.objectweb.easybeans.log.JLog;
47 import org.objectweb.easybeans.log.JLogFactory;
48 import org.objectweb.easybeans.server.EasyBeans;
49 import org.objectweb.easybeans.server.Embedded;
50 import org.objectweb.easybeans.server.EmbeddedConfigurator;
51 import org.objectweb.easybeans.server.EmbeddedException;
52 import org.objectweb.easybeans.server.ServerConfig;
53 import org.objectweb.easybeans.util.url.URLUtilsException;
54
55 /**
56  * Listener class which is notified of lifecycle events. It allows to start
57  * EasyBeans at startup and stop it at the end.
58  * @author Florent Benoit
59  */

60 public class EasyBeansContextListener implements ServletContextListener JavaDoc {
61
62     /**
63      * Resource containing the list of files.
64      */

65     private static final String JavaDoc COMMON_LIBRARIES_LIST = "easybeans-exported-libraries.lst";
66
67     /**
68      * Default XML file.
69      */

70     public static final String JavaDoc DEFAULT_XML_FILE = "org/objectweb/easybeans/server/war/easybeans-default.xml";
71
72     /**
73      * Logger.
74      */

75     private static JLog logger = JLogFactory.getLog(EasyBeansContextListener.class);
76
77     /**
78      * Embedded instance.
79      */

80     private Embedded embedded = null;
81
82     /**
83      * List of available supported container.
84      */

85     private enum AvailableWebContainer {
86         /**
87          * Containers supported.
88          */

89         TOMCAT, JETTY, UNKNOWN
90     }
91
92     /**
93      * Container detected ?.
94      */

95     private AvailableWebContainer containerType;
96
97     /**
98      * Notification that the web application initialization process is starting.
99      * All ServletContextListeners are notified of context initialization before
100      * any filter or servlet in the web application is initialized.
101      * @param servletContextEvent event class for notifications about changes to
102      * the servlet context of a web application.
103      */

104     public void contextInitialized(final ServletContextEvent JavaDoc servletContextEvent) {
105
106         // Create and configure EasyBeans embedded server
107
if (embedded == null) {
108
109             // user configuration ?
110
URL JavaDoc xmlConfigurationURL = Thread.currentThread().getContextClassLoader().getResource(EasyBeans.USER_XML_FILE);
111
112             if (xmlConfigurationURL == null) {
113                 logger.warn("No {0} resource found in classpath, use default settings", EasyBeans.USER_XML_FILE);
114                 xmlConfigurationURL = Thread.currentThread().getContextClassLoader().getResource(DEFAULT_XML_FILE);
115             }
116             try {
117                 embedded = EmbeddedConfigurator.create(xmlConfigurationURL);
118             } catch (EmbeddedException e) {
119                 throw new IllegalStateException JavaDoc("Cannot create the embedded server", e);
120             }
121
122             // Detects Tomcat/Jetty/etc.
123
String JavaDoc ejb3ParentDir = detectWebContainerDirectory();
124             logger.info("Detecting '" + containerType + "' web container");
125
126             // Create ejb3s directory
127
File JavaDoc workDir = new File JavaDoc(ejb3ParentDir + File.separator + "ejb3s");
128             workDir.mkdir();
129
130             ServerConfig serverConfig = getServerConfig();
131             serverConfig.setShouldWait(false);
132             serverConfig.setUseMBeans(true);
133             serverConfig.setUseNaming(false);
134             logger.info("Set ejb3 path to ''{0}''", workDir);
135             serverConfig.setEjb3Path(workDir.getAbsolutePath());
136
137             // TODO ejb3 path ??
138

139             registerLibraries(servletContextEvent);
140             try {
141                 embedded.start();
142             } catch (EmbeddedException e) {
143                 throw new IllegalStateException JavaDoc("Cannot start embedded EasyBeans server", e);
144             }
145         }
146     }
147
148     /**
149      * Notification that the servlet context is about to be shut down. All
150      * servlets and filters have been destroy()ed before any
151      * ServletContextListeners are notified of context destruction.
152      * @param servletContextEvent event class for notifications about changes to
153      * the servlet context of a web application.
154      */

155     public void contextDestroyed(final ServletContextEvent JavaDoc servletContextEvent) {
156         if (embedded != null) {
157             logger.info("Stopping EasyBeans embedded server...");
158             try {
159                 embedded.stop();
160             } catch (EmbeddedException e) {
161                 throw new IllegalStateException JavaDoc("Cannot stop the embedded server", e);
162             } catch (Throwable JavaDoc e) {
163                 logger.error("Unexpected error when stopping the embedded server", e);
164                 throw new IllegalStateException JavaDoc("Unexpected error when stopping the embedded server", e);
165             } finally {
166                 embedded = null;
167             }
168         }
169     }
170
171     /**
172      * Gets the directory for EJB3 depending on the servlet container.
173      * @return path to catalina.base/jetty.home/etc.
174      */

175     private String JavaDoc detectWebContainerDirectory() {
176         // catalina base ?
177
String JavaDoc catalinaBase = System.getProperty("catalina.base");
178         if (catalinaBase != null) {
179             containerType = AvailableWebContainer.TOMCAT;
180             return catalinaBase;
181         }
182
183         // Jetty ?
184
String JavaDoc jettyHome = System.getProperty("jetty.home");
185         if (jettyHome != null) {
186             containerType = AvailableWebContainer.JETTY;
187             return jettyHome;
188         }
189
190         // not found, return tmp directory
191
containerType = AvailableWebContainer.UNKNOWN;
192         return System.getProperty("java.io.tmpdir");
193     }
194
195     /**
196      * Register the EasyBeans libraries in the root classloader (allowing each
197      * applications to communicate with EasyBeans).
198      * @param servletContextEvent event class for notifications about changes to
199      * the servlet context of a web application.
200      */

201     private void registerLibraries(final ServletContextEvent JavaDoc servletContextEvent) {
202         if (containerType.equals(AvailableWebContainer.TOMCAT)) {
203             registerTomcat(servletContextEvent);
204         }
205
206     }
207
208     /**
209      * Register the EasyBeans libraries for Tomcat.
210      * @param servletContextEvent event class for notifications about changes to
211      * the servlet context of a web application.
212      */

213     private void registerTomcat(final ServletContextEvent JavaDoc servletContextEvent) {
214
215         // Current Classloader
216
ClassLoader JavaDoc currentCL = Thread.currentThread().getContextClassLoader();
217
218         // Now, search shared classloader (child of server CL)
219
// Assume that it is a correct Tomcat installation
220
ClassLoader JavaDoc cl = currentCL.getParent().getParent();
221         // Check class :
222
if (!"org.apache.catalina.loader.StandardClassLoader".equals(cl.getClass().getName())) {
223             throw new IllegalStateException JavaDoc("Didn't find common classloader");
224         }
225
226         // Cast classLoader in URL Classloader
227
URLClassLoader JavaDoc urlCl = (URLClassLoader JavaDoc) cl;
228         // Get addURL method
229
Method JavaDoc addURL = null;
230         try {
231             addURL = URLClassLoader JavaDoc.class.getDeclaredMethod("addURL", new Class JavaDoc[] {URL JavaDoc.class});
232         } catch (SecurityException JavaDoc e) {
233             throw new IllegalArgumentException JavaDoc("Cannot get addURL method on the class '" + URLClassLoader JavaDoc.class + "'.", e);
234         } catch (NoSuchMethodException JavaDoc e) {
235             throw new IllegalArgumentException JavaDoc("Cannot get addURL method on the class '" + URLClassLoader JavaDoc.class + "'.", e);
236         }
237         addURL.setAccessible(true);
238
239         // Add libraries
240
// / Get Carol jar
241
ServletContext JavaDoc sContext = servletContextEvent.getServletContext();
242         List JavaDoc<String JavaDoc> libraries = new ArrayList JavaDoc<String JavaDoc>();
243         getLibraries(sContext, libraries);
244
245         for (String JavaDoc library : libraries) {
246             URL JavaDoc url = null;
247             try {
248                 url = fileToURL2(new File JavaDoc(library));
249             } catch (URLUtilsException e) {
250                 throw new IllegalArgumentException JavaDoc("Cannot get URL on file '" + library + "'.", e);
251             }
252             try {
253                 logger.debug("Registering '" + url + "'.");
254                 addURL.invoke(urlCl, url);
255             } catch (IllegalArgumentException JavaDoc e) {
256                 throw new IllegalStateException JavaDoc("Cannot register the URL '" + url + "'.", e);
257             } catch (IllegalAccessException JavaDoc e) {
258                 throw new IllegalStateException JavaDoc("Cannot register the URL '" + url + "'.", e);
259             } catch (InvocationTargetException JavaDoc e) {
260                 throw new IllegalStateException JavaDoc("Cannot register the URL '" + url + "'.", e);
261             }
262         }
263         addURL.setAccessible(false);
264
265     }
266
267     /**
268      * Retrieve a List of libraries to be loaded by TopLevel ClassLoaders.
269      * @param sContext ServletContext.
270      * @param libraries List of libs.
271      */

272     protected void getLibraries(final ServletContext JavaDoc sContext, final List JavaDoc<String JavaDoc> libraries) {
273         // Files that needs to be in the commons classloader are stored in a
274
// properties file.
275

276         ClassLoader JavaDoc classLoader = Thread.currentThread().getContextClassLoader();
277
278         URL JavaDoc url = classLoader.getResource(COMMON_LIBRARIES_LIST);
279         if (url == null) {
280             throw new IllegalStateException JavaDoc("No resource named '" + COMMON_LIBRARIES_LIST
281                     + "' was found in the current classloader.");
282         }
283
284         // got url, open it
285
URLConnection JavaDoc urlConnection = null;
286         try {
287             urlConnection = url.openConnection();
288         } catch (IOException JavaDoc e) {
289             throw new IllegalStateException JavaDoc("Cannot open connection on the URL '" + url + "'.", e);
290         }
291         urlConnection.setDefaultUseCaches(false);
292
293         Reader JavaDoc reader = null;
294         try {
295             try {
296                 reader = new InputStreamReader JavaDoc(urlConnection.getInputStream());
297             } catch (IOException JavaDoc e) {
298                 throw new IllegalStateException JavaDoc("Cannot get inputstream on the URL '" + url + "'.", e);
299             }
300             BufferedReader JavaDoc bufferedReader = new BufferedReader JavaDoc(reader);
301             String JavaDoc fileName = null;
302             try {
303                 while ((fileName = bufferedReader.readLine()) != null) {
304                     fileName = fileName.trim();
305                     // only lines with values
306
if (fileName.length() >= 0) {
307                         // Get filename
308
libraries.add(sContext.getRealPath("/WEB-INF/lib/" + fileName.trim()));
309                     }
310                 }
311             } catch (IOException JavaDoc e) {
312                 throw new IllegalStateException JavaDoc("Cannot read the inputstream on the URL '" + url + "'.", e);
313             } finally {
314                 if (bufferedReader != null) {
315                     try {
316                         bufferedReader.close();
317                     } catch (IOException JavaDoc e) {
318                         throw new IllegalStateException JavaDoc("Cannot close reader object on the URL '" + url + "'.", e);
319                     }
320                 }
321             }
322         } finally {
323             if (reader != null) {
324                 try {
325                     reader.close();
326                 } catch (IOException JavaDoc e) {
327                     throw new IllegalStateException JavaDoc("Cannot close reader object on the URL '" + url + "'.", e);
328                 }
329             }
330         }
331     }
332
333     /**
334      * @return returns the Easybeans ServerConfig object.
335      */

336     protected ServerConfig getServerConfig() {
337         return embedded.getServerConfig();
338     }
339 }
340
Popular Tags