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 java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
24 import org.apache.myfaces.config.FacesConfigValidator;
25 import org.apache.myfaces.config.FacesConfigurator;
26 import org.apache.myfaces.config.ManagedBeanBuilder;
27 import org.apache.myfaces.config.RuntimeConfig;
28 import org.apache.myfaces.config.element.ManagedBean;
29 import org.apache.myfaces.context.ReleaseableExternalContext;
30 import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
31 import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
32 import org.apache.myfaces.shared.context.ExceptionHandlerImpl;
33 import org.apache.myfaces.shared.util.StateUtils;
34 import org.apache.myfaces.shared.util.WebConfigParamUtils;
35 import org.apache.myfaces.spi.WebConfigProvider;
36 import org.apache.myfaces.spi.WebConfigProviderFactory;
37 import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
38
39 import javax.el.ExpressionFactory;
40 import javax.faces.application.Application;
41 import javax.faces.application.ProjectStage;
42 import javax.faces.component.UIViewRoot;
43 import javax.faces.context.ExceptionHandler;
44 import javax.faces.context.ExternalContext;
45 import javax.faces.context.FacesContext;
46 import javax.faces.event.PostConstructApplicationEvent;
47 import javax.faces.event.PreDestroyApplicationEvent;
48 import javax.faces.event.SystemEvent;
49 import javax.servlet.ServletContext;
50 import java.util.ArrayList;
51 import java.util.List;
52 import java.util.Locale;
53 import java.util.Map;
54 import java.util.logging.Level;
55 import java.util.logging.Logger;
56 import org.apache.myfaces.util.ExternalSpecifications;
57
58
59
60
61 public abstract class AbstractFacesInitializer implements FacesInitializer
62 {
63
64
65
66
67 private static final Logger log = Logger.getLogger(AbstractFacesInitializer.class.getName());
68
69
70
71
72
73
74 private static final String FACES_SERVLET_ADDED_ATTRIBUTE = "org.apache.myfaces.DYNAMICALLY_ADDED_FACES_SERVLET";
75
76
77
78
79 @JSFWebConfigParam(since="1.2.7", group="EL")
80 protected static final String EXPRESSION_FACTORY = "org.apache.myfaces.EXPRESSION_FACTORY";
81
82
83
84
85 @JSFWebConfigParam(since="2.0.3", defaultValue="false")
86 protected static final String INITIALIZE_ALWAYS_STANDALONE = "org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE";
87
88
89
90
91
92
93
94 @JSFWebConfigParam(expectedValues="true, auto, false", defaultValue="auto")
95 public static final String INIT_PARAM_LOG_WEB_CONTEXT_PARAMS = "org.apache.myfaces.LOG_WEB_CONTEXT_PARAMS";
96 public static final String INIT_PARAM_LOG_WEB_CONTEXT_PARAMS_DEFAULT ="auto";
97
98
99
100
101
102 public void initFaces(ServletContext servletContext)
103 {
104 try
105 {
106 if (log.isLoggable(Level.FINEST))
107 {
108 log.finest("Initializing MyFaces");
109 }
110
111
112
113
114
115
116
117 FacesContext facesContext = FacesContext.getCurrentInstance();
118 ExternalContext externalContext = facesContext.getExternalContext();
119
120
121
122 if (!WebConfigParamUtils.getBooleanInitParameter(externalContext, INITIALIZE_ALWAYS_STANDALONE, false))
123 {
124 WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
125 facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());
126
127 if (webConfigProvider.getFacesServletMappings(facesContext.getExternalContext()).isEmpty())
128 {
129
130
131 Boolean mappingAdded = (Boolean) servletContext.getAttribute(FACES_SERVLET_ADDED_ATTRIBUTE);
132 if (mappingAdded == null || !mappingAdded)
133 {
134 if (log.isLoggable(Level.WARNING))
135 {
136 log.warning("No mappings of FacesServlet found. Abort initializing MyFaces.");
137 }
138 return;
139 }
140 }
141 }
142
143 initContainerIntegration(servletContext, externalContext);
144
145 String useEncryption = servletContext.getInitParameter(StateUtils.USE_ENCRYPTION);
146 if (!"false".equals(useEncryption))
147 {
148 StateUtils.initSecret(servletContext);
149 }
150
151
152 _createEagerBeans(facesContext);
153
154 _dispatchApplicationEvent(servletContext, PostConstructApplicationEvent.class);
155
156 if ( (facesContext.isProjectStage(ProjectStage.Development) ||
157 facesContext.isProjectStage(ProjectStage.Production)) &&
158 log.isLoggable(Level.INFO))
159 {
160 log.info("ServletContext initialized.");
161 }
162
163 WebConfigParamsLogger.logWebContextParams(facesContext);
164
165
166 ExternalSpecifications.isUnifiedELAvailable();
167 ExternalSpecifications.isBeanValidationAvailable();
168
169
170 if (!facesContext.isProjectStage(ProjectStage.Production) &&
171 !facesContext.isProjectStage(ProjectStage.UnitTest))
172 {
173 ProjectStage projectStage = facesContext.getApplication().getProjectStage();
174 StringBuilder message = new StringBuilder("\n\n");
175 message.append("*******************************************************************\n");
176 message.append("*** WARNING: Apache MyFaces-2 is running in ");
177 message.append(projectStage.name().toUpperCase());
178 message.append(" mode.");
179 int length = projectStage.name().length();
180 for (int i = 0; i < 11 - length; i++)
181 {
182 message.append(" ");
183 }
184 message.append(" ***\n");
185 message.append("*** ");
186 for (int i = 0; i < length; i++)
187 {
188 message.append("^");
189 }
190 for (int i = 0; i < 20 - length; i++)
191 {
192 message.append(" ");
193 }
194 message.append("***\n");
195 message.append("*** Do NOT deploy to your live server(s) without changing this. ***\n");
196 message.append("*** See Application#getProjectStage() for more information. ***\n");
197 message.append("*******************************************************************\n");
198 log.log(Level.WARNING, message.toString());
199 }
200
201 }
202 catch (Exception ex)
203 {
204 log.log(Level.SEVERE, "An error occured while initializing MyFaces: "
205 + ex.getMessage(), ex);
206 }
207 }
208
209
210
211
212
213
214 private void _createEagerBeans(FacesContext facesContext)
215 {
216 ExternalContext externalContext = facesContext.getExternalContext();
217 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
218 List<ManagedBean> eagerBeans = new ArrayList<ManagedBean>();
219
220
221 for (ManagedBean bean : runtimeConfig.getManagedBeans().values())
222 {
223 String eager = bean.getEager();
224 if (eager != null && "true".equals(eager))
225 {
226
227 if (ManagedBeanBuilder.APPLICATION.equals(bean.getManagedBeanScope()))
228 {
229
230 eagerBeans.add(bean);
231 }
232 else
233 {
234
235 log.log(Level.WARNING, "The managed-bean with name "
236 + bean.getManagedBeanName()
237 + " must be application scoped to support eager=true.");
238 }
239 }
240 }
241
242
243 if (!eagerBeans.isEmpty())
244 {
245 ManagedBeanBuilder managedBeanBuilder = new ManagedBeanBuilder();
246 Map<String, Object> applicationMap = externalContext.getApplicationMap();
247
248 for (ManagedBean bean : eagerBeans)
249 {
250
251 if (applicationMap.containsKey(bean.getManagedBeanName()))
252 {
253
254
255 continue;
256 }
257
258
259 Object beanInstance = managedBeanBuilder.buildManagedBean(facesContext, bean);
260
261
262 applicationMap.put(bean.getManagedBeanName(), beanInstance);
263 }
264 }
265 }
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 private void _dispatchApplicationEvent(ServletContext servletContext, Class<? extends SystemEvent> eventClass)
283 {
284 FacesContext facesContext = FacesContext.getCurrentInstance();
285 Application application = facesContext.getApplication();
286 application.publishEvent(facesContext, eventClass, Application.class, application);
287 }
288
289
290
291
292 public void destroyFaces(ServletContext servletContext)
293 {
294
295 FacesContext facesContext = FacesContext.getCurrentInstance();
296
297 if (!WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
298 INITIALIZE_ALWAYS_STANDALONE, false))
299 {
300
301 WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
302 facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());
303
304 if (webConfigProvider.getFacesServletMappings(facesContext.getExternalContext()).isEmpty())
305 {
306
307
308 Boolean mappingAdded = (Boolean) servletContext.getAttribute(FACES_SERVLET_ADDED_ATTRIBUTE);
309 if (mappingAdded == null || !mappingAdded)
310 {
311 if (log.isLoggable(Level.WARNING))
312 {
313 log.warning("No mappings of FacesServlet found. Abort destroy MyFaces.");
314 }
315 return;
316 }
317 }
318 }
319
320 _dispatchApplicationEvent(servletContext, PreDestroyApplicationEvent.class);
321
322
323 MetaRulesetImpl.clearMetadataTargetCache();
324
325
326 try
327 {
328 Class<?> c = Class.forName("javax.faces.component.UIViewParameter");
329 Method m = c.getDeclaredMethod("releaseRenderer");
330 m.setAccessible(true);
331 m.invoke(null);
332 }
333 catch(ClassNotFoundException e)
334 {
335 log.log(Level.SEVERE, e.getMessage(), e);
336 }
337 catch(NoSuchMethodException e)
338 {
339 log.log(Level.SEVERE, e.getMessage(), e);
340 }
341 catch(IllegalAccessException e)
342 {
343 log.log(Level.SEVERE, e.getMessage(), e);
344 }
345 catch(InvocationTargetException e)
346 {
347 log.log(Level.SEVERE, e.getMessage(), e);
348 }
349
350
351 }
352
353
354
355
356
357
358
359
360
361
362
363 protected RuntimeConfig buildConfiguration(ServletContext servletContext,
364 ExternalContext externalContext, ExpressionFactory expressionFactory)
365 {
366 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
367 runtimeConfig.setExpressionFactory(expressionFactory);
368
369
370 new FacesConfigurator(externalContext).configure();
371
372 validateFacesConfig(servletContext, externalContext);
373
374 return runtimeConfig;
375 }
376
377 protected void validateFacesConfig(ServletContext servletContext, ExternalContext externalContext)
378 {
379 String validate = servletContext.getInitParameter(FacesConfigValidator.VALIDATE_CONTEXT_PARAM);
380 if ("true".equals(validate) && log.isLoggable(Level.WARNING))
381 {
382 List<String> warnings = FacesConfigValidator.validate(
383 externalContext);
384
385 for (String warning : warnings)
386 {
387 log.warning(warning);
388 }
389 }
390 }
391
392
393
394
395
396
397
398
399
400 protected static ExpressionFactory getUserDefinedExpressionFactory(ExternalContext externalContext)
401 {
402 String expressionFactoryClassName
403 = WebConfigParamUtils.getStringInitParameter(externalContext, EXPRESSION_FACTORY);
404 if (expressionFactoryClassName != null
405 && expressionFactoryClassName.trim().length() > 0)
406 {
407 if (log.isLoggable(Level.FINE))
408 {
409 log.fine("Attempting to load the ExpressionFactory implementation "
410 + "you've specified: '" + expressionFactoryClassName + "'.");
411 }
412
413 return loadExpressionFactory(expressionFactoryClassName);
414 }
415
416 return null;
417 }
418
419
420
421
422
423
424
425
426 protected static ExpressionFactory loadExpressionFactory(String expressionFactoryClassName)
427 {
428 try
429 {
430 Class<?> expressionFactoryClass = Class.forName(expressionFactoryClassName);
431 return (ExpressionFactory) expressionFactoryClass.newInstance();
432 }
433 catch (Exception ex)
434 {
435 if (log.isLoggable(Level.FINE))
436 {
437 log.log(Level.FINE, "An error occured while instantiating a new ExpressionFactory. "
438 + "Attempted to load class '" + expressionFactoryClassName + "'.", ex);
439 }
440 }
441
442 return null;
443 }
444
445 public FacesContext initStartupFacesContext(ServletContext servletContext)
446 {
447
448
449 return _createFacesContext(servletContext, true);
450 }
451
452 public void destroyStartupFacesContext(FacesContext facesContext)
453 {
454 _releaseFacesContext(facesContext);
455 }
456
457 public FacesContext initShutdownFacesContext(ServletContext servletContext)
458 {
459 return _createFacesContext(servletContext, false);
460 }
461
462 public void destroyShutdownFacesContext(FacesContext facesContext)
463 {
464 _releaseFacesContext(facesContext);
465 }
466
467 private FacesContext _createFacesContext(ServletContext servletContext, boolean startup)
468 {
469 ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, startup);
470 ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
471 FacesContext facesContext = new StartupFacesContextImpl(externalContext,
472 (ReleaseableExternalContext) externalContext, exceptionHandler, startup);
473
474
475
476 UIViewRoot startupViewRoot = new UIViewRoot();
477 startupViewRoot.setLocale(Locale.getDefault());
478 facesContext.setViewRoot(startupViewRoot);
479
480 return facesContext;
481 }
482
483 private void _releaseFacesContext(FacesContext facesContext)
484 {
485
486
487 if (facesContext != null)
488 {
489 facesContext.release();
490 }
491 }
492
493
494
495
496
497
498
499 protected abstract void initContainerIntegration(
500 ServletContext servletContext, ExternalContext externalContext);
501
502 }