1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.config;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.lang.reflect.Constructor;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.net.JarURLConnection;
27 import java.net.URL;
28 import java.net.URLConnection;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Comparator;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Locale;
35 import java.util.Map;
36 import java.util.StringTokenizer;
37 import java.util.logging.Level;
38 import java.util.logging.Logger;
39
40 import javax.el.ELResolver;
41 import javax.faces.FacesException;
42 import javax.faces.FactoryFinder;
43 import javax.faces.application.Application;
44 import javax.faces.application.ApplicationFactory;
45 import javax.faces.application.ConfigurableNavigationHandler;
46 import javax.faces.application.NavigationHandler;
47 import javax.faces.application.ProjectStage;
48 import javax.faces.application.ResourceHandler;
49 import javax.faces.application.StateManager;
50 import javax.faces.application.ViewHandler;
51 import javax.faces.context.ExternalContext;
52 import javax.faces.context.FacesContext;
53 import javax.faces.el.PropertyResolver;
54 import javax.faces.el.VariableResolver;
55 import javax.faces.event.ActionListener;
56 import javax.faces.event.ComponentSystemEvent;
57 import javax.faces.event.PhaseListener;
58 import javax.faces.event.PostConstructApplicationEvent;
59 import javax.faces.event.PreDestroyCustomScopeEvent;
60 import javax.faces.event.PreDestroyViewMapEvent;
61 import javax.faces.event.SystemEvent;
62 import javax.faces.lifecycle.Lifecycle;
63 import javax.faces.lifecycle.LifecycleFactory;
64 import javax.faces.render.RenderKit;
65 import javax.faces.render.RenderKitFactory;
66 import javax.faces.validator.BeanValidator;
67 import javax.faces.webapp.FacesServlet;
68
69 import org.apache.myfaces.application.ApplicationFactoryImpl;
70 import org.apache.myfaces.application.BackwardsCompatibleNavigationHandlerWrapper;
71 import org.apache.myfaces.component.visit.VisitContextFactoryImpl;
72 import org.apache.myfaces.config.annotation.AnnotationConfigurator;
73 import org.apache.myfaces.config.annotation.LifecycleProvider;
74 import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
75 import org.apache.myfaces.config.element.Behavior;
76 import org.apache.myfaces.config.element.ClientBehaviorRenderer;
77 import org.apache.myfaces.config.element.FacesConfig;
78 import org.apache.myfaces.config.element.FacesConfigData;
79 import org.apache.myfaces.config.element.ManagedBean;
80 import org.apache.myfaces.config.element.NamedEvent;
81 import org.apache.myfaces.config.element.NavigationRule;
82 import org.apache.myfaces.config.element.Renderer;
83 import org.apache.myfaces.config.element.ResourceBundle;
84 import org.apache.myfaces.config.element.SystemEventListener;
85 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
86 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
87 import org.apache.myfaces.context.ExceptionHandlerFactoryImpl;
88 import org.apache.myfaces.context.ExternalContextFactoryImpl;
89 import org.apache.myfaces.context.FacesContextFactoryImpl;
90 import org.apache.myfaces.context.PartialViewContextFactoryImpl;
91 import org.apache.myfaces.el.DefaultPropertyResolver;
92 import org.apache.myfaces.el.VariableResolverImpl;
93 import org.apache.myfaces.el.unified.ResolverBuilderBase;
94 import org.apache.myfaces.lifecycle.LifecycleFactoryImpl;
95 import org.apache.myfaces.renderkit.RenderKitFactoryImpl;
96 import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl;
97 import org.apache.myfaces.shared.config.MyfacesConfig;
98 import org.apache.myfaces.shared.util.ClassUtils;
99 import org.apache.myfaces.shared.util.LocaleUtils;
100 import org.apache.myfaces.shared.util.StateUtils;
101 import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
102 import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
103 import org.apache.myfaces.spi.FacesConfigurationMerger;
104 import org.apache.myfaces.spi.FacesConfigurationMergerFactory;
105 import org.apache.myfaces.util.ContainerUtils;
106 import org.apache.myfaces.util.ExternalSpecifications;
107 import org.apache.myfaces.view.ViewDeclarationLanguageFactoryImpl;
108 import org.apache.myfaces.view.facelets.tag.jsf.TagHandlerDelegateFactoryImpl;
109 import org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener;
110 import org.apache.myfaces.webapp.ManagedBeanDestroyerListener;
111
112
113
114
115
116
117
118
119 @SuppressWarnings("deprecation")
120 public class FacesConfigurator
121 {
122
123 private static final Logger log = Logger.getLogger(FacesConfigurator.class.getName());
124
125 private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class.getName();
126 private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class.getName();
127 private static final String DEFAULT_EXTERNAL_CONTEXT_FACTORY = ExternalContextFactoryImpl.class.getName();
128 private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class.getName();
129 private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class.getName();
130 private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class.getName();
131 private static final String DEFAULT_PARTIAL_VIEW_CONTEXT_FACTORY = PartialViewContextFactoryImpl.class.getName();
132 private static final String DEFAULT_VISIT_CONTEXT_FACTORY = VisitContextFactoryImpl.class.getName();
133 private static final String DEFAULT_VIEW_DECLARATION_LANGUAGE_FACTORY
134 = ViewDeclarationLanguageFactoryImpl.class.getName();
135 private static final String DEFAULT_EXCEPTION_HANDLER_FACTORY = ExceptionHandlerFactoryImpl.class.getName();
136 private static final String DEFAULT_TAG_HANDLER_DELEGATE_FACTORY = TagHandlerDelegateFactoryImpl.class.getName();
137 private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml";
138
139 private final ExternalContext _externalContext;
140 private FacesConfigUnmarshaller<? extends FacesConfig> _unmarshaller;
141 private FacesConfigData _dispenser;
142 private AnnotationConfigurator _annotationConfigurator;
143
144 private RuntimeConfig _runtimeConfig;
145
146 private static long lastUpdate;
147
148 public FacesConfigurator(ExternalContext externalContext)
149 {
150 if (externalContext == null)
151 {
152 throw new IllegalArgumentException("external context must not be null");
153 }
154 _externalContext = externalContext;
155
156 }
157
158
159
160
161
162 public void setUnmarshaller(FacesConfigUnmarshaller<? extends FacesConfig> unmarshaller)
163 {
164 _unmarshaller = unmarshaller;
165 }
166
167
168
169
170 protected FacesConfigUnmarshaller<? extends FacesConfig> getUnmarshaller()
171 {
172 if (_unmarshaller == null)
173 {
174 _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(_externalContext);
175 }
176
177 return _unmarshaller;
178 }
179
180
181
182
183
184 public void setDispenser(FacesConfigData dispenser)
185 {
186 _dispenser = dispenser;
187 }
188
189
190
191
192 protected FacesConfigData getDispenser()
193 {
194 if (_dispenser == null)
195 {
196 _dispenser = new DigesterFacesConfigDispenserImpl();
197 }
198
199 return _dispenser;
200 }
201
202 public void setAnnotationConfigurator(AnnotationConfigurator configurator)
203 {
204 _annotationConfigurator = configurator;
205 }
206
207 protected AnnotationConfigurator getAnnotationConfigurator()
208 {
209 if (_annotationConfigurator == null)
210 {
211 _annotationConfigurator = new AnnotationConfigurator();
212 }
213 return _annotationConfigurator;
214 }
215
216 private long getResourceLastModified(String resource)
217 {
218 try
219 {
220 URL url = _externalContext.getResource(resource);
221 if (url != null)
222 {
223 return getResourceLastModified(url);
224 }
225 }
226 catch (IOException e)
227 {
228 log.log(Level.SEVERE, "Could not read resource " + resource, e);
229 }
230 return 0;
231 }
232
233
234 private long getResourceLastModified(URL url) throws IOException
235 {
236 if ("file".equals(url.getProtocol()))
237 {
238 String externalForm = url.toExternalForm();
239
240 File file = new File(externalForm.substring(5));
241
242 return file.lastModified();
243 }
244 else
245 {
246 return getResourceLastModified(url.openConnection());
247 }
248 }
249
250
251 private long getResourceLastModified(URLConnection connection) throws IOException
252 {
253 long modified;
254 if (connection instanceof JarURLConnection)
255 {
256
257
258
259
260
261
262
263
264
265
266 URL jarFileUrl = ((JarURLConnection) connection).getJarFileURL();
267 URLConnection jarFileConnection = jarFileUrl.openConnection();
268
269 try
270 {
271 modified = jarFileConnection.getLastModified();
272 }
273 finally
274 {
275 try
276 {
277 jarFileConnection.getInputStream().close();
278 }
279 catch (Exception exception)
280 {
281
282 }
283 }
284 }
285 else
286 {
287 modified = connection.getLastModified();
288 }
289
290 return modified;
291 }
292
293 private long getLastModifiedTime()
294 {
295 long lastModified = 0;
296 long resModified;
297
298 resModified = getResourceLastModified(DEFAULT_FACES_CONFIG);
299 if (resModified > lastModified)
300 {
301 lastModified = resModified;
302 }
303
304
305 List<String> configFilesList = getConfigFilesList();
306 for (int i = 0, size = configFilesList.size(); i < size; i++)
307 {
308 String systemId = configFilesList.get(i);
309 resModified = getResourceLastModified(systemId);
310 if (resModified > lastModified)
311 {
312 lastModified = resModified;
313 }
314 }
315
316 return lastModified;
317 }
318
319 public void update()
320 {
321
322
323
324 if (ContainerUtils.isRunningOnGoogleAppEngine(_externalContext))
325 {
326 return;
327 }
328 long refreshPeriod = (MyfacesConfig.getCurrentInstance(_externalContext).getConfigRefreshPeriod()) * 1000;
329
330 if (refreshPeriod > 0)
331 {
332 long ttl = lastUpdate + refreshPeriod;
333 if ((System.currentTimeMillis() > ttl) && (getLastModifiedTime() > ttl))
334 {
335 try
336 {
337 purgeConfiguration();
338 }
339 catch (NoSuchMethodException e)
340 {
341 log.severe("Configuration objects do not support clean-up. Update aborted");
342
343
344
345
346 lastUpdate = System.currentTimeMillis();
347
348 return;
349 }
350 catch (IllegalAccessException e)
351 {
352 log.severe("Error during configuration clean-up" + e.getMessage());
353 }
354 catch (InvocationTargetException e)
355 {
356 log.severe("Error during configuration clean-up" + e.getMessage());
357 }
358 configure();
359
360
361
362 FacesContext facesContext = FacesContext.getCurrentInstance();
363 Application application = facesContext.getApplication();
364
365 application.publishEvent(facesContext, PostConstructApplicationEvent.class,
366 Application.class, application);
367 }
368 }
369 }
370
371 private void purgeConfiguration() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
372 {
373 final Class<?>[] NO_PARAMETER_TYPES = new Class[]{};
374 final Object[] NO_PARAMETERS = new Object[]{};
375
376 Method appFactoryPurgeMethod;
377 Method renderKitPurgeMethod;
378 Method lifecyclePurgeMethod;
379
380
381
382 ApplicationFactory applicationFactory
383 = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
384 appFactoryPurgeMethod = applicationFactory.getClass().getMethod("purgeApplication", NO_PARAMETER_TYPES);
385
386 RenderKitFactory renderKitFactory
387 = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
388 renderKitPurgeMethod = renderKitFactory.getClass().getMethod("purgeRenderKit", NO_PARAMETER_TYPES);
389
390 LifecycleFactory lifecycleFactory
391 = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
392 lifecyclePurgeMethod = lifecycleFactory.getClass().getMethod("purgeLifecycle", NO_PARAMETER_TYPES);
393
394
395
396 appFactoryPurgeMethod.invoke(applicationFactory, NO_PARAMETERS);
397 renderKitPurgeMethod.invoke(renderKitFactory, NO_PARAMETERS);
398 RuntimeConfig.getCurrentInstance(_externalContext).purge();
399 lifecyclePurgeMethod.invoke(lifecycleFactory, NO_PARAMETERS);
400
401
402 }
403
404 public void configure() throws FacesException
405 {
406
407 FacesConfigurationMerger facesConfigurationMerger = FacesConfigurationMergerFactory
408 .getFacesConfigurationMergerFactory(_externalContext).getFacesConfigurationMerger(_externalContext);
409
410
411 setDispenser(facesConfigurationMerger.getFacesConfigData(_externalContext));
412
413 configureFactories();
414 configureApplication();
415 configureRenderKits();
416
417
418
419
420
421
422
423 configureRuntimeConfig();
424 configureLifecycle();
425 handleSerialFactory();
426 configureManagedBeanDestroyer();
427
428
429 lastUpdate = System.currentTimeMillis();
430 }
431
432 private List<String> getConfigFilesList()
433 {
434 String configFiles = _externalContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
435 List<String> configFilesList = new ArrayList<String>();
436 if (configFiles != null)
437 {
438 StringTokenizer st = new StringTokenizer(configFiles, ",", false);
439 while (st.hasMoreTokens())
440 {
441 String systemId = st.nextToken().trim();
442
443 if (DEFAULT_FACES_CONFIG.equals(systemId))
444 {
445 if (log.isLoggable(Level.WARNING))
446 {
447 log.warning(DEFAULT_FACES_CONFIG + " has been specified in the "
448 + FacesServlet.CONFIG_FILES_ATTR
449 + " context parameter of "
450 + "the deployment descriptor. This will automatically be removed, "
451 + "if we wouldn't do this, it would be loaded twice. See JSF spec 1.1, 10.3.2");
452 }
453 }
454 else
455 {
456 configFilesList.add(systemId);
457 }
458 }
459 }
460 return configFilesList;
461 }
462
463 private void configureFactories()
464 {
465 FacesConfigData dispenser = getDispenser();
466 setFactories(FactoryFinder.APPLICATION_FACTORY, dispenser.getApplicationFactoryIterator(),
467 DEFAULT_APPLICATION_FACTORY);
468 setFactories(FactoryFinder.EXCEPTION_HANDLER_FACTORY, dispenser.getExceptionHandlerFactoryIterator(),
469 DEFAULT_EXCEPTION_HANDLER_FACTORY);
470 setFactories(FactoryFinder.EXTERNAL_CONTEXT_FACTORY, dispenser.getExternalContextFactoryIterator(),
471 DEFAULT_EXTERNAL_CONTEXT_FACTORY);
472 setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, dispenser.getFacesContextFactoryIterator(),
473 DEFAULT_FACES_CONTEXT_FACTORY);
474 setFactories(FactoryFinder.LIFECYCLE_FACTORY, dispenser.getLifecycleFactoryIterator(),
475 DEFAULT_LIFECYCLE_FACTORY);
476 setFactories(FactoryFinder.RENDER_KIT_FACTORY, dispenser.getRenderKitFactoryIterator(),
477 DEFAULT_RENDER_KIT_FACTORY);
478 setFactories(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY, dispenser.getTagHandlerDelegateFactoryIterator(),
479 DEFAULT_TAG_HANDLER_DELEGATE_FACTORY);
480 setFactories(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY, dispenser.getPartialViewContextFactoryIterator(),
481 DEFAULT_PARTIAL_VIEW_CONTEXT_FACTORY);
482 setFactories(FactoryFinder.VISIT_CONTEXT_FACTORY, dispenser.getVisitContextFactoryIterator(),
483 DEFAULT_VISIT_CONTEXT_FACTORY);
484 setFactories(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY,
485 dispenser.getViewDeclarationLanguageFactoryIterator(),
486 DEFAULT_VIEW_DECLARATION_LANGUAGE_FACTORY);
487 }
488
489 private void setFactories(String factoryName, Collection<String> factories, String defaultFactory)
490 {
491 FactoryFinder.setFactory(factoryName, defaultFactory);
492 for (String factory : factories)
493 {
494 if (!factory.equals(defaultFactory))
495 {
496 FactoryFinder.setFactory(factoryName, factory);
497 }
498 }
499 }
500
501 private void configureApplication()
502 {
503 Application application = ((ApplicationFactory)
504 FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
505
506 FacesConfigData dispenser = getDispenser();
507 application.setActionListener(ClassUtils.buildApplicationObject(ActionListener.class,
508 dispenser.getActionListenerIterator(), null));
509
510 if (dispenser.getDefaultLocale() != null)
511 {
512 application.setDefaultLocale(LocaleUtils.toLocale(dispenser.getDefaultLocale()));
513 }
514
515 if (dispenser.getDefaultRenderKitId() != null)
516 {
517 application.setDefaultRenderKitId(dispenser.getDefaultRenderKitId());
518 }
519
520 if (dispenser.getMessageBundle() != null)
521 {
522 application.setMessageBundle(dispenser.getMessageBundle());
523 }
524
525 application.setNavigationHandler(ClassUtils.buildApplicationObject(NavigationHandler.class,
526 ConfigurableNavigationHandler.class,
527 BackwardsCompatibleNavigationHandlerWrapper.class,
528 dispenser.getNavigationHandlerIterator(),
529 application.getNavigationHandler()));
530
531 application.setStateManager(ClassUtils.buildApplicationObject(StateManager.class,
532 dispenser.getStateManagerIterator(),
533 application.getStateManager()));
534
535 application.setResourceHandler(ClassUtils.buildApplicationObject(ResourceHandler.class,
536 dispenser.getResourceHandlerIterator(),
537 application.getResourceHandler()));
538
539 List<Locale> locales = new ArrayList<Locale>();
540 for (String locale : dispenser.getSupportedLocalesIterator())
541 {
542 locales.add(LocaleUtils.toLocale(locale));
543 }
544
545 application.setSupportedLocales(locales);
546
547 application.setViewHandler(ClassUtils.buildApplicationObject(ViewHandler.class,
548 dispenser.getViewHandlerIterator(),
549 application.getViewHandler()));
550 for (SystemEventListener systemEventListener : dispenser.getSystemEventListeners())
551 {
552
553
554 try
555 {
556
557
558
559
560 Class eventClass = ClassUtils.classForName((systemEventListener.getSystemEventClass() != null)
561 ? systemEventListener.getSystemEventClass()
562 : SystemEvent.class.getName());
563
564
565
566
567
568 if (systemEventListener.getSourceClass() != null && systemEventListener.getSourceClass().length() > 0)
569 {
570 application.subscribeToEvent(
571 (Class<? extends SystemEvent>) eventClass,
572 ClassUtils.classForName(systemEventListener.getSourceClass()),
573 (javax.faces.event.SystemEventListener)
574 ClassUtils.newInstance(systemEventListener.getSystemEventListenerClass()));
575 }
576 else
577 {
578 application.subscribeToEvent(
579 (Class<? extends SystemEvent>) eventClass,
580 (javax.faces.event.SystemEventListener)
581 ClassUtils.newInstance(systemEventListener.getSystemEventListenerClass()));
582 }
583 }
584 catch (ClassNotFoundException e)
585 {
586 log.log(Level.SEVERE, "System event listener could not be initialized, reason:", e);
587 }
588 }
589
590
591 for (String componentType : dispenser.getComponentTypes())
592 {
593 application.addComponent(componentType, dispenser.getComponentClass(componentType));
594 }
595
596 for (String converterId : dispenser.getConverterIds())
597 {
598 application.addConverter(converterId, dispenser.getConverterClassById(converterId));
599 }
600
601 for (String converterClass : dispenser.getConverterClasses())
602 {
603 try
604 {
605 application.addConverter(ClassUtils.simpleClassForName(converterClass),
606 dispenser.getConverterClassByClass(converterClass));
607 }
608 catch (Exception ex)
609 {
610 log.log(Level.SEVERE, "Converter could not be added. Reason:", ex);
611 }
612 }
613
614 for (String validatorId : dispenser.getValidatorIds())
615 {
616 application.addValidator(validatorId, dispenser.getValidatorClass(validatorId));
617 }
618
619
620
621
622 String beanValidatorDisabled = _externalContext.getInitParameter(
623 BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME);
624 final boolean defaultBeanValidatorDisabled = (beanValidatorDisabled != null
625 && beanValidatorDisabled.toLowerCase().equals("true"));
626 boolean beanValidatorInstalledProgrammatically = false;
627 if (!defaultBeanValidatorDisabled
628 && ExternalSpecifications.isBeanValidationAvailable())
629 {
630
631 application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
632 beanValidatorInstalledProgrammatically = true;
633 }
634
635
636 for (String validatorId : dispenser.getDefaultValidatorIds())
637 {
638 application.addDefaultValidatorId(validatorId);
639 }
640
641
642
643 if (!beanValidatorInstalledProgrammatically
644 && application.getDefaultValidatorInfo()
645 .containsKey(BeanValidator.VALIDATOR_ID))
646 {
647 if (!ExternalSpecifications.isBeanValidationAvailable())
648 {
649
650
651 log.log(Level.WARNING, "The BeanValidator was installed as a " +
652 "default-validator from a faces-config file, but bean " +
653 "validation is not available on the classpath, " +
654 "thus it will not work!");
655 }
656 else if (defaultBeanValidatorDisabled)
657 {
658
659
660
661
662 log.log(Level.INFO, "The BeanValidator was disabled as a " +
663 "default-validator via the config parameter " +
664 BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME +
665 " in web.xml, but a faces-config file added it, " +
666 "thus it actually was installed as a default-validator.");
667 }
668 }
669
670 for (Behavior behavior : dispenser.getBehaviors())
671 {
672 application.addBehavior(behavior.getBehaviorId(), behavior.getBehaviorClass());
673 }
674
675 RuntimeConfig runtimeConfig = getRuntimeConfig();
676
677 if (MyfacesConfig.getCurrentInstance(_externalContext).isSupportJSPAndFacesEL())
678 {
679
680
681 runtimeConfig.setPropertyResolverChainHead(ClassUtils.buildApplicationObject(PropertyResolver.class,
682 dispenser.getPropertyResolverIterator(),
683 new DefaultPropertyResolver()));
684
685 runtimeConfig.setVariableResolverChainHead(ClassUtils.buildApplicationObject(VariableResolver.class,
686 dispenser.getVariableResolverIterator(),
687 new VariableResolverImpl()));
688 }
689 }
690
691
692
693
694
695
696
697
698
699
700 String getDefaultSourcClassForSystemEvent(Class systemEventClass)
701 {
702 Constructor[] constructors = systemEventClass.getConstructors();
703 for (Constructor constr : constructors)
704 {
705 Class[] parms = constr.getParameterTypes();
706 if (parms == null || parms.length != 1)
707 {
708
709 continue;
710 }
711 return parms[0].getName();
712 }
713 log.warning("The SystemEvent source type for " + systemEventClass.getName()
714 + " could not be detected, either register it manually or use a constructor argument "
715 + "for auto detection, defaulting now to java.lang.Object");
716 return "java.lang.Object";
717 }
718
719
720 protected RuntimeConfig getRuntimeConfig()
721 {
722 if (_runtimeConfig == null)
723 {
724 _runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext);
725 }
726 return _runtimeConfig;
727 }
728
729 public void setRuntimeConfig(RuntimeConfig runtimeConfig)
730 {
731 _runtimeConfig = runtimeConfig;
732 }
733
734 private void configureRuntimeConfig()
735 {
736 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext);
737
738 FacesConfigData dispenser = getDispenser();
739 for (ManagedBean bean : dispenser.getManagedBeans())
740 {
741 if (log.isLoggable(Level.WARNING) && runtimeConfig.getManagedBean(bean.getManagedBeanName()) != null)
742 {
743 log.warning("More than one managed bean w/ the name of '" + bean.getManagedBeanName()
744 + "' - only keeping the last ");
745 }
746
747 runtimeConfig.addManagedBean(bean.getManagedBeanName(), bean);
748
749 }
750
751 removePurgedBeansFromSessionAndApplication(runtimeConfig);
752
753 for (NavigationRule rule : dispenser.getNavigationRules())
754 {
755 runtimeConfig.addNavigationRule(rule);
756 }
757
758 for (String converterClassName : dispenser.getConverterConfigurationByClassName())
759 {
760 runtimeConfig.addConverterConfiguration(converterClassName,
761 _dispenser.getConverterConfiguration(converterClassName));
762 }
763
764 for (ResourceBundle bundle : dispenser.getResourceBundles())
765 {
766 runtimeConfig.addResourceBundle(bundle);
767 }
768
769 for (String className : dispenser.getElResolvers())
770 {
771 runtimeConfig.addFacesConfigElResolver((ELResolver) ClassUtils.newInstance(className, ELResolver.class));
772 }
773
774 runtimeConfig.setFacesVersion(dispenser.getFacesVersion());
775
776 runtimeConfig.setNamedEventManager(new NamedEventManager());
777
778 for (NamedEvent event : dispenser.getNamedEvents())
779 {
780 try
781 {
782 Class<? extends ComponentSystemEvent> clazz = ClassUtils.classForName(event.getEventClass());
783 runtimeConfig.getNamedEventManager().addNamedEvent(event.getShortName(), clazz);
784 }
785 catch (ClassNotFoundException e)
786 {
787 log.log(Level.SEVERE, "Named event could not be initialized, reason:", e);
788 }
789 }
790
791 String comparatorClass = _externalContext.getInitParameter(ResolverBuilderBase.EL_RESOLVER_COMPARATOR);
792
793 if (comparatorClass != null && !"".equals(comparatorClass))
794 {
795
796 Class<Comparator<ELResolver>> clazz;
797 try
798 {
799 clazz = ClassUtils.classForName(comparatorClass);
800
801 Comparator<ELResolver> comparator = clazz.newInstance();
802
803 runtimeConfig.setELResolverComparator(comparator);
804 }
805 catch (Exception e)
806 {
807 if (log.isLoggable(Level.SEVERE))
808 {
809 log.log(Level.SEVERE, "Cannot instantiate EL Resolver Comparator " + comparatorClass
810 + " . Check org.apache.myfaces.EL_RESOLVER_COMPARATOR web config param. "
811 + "Initialization continues with no comparator used.", e);
812 }
813 }
814 }
815 else
816 {
817 runtimeConfig.setELResolverComparator(null);
818 }
819 }
820
821 private void removePurgedBeansFromSessionAndApplication(RuntimeConfig runtimeConfig)
822 {
823 Map<String, ManagedBean> oldManagedBeans = runtimeConfig.getManagedBeansNotReaddedAfterPurge();
824 if (oldManagedBeans != null)
825 {
826 for (Map.Entry<String, ManagedBean> entry : oldManagedBeans.entrySet())
827 {
828 ManagedBean bean = entry.getValue();
829
830 String scope = bean.getManagedBeanScope();
831
832 if (scope != null && scope.equalsIgnoreCase("session"))
833 {
834 _externalContext.getSessionMap().remove(entry.getKey());
835 }
836 else if (scope != null && scope.equalsIgnoreCase("application"))
837 {
838 _externalContext.getApplicationMap().remove(entry.getKey());
839 }
840 }
841 }
842
843 runtimeConfig.resetManagedBeansNotReaddedAfterPurge();
844 }
845
846 private void configureRenderKits()
847 {
848 RenderKitFactory renderKitFactory
849 = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
850
851 FacesConfigData dispenser = getDispenser();
852 for (String renderKitId : dispenser.getRenderKitIds())
853 {
854 Collection<String> renderKitClass = dispenser.getRenderKitClasses(renderKitId);
855
856 if (renderKitClass.isEmpty())
857 {
858 renderKitClass = new ArrayList<String>(1);
859 renderKitClass.add(DEFAULT_RENDER_KIT_CLASS);
860 }
861
862
863 RenderKit renderKit = (RenderKit) ClassUtils.buildApplicationObject(RenderKit.class, renderKitClass, null);
864
865 for (Renderer element : dispenser.getRenderers(renderKitId))
866 {
867 javax.faces.render.Renderer renderer;
868 Collection<ClientBehaviorRenderer> clientBehaviorRenderers
869 = dispenser.getClientBehaviorRenderers(renderKitId);
870
871 try
872 {
873 renderer = (javax.faces.render.Renderer) ClassUtils.newInstance(element.getRendererClass());
874 }
875 catch (Throwable e)
876 {
877
878 log.log(Level.SEVERE, "failed to configure class " + element.getRendererClass(), e);
879 continue;
880 }
881
882 renderKit.addRenderer(element.getComponentFamily(), element.getRendererType(), renderer);
883
884
885
886 for (ClientBehaviorRenderer clientBehaviorRenderer : clientBehaviorRenderers)
887 {
888 try
889 {
890 javax.faces.render.ClientBehaviorRenderer behaviorRenderer
891 = (javax.faces.render.ClientBehaviorRenderer)
892 ClassUtils.newInstance(clientBehaviorRenderer.getRendererClass());
893
894 renderKit.addClientBehaviorRenderer(clientBehaviorRenderer.getRendererType(), behaviorRenderer);
895 }
896
897 catch (Throwable e)
898 {
899
900
901 if (log.isLoggable(Level.SEVERE))
902 {
903 log.log(Level.SEVERE, "failed to configure client behavior renderer class " +
904 clientBehaviorRenderer.getRendererClass(), e);
905 }
906 }
907 }
908 }
909
910 renderKitFactory.addRenderKit(renderKitId, renderKit);
911 }
912 }
913
914 private void configureLifecycle()
915 {
916
917 LifecycleFactory lifecycleFactory
918 = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
919
920
921 for (Iterator<String> it = lifecycleFactory.getLifecycleIds(); it.hasNext();)
922 {
923 Lifecycle lifecycle = lifecycleFactory.getLifecycle(it.next());
924
925
926 for (String listenerClassName : getDispenser().getLifecyclePhaseListeners())
927 {
928 try
929 {
930 lifecycle.addPhaseListener((PhaseListener)
931 ClassUtils.newInstance(listenerClassName, PhaseListener.class));
932 }
933 catch (ClassCastException e)
934 {
935 log.severe("Class " + listenerClassName + " does not implement PhaseListener");
936 }
937 }
938
939
940 FacesContext facesContext = FacesContext.getCurrentInstance();
941 if (facesContext.isProjectStage(ProjectStage.Development) &&
942 MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isDebugPhaseListenerEnabled())
943 {
944 lifecycle.addPhaseListener(new DebugPhaseListener());
945 }
946 }
947 }
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962 private void handleSerialFactory()
963 {
964
965 String serialProvider = _externalContext.getInitParameter(StateUtils.SERIAL_FACTORY);
966 SerialFactory serialFactory = null;
967
968 if (serialProvider == null)
969 {
970 serialFactory = new DefaultSerialFactory();
971 }
972 else
973 {
974 try
975 {
976 serialFactory = (SerialFactory) ClassUtils.newInstance(serialProvider);
977
978 }
979 catch (ClassCastException e)
980 {
981 log.log(Level.SEVERE, "Make sure '" + serialProvider + "' implements the correct interface", e);
982 }
983 catch (Exception e)
984 {
985 log.log(Level.SEVERE, "", e);
986 }
987 finally
988 {
989 if (serialFactory == null)
990 {
991 serialFactory = new DefaultSerialFactory();
992 log.severe("Using default serialization provider");
993 }
994 }
995
996 }
997
998 log.info("Serialization provider : " + serialFactory.getClass());
999 _externalContext.getApplicationMap().put(StateUtils.SERIAL_FACTORY, serialFactory);
1000 }
1001
1002 private void configureManagedBeanDestroyer()
1003 {
1004 FacesContext facesContext = FacesContext.getCurrentInstance();
1005 ExternalContext externalContext = facesContext.getExternalContext();
1006 Map<String, Object> applicationMap = externalContext.getApplicationMap();
1007 Application application = facesContext.getApplication();
1008
1009
1010 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
1011 LifecycleProvider lifecycleProvider = LifecycleProviderFactory
1012 .getLifecycleProviderFactory(externalContext).getLifecycleProvider(externalContext);
1013
1014
1015 ManagedBeanDestroyer mbDestroyer
1016 = new ManagedBeanDestroyer(lifecycleProvider, runtimeConfig);
1017
1018
1019 application.subscribeToEvent(PreDestroyCustomScopeEvent.class, mbDestroyer);
1020 application.subscribeToEvent(PreDestroyViewMapEvent.class, mbDestroyer);
1021
1022
1023 ManagedBeanDestroyerListener listener = (ManagedBeanDestroyerListener)
1024 applicationMap.get(ManagedBeanDestroyerListener.APPLICATION_MAP_KEY);
1025 if (listener != null)
1026 {
1027
1028 listener.setManagedBeanDestroyer(mbDestroyer);
1029 }
1030 else
1031 {
1032 log.log(Level.SEVERE, "No ManagedBeanDestroyerListener instance found, thus "
1033 + "@PreDestroy methods won't get called in every case. "
1034 + "This instance needs to be published before configuration is started.");
1035 }
1036 }
1037
1038 }