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 if (_facesInitializer == null)
108 {
109 _facesInitializer = FacesInitializerFactory.getFacesInitializer(_servletContext);
110 }
111
112
113 FacesContext facesContext = _facesInitializer.initStartupFacesContext(_servletContext);
114
115
116 _publishManagedBeanDestroyerListener(facesContext);
117
118 dispatchInitializationEvent(event, FACES_INIT_PHASE_PREINIT);
119 _facesInitializer.initFaces(_servletContext);
120 dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTINIT);
121 _servletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
122
123
124 _detroyerListener.contextInitialized(event);
125
126
127 _facesInitializer.destroyStartupFacesContext(facesContext);
128 }
129 else
130 {
131 log.info("MyFaces already initialized");
132 }
133 }
134
135
136
137
138
139
140
141
142 private void _publishManagedBeanDestroyerListener(FacesContext facesContext)
143 {
144 ExternalContext externalContext = facesContext.getExternalContext();
145 Map<String, Object> applicationMap = externalContext.getApplicationMap();
146
147 applicationMap.put(ManagedBeanDestroyerListener.APPLICATION_MAP_KEY, _detroyerListener);
148 }
149
150 public void contextDestroyed(ServletContextEvent event)
151 {
152 if (_facesInitializer != null && _servletContext != null)
153 {
154
155 FacesContext facesContext = _facesInitializer.initShutdownFacesContext(_servletContext);
156
157 dispatchInitializationEvent(event, FACES_INIT_PHASE_PREDESTROY);
158
159 _detroyerListener.contextDestroyed(event);
160
161 _facesInitializer.destroyFaces(_servletContext);
162
163 LifecycleProviderFactory.getLifecycleProviderFactory().release();
164
165
166
167 if (facesContext != null)
168 {
169 _facesInitializer.destroyShutdownFacesContext(facesContext);
170 }
171
172 FactoryFinder.releaseFactories();
173
174
175 dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
176 }
177
178 _servletContext = null;
179 }
180
181
182
183
184
185
186 public void setFacesInitializer(FacesInitializer facesInitializer)
187 {
188 if (_facesInitializer != null && _facesInitializer != facesInitializer && _servletContext != null)
189 {
190 _facesInitializer.destroyFaces(_servletContext);
191 }
192 _facesInitializer = facesInitializer;
193 if (_servletContext != null)
194 {
195 facesInitializer.initFaces(_servletContext);
196 }
197 }
198
199
200
201
202
203
204
205
206 private boolean loadFacesInitPluginsJDK6()
207 {
208 String[] pluginEntries = null;
209 try
210 {
211 Class serviceLoader = ClassUtils.getContextClassLoader().loadClass("java.util.ServiceLoader");
212 Method m = serviceLoader.getDeclaredMethod("load", Class.class, ClassLoader.class);
213 Object loader = m.invoke(serviceLoader, StartupListener.class, ClassUtils.getContextClassLoader());
214 m = loader.getClass().getDeclaredMethod("iterator");
215 Iterator<StartupListener> it = (Iterator<StartupListener>) m.invoke(loader);
216 List<StartupListener> listeners = new LinkedList<StartupListener>();
217 if (!it.hasNext())
218 {
219 return false;
220 }
221 while (it.hasNext())
222 {
223 listeners.add(it.next());
224 }
225
226 _servletContext.setAttribute(FACES_INIT_PLUGINS, listeners);
227 return true;
228 }
229 catch (ClassNotFoundException e)
230 {
231
232 }
233 catch (NoSuchMethodException e)
234 {
235 log.log(Level.SEVERE, e.getMessage(), e);
236 }
237 catch (InvocationTargetException e)
238 {
239 log.log(Level.SEVERE, e.getMessage(), e);
240 }
241 catch (IllegalAccessException e)
242 {
243 log.log(Level.SEVERE, e.getMessage(), e);
244 }
245 return false;
246 }
247
248
249
250
251
252 private void loadFacesInitPluginsJDK5()
253 {
254
255 String plugins = (String) _servletContext.getInitParameter(FACES_INIT_PLUGINS);
256 if (plugins == null)
257 {
258 return;
259 }
260 log.info("MyFaces Plugins found");
261 String[] pluginEntries = plugins.split(",");
262 List<StartupListener> listeners = new ArrayList<StartupListener>(pluginEntries.length);
263 for (String pluginEntry : pluginEntries)
264 {
265 try
266 {
267 Class pluginClass = null;
268 pluginClass = ClassUtils.getContextClassLoader().loadClass(pluginEntry);
269 if (pluginClass == null)
270 {
271 pluginClass = this.getClass().getClassLoader().loadClass(pluginEntry);
272 }
273 listeners.add((StartupListener) pluginClass.newInstance());
274 }
275 catch (ClassNotFoundException e)
276 {
277 log.log(Level.SEVERE, e.getMessage(), e);
278 }
279 catch (InstantiationException e)
280 {
281 log.log(Level.SEVERE, e.getMessage(), e);
282 }
283 catch (IllegalAccessException e)
284 {
285 log.log(Level.SEVERE, e.getMessage(), e);
286 }
287 }
288
289 _servletContext.setAttribute(FACES_INIT_PLUGINS, listeners);
290
291 }
292
293
294
295
296
297
298
299
300 private void dispatchInitializationEvent(ServletContextEvent event, int operation)
301 {
302
303 if (operation == FACES_INIT_PHASE_PREINIT)
304 {
305 if (!loadFacesInitPluginsJDK6())
306 {
307 loadFacesInitPluginsJDK5();
308 }
309 }
310
311 List<StartupListener> pluginEntries = (List<StartupListener>) _servletContext.getAttribute(FACES_INIT_PLUGINS);
312 if (pluginEntries == null)
313 {
314 return;
315 }
316
317
318 for (StartupListener initializer : pluginEntries)
319 {
320 log.info("Processing plugin");
321
322
323
324
325 switch (operation)
326 {
327 case FACES_INIT_PHASE_PREINIT:
328 initializer.preInit(event);
329 break;
330 case FACES_INIT_PHASE_POSTINIT:
331 initializer.postInit(event);
332 break;
333 case FACES_INIT_PHASE_PREDESTROY:
334 initializer.preDestroy(event);
335 break;
336 default:
337 initializer.postDestroy(event);
338 break;
339 }
340 }
341 log.info("Processing MyFaces plugins done");
342 }
343
344
345
346
347 public void attributeAdded(HttpSessionBindingEvent event)
348 {
349 _detroyerListener.attributeAdded(event);
350 }
351
352 public void attributeRemoved(HttpSessionBindingEvent event)
353 {
354 _detroyerListener.attributeRemoved(event);
355 }
356
357 public void attributeReplaced(HttpSessionBindingEvent event)
358 {
359 _detroyerListener.attributeReplaced(event);
360 }
361
362 public void sessionCreated(HttpSessionEvent event)
363 {
364 _detroyerListener.sessionCreated(event);
365 }
366
367 public void sessionDestroyed(HttpSessionEvent event)
368 {
369 _detroyerListener.sessionDestroyed(event);
370 }
371
372
373
374 public void attributeAdded(ServletContextAttributeEvent event)
375 {
376 _detroyerListener.attributeAdded(event);
377 }
378
379 public void attributeRemoved(ServletContextAttributeEvent event)
380 {
381 _detroyerListener.attributeRemoved(event);
382 }
383
384 public void attributeReplaced(ServletContextAttributeEvent event)
385 {
386 _detroyerListener.attributeReplaced(event);
387 }
388
389
390
391 public void attributeAdded(ServletRequestAttributeEvent event)
392 {
393 _detroyerListener.attributeAdded(event);
394 }
395
396 public void attributeRemoved(ServletRequestAttributeEvent event)
397 {
398 _detroyerListener.attributeRemoved(event);
399 }
400
401 public void attributeReplaced(ServletRequestAttributeEvent event)
402 {
403 _detroyerListener.attributeReplaced(event);
404 }
405
406 public void requestInitialized(ServletRequestEvent event)
407 {
408 _detroyerListener.requestInitialized(event);
409 }
410
411 public void requestDestroyed(ServletRequestEvent event)
412 {
413 _detroyerListener.requestDestroyed(event);
414 }
415
416 }