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.FacesContext;
27
28 import javax.servlet.ServletContext;
29 import javax.servlet.ServletContextEvent;
30 import javax.servlet.ServletContextListener;
31 import java.lang.reflect.InvocationTargetException;
32 import java.lang.reflect.Method;
33
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.logging.Level;
39 import java.util.logging.Logger;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class StartupServletContextListener implements ServletContextListener
61 {
62 static final String FACES_INIT_DONE = "org.apache.myfaces.webapp.StartupServletContextListener.FACES_INIT_DONE";
63
64
65
66
67 @JSFWebConfigParam(since = "2.0")
68 static final String FACES_INIT_PLUGINS = "org.apache.myfaces.FACES_INIT_PLUGINS";
69
70 private static final byte FACES_INIT_PHASE_PREINIT = 0;
71 private static final byte FACES_INIT_PHASE_POSTINIT = 1;
72 private static final byte FACES_INIT_PHASE_PREDESTROY = 2;
73 private static final byte FACES_INIT_PHASE_POSTDESTROY = 3;
74
75 private static final Logger log = Logger.getLogger(StartupServletContextListener.class.getName());
76
77 private FacesInitializer _facesInitializer;
78 private ServletContext _servletContext;
79
80 @Override
81 public void contextInitialized(ServletContextEvent event)
82 {
83 if (_servletContext != null)
84 {
85 throw new IllegalStateException("context is already initialized");
86 }
87 _servletContext = event.getServletContext();
88
89 Boolean b = (Boolean) _servletContext.getAttribute(FACES_INIT_DONE);
90 if (b == null || b.booleanValue() == false)
91 {
92 long start = System.currentTimeMillis();
93
94 if (_facesInitializer == null)
95 {
96 _facesInitializer = FacesInitializerFactory.getFacesInitializer(_servletContext);
97 }
98
99
100 FacesContext facesContext = _facesInitializer.initStartupFacesContext(_servletContext);
101
102 dispatchInitializationEvent(event, FACES_INIT_PHASE_PREINIT);
103 _facesInitializer.initFaces(_servletContext);
104 dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTINIT);
105 _servletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
106
107
108 _facesInitializer.destroyStartupFacesContext(facesContext);
109
110 log.log(Level.INFO, "MyFaces Core has started, it took ["
111 + (System.currentTimeMillis() - start)
112 + "] ms.");
113 }
114 else
115 {
116 log.info("MyFaces already initialized");
117 }
118 }
119
120 @Override
121 public void contextDestroyed(ServletContextEvent event)
122 {
123 if (_facesInitializer != null && _servletContext != null)
124 {
125
126 FacesContext facesContext = _facesInitializer.initShutdownFacesContext(_servletContext);
127
128 dispatchInitializationEvent(event, FACES_INIT_PHASE_PREDESTROY);
129
130 _facesInitializer.destroyFaces(_servletContext);
131
132 LifecycleProviderFactory.getLifecycleProviderFactory().release();
133
134
135
136 if (facesContext != null)
137 {
138 _facesInitializer.destroyShutdownFacesContext(facesContext);
139 }
140
141 FactoryFinder.releaseFactories();
142
143
144 dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
145 }
146
147 _servletContext = null;
148 }
149
150
151
152
153
154
155 public void setFacesInitializer(FacesInitializer facesInitializer)
156 {
157 if (_facesInitializer != null && _facesInitializer != facesInitializer && _servletContext != null)
158 {
159 _facesInitializer.destroyFaces(_servletContext);
160 }
161 _facesInitializer = facesInitializer;
162 if (_servletContext != null)
163 {
164 facesInitializer.initFaces(_servletContext);
165 }
166 }
167
168
169
170
171
172
173
174
175 private boolean loadFacesInitPluginsViaServiceLoader()
176 {
177 try
178 {
179 Class serviceLoader = ClassUtils.getContextClassLoader().loadClass("java.util.ServiceLoader");
180 Method m = serviceLoader.getDeclaredMethod("load", Class.class, ClassLoader.class);
181
182 Object loader = m.invoke(serviceLoader, StartupListener.class, ClassUtils.getContextClassLoader());
183 m = loader.getClass().getDeclaredMethod("iterator");
184
185 Iterator<StartupListener> it = (Iterator<StartupListener>) m.invoke(loader);
186 List<StartupListener> listeners = new LinkedList<StartupListener>();
187 if (!it.hasNext())
188 {
189 return false;
190 }
191 while (it.hasNext())
192 {
193 listeners.add(it.next());
194 }
195
196 _servletContext.setAttribute(FACES_INIT_PLUGINS, listeners);
197 return true;
198 }
199 catch (ClassNotFoundException e)
200 {
201
202 }
203 catch (NoSuchMethodException e)
204 {
205 log.log(Level.SEVERE, e.getMessage(), e);
206 }
207 catch (InvocationTargetException e)
208 {
209 log.log(Level.SEVERE, e.getMessage(), e);
210 }
211 catch (IllegalAccessException e)
212 {
213 log.log(Level.SEVERE, e.getMessage(), e);
214 }
215 return false;
216 }
217
218
219
220
221 private void loadFacesInitViaContextParam()
222 {
223 String plugins = (String) _servletContext.getInitParameter(FACES_INIT_PLUGINS);
224 if (plugins == null)
225 {
226 return;
227 }
228 log.info("MyFaces Plugins found");
229
230 String[] pluginEntries = plugins.split(",");
231 List<StartupListener> listeners = new ArrayList<StartupListener>(pluginEntries.length);
232 for (String pluginEntry : pluginEntries)
233 {
234 try
235 {
236 Class pluginClass = null;
237 pluginClass = ClassUtils.getContextClassLoader().loadClass(pluginEntry);
238 if (pluginClass == null)
239 {
240 pluginClass = this.getClass().getClassLoader().loadClass(pluginEntry);
241 }
242 listeners.add((StartupListener) pluginClass.newInstance());
243 }
244 catch (ClassNotFoundException e)
245 {
246 log.log(Level.SEVERE, e.getMessage(), e);
247 }
248 catch (InstantiationException e)
249 {
250 log.log(Level.SEVERE, e.getMessage(), e);
251 }
252 catch (IllegalAccessException e)
253 {
254 log.log(Level.SEVERE, e.getMessage(), e);
255 }
256 }
257
258 _servletContext.setAttribute(FACES_INIT_PLUGINS, listeners);
259
260 }
261
262
263
264
265
266
267
268
269 private void dispatchInitializationEvent(ServletContextEvent event, int operation)
270 {
271 if (operation == FACES_INIT_PHASE_PREINIT)
272 {
273 if (!loadFacesInitPluginsViaServiceLoader())
274 {
275 loadFacesInitViaContextParam();
276 }
277 }
278
279 List<StartupListener> pluginEntries = (List<StartupListener>) _servletContext.getAttribute(FACES_INIT_PLUGINS);
280 if (pluginEntries == null)
281 {
282 return;
283 }
284
285
286 for (StartupListener initializer : pluginEntries)
287 {
288 log.info("Processing plugin");
289
290
291
292
293 switch (operation)
294 {
295 case FACES_INIT_PHASE_PREINIT:
296 initializer.preInit(event);
297 break;
298 case FACES_INIT_PHASE_POSTINIT:
299 initializer.postInit(event);
300 break;
301 case FACES_INIT_PHASE_PREDESTROY:
302 initializer.preDestroy(event);
303 break;
304 default:
305 initializer.postDestroy(event);
306 break;
307 }
308 }
309 log.info("Processing MyFaces plugins done");
310 }
311 }