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