1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.webapp;
20
21 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
22 import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
23 import org.apache.myfaces.shared.util.ClassUtils;
24
25 import javax.faces.FactoryFinder;
26 import javax.faces.context.ExternalContext;
27 import javax.faces.context.FacesContext;
28
29 import javax.servlet.ServletContext;
30 import javax.servlet.ServletContextAttributeEvent;
31 import javax.servlet.ServletContextAttributeListener;
32 import javax.servlet.ServletContextEvent;
33 import javax.servlet.ServletContextListener;
34 import javax.servlet.ServletRequestAttributeEvent;
35 import javax.servlet.ServletRequestAttributeListener;
36 import javax.servlet.ServletRequestEvent;
37 import javax.servlet.ServletRequestListener;
38 import javax.servlet.http.HttpSessionAttributeListener;
39 import javax.servlet.http.HttpSessionBindingEvent;
40 import javax.servlet.http.HttpSessionEvent;
41 import javax.servlet.http.HttpSessionListener;
42 import java.lang.reflect.InvocationTargetException;
43 import java.lang.reflect.Method;
44
45 import java.util.ArrayList;
46 import java.util.Iterator;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.logging.Level;
51 import java.util.logging.Logger;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class StartupServletContextListener implements ServletContextListener,
72 HttpSessionAttributeListener, HttpSessionListener,
73 ServletRequestListener, ServletRequestAttributeListener,
74 ServletContextAttributeListener
75 {
76 static final String FACES_INIT_DONE = "org.apache.myfaces.webapp.StartupServletContextListener.FACES_INIT_DONE";
77
78
79
80
81 @JSFWebConfigParam(since = "2.0")
82 static final String FACES_INIT_PLUGINS = "org.apache.myfaces.FACES_INIT_PLUGINS";
83
84 private static final byte FACES_INIT_PHASE_PREINIT = 0;
85 private static final byte FACES_INIT_PHASE_POSTINIT = 1;
86 private static final byte FACES_INIT_PHASE_PREDESTROY = 2;
87 private static final byte FACES_INIT_PHASE_POSTDESTROY = 3;
88
89
90 private static final Logger log = Logger.getLogger(StartupServletContextListener.class.getName());
91
92 private FacesInitializer _facesInitializer;
93 private ServletContext _servletContext;
94 private ManagedBeanDestroyerListener _detroyerListener = new ManagedBeanDestroyerListener();
95
96 public void contextInitialized(ServletContextEvent event)
97 {
98 if (_servletContext != null)
99 {
100 throw new IllegalStateException("context is already initialized");
101 }
102 _servletContext = event.getServletContext();
103
104 Boolean b = (Boolean) _servletContext.getAttribute(FACES_INIT_DONE);
105 if (b == null || b.booleanValue() == false)
106 {
107 long start = System.currentTimeMillis();
108
109 if (_facesInitializer == null)
110 {
111 _facesInitializer = FacesInitializerFactory.getFacesInitializer(_servletContext);
112 }
113
114
115 FacesContext facesContext = _facesInitializer.initStartupFacesContext(_servletContext);
116
117
118 _publishManagedBeanDestroyerListener(facesContext);
119
120 dispatchInitializationEvent(event, FACES_INIT_PHASE_PREINIT);
121 _facesInitializer.initFaces(_servletContext);
122 dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTINIT);
123 _servletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
124
125
126 _detroyerListener.contextInitialized(event);
127
128
129 _facesInitializer.destroyStartupFacesContext(facesContext);
130
131 log.log(Level.INFO, "MyFaces Core has started, it took ["
132 + (System.currentTimeMillis() - start)
133 + "] ms.");
134 }
135 else
136 {
137 log.info("MyFaces already initialized");
138 }
139 }
140
141
142
143
144
145
146
147
148 private void _publishManagedBeanDestroyerListener(FacesContext facesContext)
149 {
150 ExternalContext externalContext = facesContext.getExternalContext();
151 Map<String, Object> applicationMap = externalContext.getApplicationMap();
152
153 applicationMap.put(ManagedBeanDestroyerListener.APPLICATION_MAP_KEY, _detroyerListener);
154 }
155
156 public void contextDestroyed(ServletContextEvent event)
157 {
158 if (_facesInitializer != null && _servletContext != null)
159 {
160
161 FacesContext facesContext = _facesInitializer.initShutdownFacesContext(_servletContext);
162
163 dispatchInitializationEvent(event, FACES_INIT_PHASE_PREDESTROY);
164
165 _detroyerListener.contextDestroyed(event);
166
167 _facesInitializer.destroyFaces(_servletContext);
168
169 LifecycleProviderFactory.getLifecycleProviderFactory().release();
170
171
172
173 if (facesContext != null)
174 {
175 _facesInitializer.destroyShutdownFacesContext(facesContext);
176 }
177
178 FactoryFinder.releaseFactories();
179
180
181 dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
182 }
183
184 _servletContext = null;
185 }
186
187
188
189
190
191
192 public void setFacesInitializer(FacesInitializer facesInitializer)
193 {
194 if (_facesInitializer != null && _facesInitializer != facesInitializer && _servletContext != null)
195 {
196 _facesInitializer.destroyFaces(_servletContext);
197 }
198 _facesInitializer = facesInitializer;
199 if (_servletContext != null)
200 {
201 facesInitializer.initFaces(_servletContext);
202 }
203 }
204
205
206
207
208
209
210
211
212 private boolean loadFacesInitPluginsJDK6()
213 {
214 String[] pluginEntries = null;
215 try
216 {
217 Class serviceLoader = ClassUtils.getContextClassLoader().loadClass("java.util.ServiceLoader");
218 Method m = serviceLoader.getDeclaredMethod("load", Class.class, ClassLoader.class);
219 Object loader = m.invoke(serviceLoader, StartupListener.class, ClassUtils.getContextClassLoader());
220 m = loader.getClass().getDeclaredMethod("iterator");
221 Iterator<StartupListener> it = (Iterator<StartupListener>) m.invoke(loader);
222 List<StartupListener> listeners = new LinkedList<StartupListener>();
223 if (!it.hasNext())
224 {
225 return false;
226 }
227 while (it.hasNext())
228 {
229 listeners.add(it.next());
230 }
231
232 _servletContext.setAttribute(FACES_INIT_PLUGINS, listeners);
233 return true;
234 }
235 catch (ClassNotFoundException e)
236 {
237
238 }
239 catch (NoSuchMethodException e)
240 {
241 log.log(Level.SEVERE, e.getMessage(), e);
242 }
243 catch (InvocationTargetException e)
244 {
245 log.log(Level.SEVERE, e.getMessage(), e);
246 }
247 catch (IllegalAccessException e)
248 {
249 log.log(Level.SEVERE, e.getMessage(), e);
250 }
251 return false;
252 }
253
254
255
256
257
258 private void loadFacesInitPluginsJDK5()
259 {
260
261 String plugins = (String) _servletContext.getInitParameter(FACES_INIT_PLUGINS);
262 if (plugins == null)
263 {
264 return;
265 }
266 log.info("MyFaces Plugins found");
267 String[] pluginEntries = plugins.split(",");
268 List<StartupListener> listeners = new ArrayList<StartupListener>(pluginEntries.length);
269 for (String pluginEntry : pluginEntries)
270 {
271 try
272 {
273 Class pluginClass = null;
274 pluginClass = ClassUtils.getContextClassLoader().loadClass(pluginEntry);
275 if (pluginClass == null)
276 {
277 pluginClass = this.getClass().getClassLoader().loadClass(pluginEntry);
278 }
279 listeners.add((StartupListener) pluginClass.newInstance());
280 }
281 catch (ClassNotFoundException e)
282 {
283 log.log(Level.SEVERE, e.getMessage(), e);
284 }
285 catch (InstantiationException e)
286 {
287 log.log(Level.SEVERE, e.getMessage(), e);
288 }
289 catch (IllegalAccessException e)
290 {
291 log.log(Level.SEVERE, e.getMessage(), e);
292 }
293 }
294
295 _servletContext.setAttribute(FACES_INIT_PLUGINS, listeners);
296
297 }
298
299
300
301
302
303
304
305
306 private void dispatchInitializationEvent(ServletContextEvent event, int operation)
307 {
308
309 if (operation == FACES_INIT_PHASE_PREINIT)
310 {
311 if (!loadFacesInitPluginsJDK6())
312 {
313 loadFacesInitPluginsJDK5();
314 }
315 }
316
317 List<StartupListener> pluginEntries = (List<StartupListener>) _servletContext.getAttribute(FACES_INIT_PLUGINS);
318 if (pluginEntries == null)
319 {
320 return;
321 }
322
323
324 for (StartupListener initializer : pluginEntries)
325 {
326 log.info("Processing plugin");
327
328
329
330
331 switch (operation)
332 {
333 case FACES_INIT_PHASE_PREINIT:
334 initializer.preInit(event);
335 break;
336 case FACES_INIT_PHASE_POSTINIT:
337 initializer.postInit(event);
338 break;
339 case FACES_INIT_PHASE_PREDESTROY:
340 initializer.preDestroy(event);
341 break;
342 default:
343 initializer.postDestroy(event);
344 break;
345 }
346 }
347 log.info("Processing MyFaces plugins done");
348 }
349
350
351
352
353 public void attributeAdded(HttpSessionBindingEvent event)
354 {
355 _detroyerListener.attributeAdded(event);
356 }
357
358 public void attributeRemoved(HttpSessionBindingEvent event)
359 {
360 _detroyerListener.attributeRemoved(event);
361 }
362
363 public void attributeReplaced(HttpSessionBindingEvent event)
364 {
365 _detroyerListener.attributeReplaced(event);
366 }
367
368 public void sessionCreated(HttpSessionEvent event)
369 {
370 _detroyerListener.sessionCreated(event);
371 }
372
373 public void sessionDestroyed(HttpSessionEvent event)
374 {
375 _detroyerListener.sessionDestroyed(event);
376 }
377
378
379
380 public void attributeAdded(ServletContextAttributeEvent event)
381 {
382 _detroyerListener.attributeAdded(event);
383 }
384
385 public void attributeRemoved(ServletContextAttributeEvent event)
386 {
387 _detroyerListener.attributeRemoved(event);
388 }
389
390 public void attributeReplaced(ServletContextAttributeEvent event)
391 {
392 _detroyerListener.attributeReplaced(event);
393 }
394
395
396
397 public void attributeAdded(ServletRequestAttributeEvent event)
398 {
399 _detroyerListener.attributeAdded(event);
400 }
401
402 public void attributeRemoved(ServletRequestAttributeEvent event)
403 {
404 _detroyerListener.attributeRemoved(event);
405 }
406
407 public void attributeReplaced(ServletRequestAttributeEvent event)
408 {
409 _detroyerListener.attributeReplaced(event);
410 }
411
412 public void requestInitialized(ServletRequestEvent event)
413 {
414 _detroyerListener.requestInitialized(event);
415 }
416
417 public void requestDestroyed(ServletRequestEvent event)
418 {
419 _detroyerListener.requestDestroyed(event);
420 }
421
422 }