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 org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.myfaces.application.ApplicationFactoryImpl;
24 import org.apache.myfaces.config.element.ManagedBean;
25 import org.apache.myfaces.config.element.NavigationRule;
26 import org.apache.myfaces.config.element.Renderer;
27 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
28 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
29 import org.apache.myfaces.context.FacesContextFactoryImpl;
30 import org.apache.myfaces.lifecycle.LifecycleFactoryImpl;
31 import org.apache.myfaces.renderkit.RenderKitFactoryImpl;
32 import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl;
33 import org.apache.myfaces.shared_impl.config.MyfacesConfig;
34 import org.apache.myfaces.shared_impl.util.ClassUtils;
35 import org.apache.myfaces.shared_impl.util.LocaleUtils;
36 import org.apache.myfaces.shared_impl.util.StateUtils;
37 import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
38 import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
39 import org.xml.sax.SAXException;
40
41 import javax.faces.FacesException;
42 import javax.faces.FactoryFinder;
43 import javax.faces.application.*;
44 import javax.faces.context.ExternalContext;
45 import javax.faces.el.PropertyResolver;
46 import javax.faces.el.VariableResolver;
47 import javax.faces.event.ActionListener;
48 import javax.faces.event.PhaseListener;
49 import javax.faces.lifecycle.Lifecycle;
50 import javax.faces.lifecycle.LifecycleFactory;
51 import javax.faces.render.RenderKit;
52 import javax.faces.render.RenderKitFactory;
53 import javax.faces.webapp.FacesServlet;
54 import java.io.*;
55 import java.lang.reflect.Constructor;
56 import java.lang.reflect.InvocationTargetException;
57 import java.lang.reflect.Method;
58 import java.net.JarURLConnection;
59 import java.net.URL;
60 import java.net.URLConnection;
61 import java.util.*;
62
63
64
65
66
67
68
69
70
71
72 public class FacesConfigurator
73 {
74 private static final Log log = LogFactory.getLog(FacesConfigurator.class);
75
76 private static final String STANDARD_FACES_CONFIG_RESOURCE
77 = "org.apache.myfaces.resource".replace('.', '/') + "/standard-faces-config.xml";
78 private static final String FACES_CONFIG_RESOURCE = "META-INF/faces-config.xml";
79
80 private static final String META_INF_SERVICES_RESOURCE_PREFIX = "META-INF/services/";
81
82 private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class.getName();
83 private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class.getName();
84 private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class.getName();
85 private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class.getName();
86 private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class.getName();
87 private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml";
88
89 private static final Set FACTORY_NAMES = new HashSet();
90 {
91 FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY);
92 FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY);
93 FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY);
94 FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY);
95 }
96
97
98 private ExternalContext _externalContext;
99 private FacesConfigUnmarshaller _unmarshaller;
100 private FacesConfigDispenser _dispenser;
101 private static final String JAR_EXTENSION = ".jar";
102 private static final String META_INF_MANIFEST_SUFFIX = "!/META-INF/MANIFEST.MF";
103 private static final String JAR_PREFIX = "jar:";
104
105 private static long lastUpdate;
106
107 public static final String MYFACES_API_PACKAGE_NAME = "myfaces-api";
108 public static final String MYFACES_IMPL_PACKAGE_NAME = "myfaces-impl";
109 public static final String MYFACES_TOMAHAWK_PACKAGE_NAME = "tomahawk";
110 public static final String MYFACES_TOMAHAWK_SANDBOX_PACKAGE_NAME = "tomahawk-sandbox";
111 public static final String MYFACES_TOBAGO_PACKAGE_NAME = "tobago-core";
112 public static final String COMMONS_EL_PACKAGE_NAME = "commons-el";
113 public static final String JSP_API_PACKAGE_NAME = "jsp-api";
114
115 public FacesConfigurator(ExternalContext externalContext)
116 {
117 _externalContext = externalContext;
118
119 }
120
121 private long getResourceLastModified(String resource)
122 {
123 try
124 {
125 URL url = _externalContext.getResource(resource);
126 if (url != null)
127 {
128 return getResourceLastModified(url);
129 }
130 }
131 catch (IOException e)
132 {
133 log.error("Could not read resource " + resource, e);
134 }
135 return 0;
136 }
137
138
139 private long getResourceLastModified(URL url) throws IOException
140 {
141 if ("file".equals(url.getProtocol()))
142 {
143 String externalForm = url.toExternalForm();
144
145 File file = new File(externalForm.substring(5));
146
147 return file.lastModified();
148 }
149 else
150 {
151 return getResourceLastModified(url.openConnection());
152 }
153 }
154
155
156 private long getResourceLastModified(URLConnection connection) throws IOException
157 {
158 long modified;
159 if (connection instanceof JarURLConnection)
160 {
161
162
163
164
165
166
167
168
169
170
171 URL jarFileUrl = ((JarURLConnection) connection).getJarFileURL();
172 URLConnection jarFileConnection = jarFileUrl.openConnection();
173
174 try
175 {
176 modified = jarFileConnection.getLastModified();
177 }
178 finally
179 {
180 try
181 {
182 jarFileConnection.getInputStream().close();
183 }
184 catch (Exception exception)
185 {
186
187 }
188 }
189 }
190 else
191 {
192 modified = connection.getLastModified();
193 }
194
195 return modified;
196 }
197
198 private long getLastModifiedTime(){
199 long lastModified = 0;
200 long resModified;
201
202 resModified = getResourceLastModified(DEFAULT_FACES_CONFIG);
203 if (resModified > lastModified)
204 lastModified = resModified;
205
206
207 List configFilesList = getConfigFilesList();
208
209 for (int i = 0; i < configFilesList.size(); i++) {
210 String systemId = (String) configFilesList.get(i);
211
212 resModified = getResourceLastModified(systemId);
213 if (resModified > lastModified)
214 lastModified = resModified;
215
216 }
217
218 return lastModified;
219 }
220
221 public void update(){
222 long refreshPeriod = (MyfacesConfig.getCurrentInstance(_externalContext).getConfigRefreshPeriod())*1000;
223
224 if (refreshPeriod > 0){
225 long ttl = lastUpdate + refreshPeriod;
226 if ((System.currentTimeMillis() > ttl) && (getLastModifiedTime() > ttl)) {
227 log.info("Faces config-files are being reloaded. If you don't want this reload to happen (e.g. in production), set the web-xml-parameter: "+MyfacesConfig.INIT_PARAM_CONFIG_REFRESH_PERIOD +" to -1.");
228 purgeConfiguration();
229 configure();
230 }
231 }
232 }
233
234 private void purgeConfiguration() {
235 Method appplicationPurgeMethod = null;
236 Method renderKitPurgeMethod = null;
237 Method lifecyclePurgeMethod = null;
238
239 Class[] emptyParameterList = new Class[]{};
240
241 ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
242 RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
243 LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
244
245 try {
246
247 appplicationPurgeMethod = applicationFactory.getClass().getMethod("purgeApplication", emptyParameterList);
248 renderKitPurgeMethod = renderKitFactory.getClass().getMethod("purgeRenderKit", emptyParameterList);
249 lifecyclePurgeMethod = lifecycleFactory.getClass().getMethod("purgeLifecycle", emptyParameterList);
250
251 }
252 catch (NoSuchMethodException e)
253 {
254 log.error("Configuration objects do not support clean-up. Update aborted",e);
255 return;
256 }
257
258 if (appplicationPurgeMethod != null && renderKitPurgeMethod != null && lifecyclePurgeMethod != null)
259 {
260 try
261 {
262 RuntimeConfig.getCurrentInstance(_externalContext).purge();
263 appplicationPurgeMethod.invoke(applicationFactory, emptyParameterList);
264 renderKitPurgeMethod.invoke(renderKitFactory, emptyParameterList);
265 lifecyclePurgeMethod.invoke(lifecycleFactory, emptyParameterList);
266 }
267 catch (IllegalAccessException e)
268 {
269 log.fatal("Error during configuration clean-up" + e.getMessage(),e);
270 }
271 catch (InvocationTargetException e)
272 {
273 log.fatal("Error during configuration clean-up" + e.getMessage(),e);
274 }
275 }
276 }
277
278 public void configure()
279 throws FacesException
280 {
281
282
283
284 _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(_externalContext);
285 _dispenser = new DigesterFacesConfigDispenserImpl();
286
287 try
288 {
289 feedStandardConfig();
290 feedMetaInfServicesFactories();
291
292 feedClassloaderConfigurations();
293 feedContextSpecifiedConfig();
294 feedWebAppConfig();
295
296 if(log.isInfoEnabled())
297 {
298 logMetaInf();
299 }
300 } catch (IOException e)
301 {
302 throw new FacesException(e);
303 } catch (SAXException e)
304 {
305 throw new FacesException(e);
306 }
307
308 configureFactories();
309 configureApplication();
310 configureRenderKits();
311 configureRuntimeConfig();
312 configureLifecycle();
313 handleSerialFactory();
314
315
316 lastUpdate = System.currentTimeMillis();
317 }
318
319 private void feedStandardConfig() throws IOException, SAXException
320 {
321 InputStream stream = ClassUtils.getResourceAsStream(STANDARD_FACES_CONFIG_RESOURCE);
322 if (stream == null) throw new FacesException("Standard faces config " + STANDARD_FACES_CONFIG_RESOURCE + " not found");
323 if (log.isInfoEnabled()) log.info("Reading standard config " + STANDARD_FACES_CONFIG_RESOURCE);
324 _dispenser.feed(_unmarshaller.getFacesConfig(stream, STANDARD_FACES_CONFIG_RESOURCE));
325 stream.close();
326 }
327
328
329
330
331 protected void logMetaInf()
332 {
333 try
334 {
335 List li = new ArrayList();
336 li.add(new VersionInfo(MYFACES_API_PACKAGE_NAME));
337 li.add(new VersionInfo(MYFACES_IMPL_PACKAGE_NAME));
338 li.add(new VersionInfo(MYFACES_TOMAHAWK_SANDBOX_PACKAGE_NAME));
339 li.add(new VersionInfo(MYFACES_TOMAHAWK_PACKAGE_NAME));
340 li.add(new VersionInfo(MYFACES_TOBAGO_PACKAGE_NAME));
341
342 Iterator it = ClassUtils.getResources("META-INF/MANIFEST.MF",
343 this);
344 while (it.hasNext())
345 {
346 URL url = (URL)it.next();
347
348 for (int i = 0; i < li.size(); i++)
349 {
350 VersionInfo versionInfo = (VersionInfo) li.get(i);
351 if(checkJar(versionInfo, url))
352 break;
353 }
354 }
355
356 for (int i = 0; i < li.size(); i++)
357 {
358 VersionInfo versionInfo = (VersionInfo) li.get(i);
359
360 if(versionInfo.getUsedVersion()!=null)
361 {
362 if(log.isInfoEnabled())
363 {
364 log.info("Artifact '" + versionInfo.getPackageName()
365 + "' was found in version '" + versionInfo.getUsedVersion()
366 + "' from path '" + versionInfo.getUsedVersionPath() + "'");
367 }
368 }
369 else
370 {
371 if(log.isInfoEnabled())
372 {
373 log.info("Artifact '" + versionInfo.getPackageName() + "' was not found.");
374 }
375 }
376 }
377 }
378 catch (Throwable e)
379 {
380 throw new FacesException(e);
381 }
382 }
383
384 private static boolean checkJar(VersionInfo versionInfo, URL path)
385 {
386 int index;
387
388 String version = versionInfo.getLastVersion();
389
390 String pathString = path.toString();
391
392 if(!pathString.startsWith(JAR_PREFIX))
393 return false;
394
395 if(!(pathString.length()>(META_INF_MANIFEST_SUFFIX.length()+JAR_PREFIX.length())))
396 {
397 if(log.isDebugEnabled())
398 log.debug("PathString : "+pathString+" not long enough to be parsed.");
399 return false;
400 }
401
402 pathString = pathString.substring(JAR_PREFIX.length(),pathString.length()-META_INF_MANIFEST_SUFFIX.length());
403
404 File file = new File(pathString);
405
406 String fileName = file.getName();
407
408 if(fileName.endsWith(JAR_EXTENSION) && ((index=fileName.indexOf(versionInfo.getPackageName()))!=-1))
409 {
410 int beginIndex = index+versionInfo.getPackageName().length()+1;
411
412 if(beginIndex > fileName.length()-1)
413 {
414 log.debug("beginIndex out of bounds. fileName: "+fileName);
415 return false;
416 }
417
418 int endIndex = fileName.length()-JAR_EXTENSION.length();
419
420 if(endIndex<0 || endIndex<=beginIndex)
421 {
422 log.debug("endIndex out of bounds. fileName: "+fileName);
423 return false;
424 }
425
426 String newVersion = fileName.substring(beginIndex, endIndex);
427
428 if(version == null)
429 {
430 versionInfo.addJarInfo(pathString,newVersion);
431 }
432 else if(version.equals(newVersion))
433 {
434 versionInfo.addJarInfo(pathString, version);
435 }
436 else
437 {
438 log.error("You are using the MyFaces-package : "+versionInfo.getPackageName() +
439 " in different versions; first (and probably used) version is : "+versionInfo.getUsedVersion() +", currently encountered version is : "+newVersion+
440 ". This will cause undesired behaviour. Please clean out your class-path." +
441 " The first encountered version is loaded from : "+versionInfo.getUsedVersionPath()+". The currently encountered version is loaded from : "+
442 path);
443 }
444
445 return true;
446 }
447
448 return false;
449 }
450
451
452
453
454
455 protected void feedMetaInfServicesFactories()
456 {
457 try
458 {
459 for (Iterator iterator = FACTORY_NAMES.iterator(); iterator.hasNext();)
460 {
461 String factoryName = (String)iterator.next();
462 Iterator it = ClassUtils.getResources(META_INF_SERVICES_RESOURCE_PREFIX + factoryName,
463 this);
464 while (it.hasNext())
465 {
466 URL url = (URL)it.next();
467 InputStream stream = openStreamWithoutCache(url);
468 InputStreamReader isr = new InputStreamReader(stream);
469 BufferedReader br = new BufferedReader(isr);
470 String className;
471 try
472 {
473 className = br.readLine();
474 }
475 catch (IOException e)
476 {
477 throw new FacesException("Unable to read class name from file "
478 + url.toExternalForm(), e);
479 }
480 br.close();
481 isr.close();
482 stream.close();
483
484 if (log.isInfoEnabled()) log.info("Found " + factoryName + " factory implementation: " + className);
485
486 if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY))
487 {
488 _dispenser.feedApplicationFactory(className);
489 } else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY))
490 {
491 _dispenser.feedFacesContextFactory(className);
492 } else if (factoryName.equals(FactoryFinder.LIFECYCLE_FACTORY))
493 {
494 _dispenser.feedLifecycleFactory(className);
495 } else if (factoryName.equals(FactoryFinder.RENDER_KIT_FACTORY))
496 {
497 _dispenser.feedRenderKitFactory(className);
498 } else
499 {
500 throw new IllegalStateException("Unexpected factory name " + factoryName);
501 }
502 }
503 }
504 }
505 catch (Throwable e)
506 {
507 throw new FacesException(e);
508 }
509 }
510
511 private InputStream openStreamWithoutCache(URL url)
512 throws IOException
513 {
514 URLConnection connection = url.openConnection();
515 connection.setUseCaches(false);
516 return connection.getInputStream();
517 }
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 private void feedClassloaderConfigurations()
536 {
537 try
538 {
539 Iterator it = ClassUtils.getResources(FACES_CONFIG_RESOURCE, this);
540 while (it.hasNext())
541 {
542 URL url = (URL)it.next();
543 InputStream stream = openStreamWithoutCache(url);
544 String systemId = url.toExternalForm();
545 if (log.isInfoEnabled()) log.info("Reading config " + systemId);
546 _dispenser.feed(_unmarshaller.getFacesConfig(stream, systemId));
547 stream.close();
548 }
549 }
550 catch (Throwable e)
551 {
552 throw new FacesException(e);
553 }
554 }
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669 private void feedContextSpecifiedConfig() throws IOException, SAXException
670 {
671 List configFilesList = getConfigFilesList();
672 for (int i = 0; i < configFilesList.size(); i++) {
673 String systemId = (String) configFilesList.get(i);
674 InputStream stream = _externalContext.getResourceAsStream(systemId);
675 if (stream == null)
676 {
677 log.error("Faces config resource " + systemId + " not found");
678 continue;
679 }
680
681 if (log.isInfoEnabled()) log.info("Reading config " + systemId);
682 _dispenser.feed(_unmarshaller.getFacesConfig(stream, systemId));
683 stream.close();
684 }
685 }
686
687 private List getConfigFilesList() {
688 String configFiles = _externalContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
689 List configFilesList = new ArrayList();
690 if (configFiles != null)
691 {
692 StringTokenizer st = new StringTokenizer(configFiles, ",", false);
693 while (st.hasMoreTokens())
694 {
695 String systemId = st.nextToken().trim();
696
697 if (DEFAULT_FACES_CONFIG.equals(systemId))
698 {
699 if(log.isWarnEnabled())
700 log.warn(DEFAULT_FACES_CONFIG + " has been specified in the " +
701 FacesServlet.CONFIG_FILES_ATTR + " context parameter of " +
702 "the deployment descriptor. This will automatically be removed, " +
703 "if we wouldn't do this, it would be loaded twice. See JSF spec 1.1, 10.3.2");
704 }
705 else
706 configFilesList.add(systemId);
707
708
709 }
710 }
711 return configFilesList;
712 }
713
714
715 private void feedWebAppConfig() throws IOException, SAXException
716 {
717
718 InputStream stream = _externalContext.getResourceAsStream(DEFAULT_FACES_CONFIG);
719 if (stream != null)
720 {
721 if (log.isInfoEnabled()) log.info("Reading config /WEB-INF/faces-config.xml");
722 _dispenser.feed(_unmarshaller.getFacesConfig(stream, DEFAULT_FACES_CONFIG));
723 stream.close();
724 }
725 }
726
727
728 private void configureFactories()
729 {
730 setFactories(FactoryFinder.APPLICATION_FACTORY, _dispenser.getApplicationFactoryIterator(), DEFAULT_APPLICATION_FACTORY);
731 setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, _dispenser.getFacesContextFactoryIterator(), DEFAULT_FACES_CONTEXT_FACTORY);
732 setFactories(FactoryFinder.LIFECYCLE_FACTORY, _dispenser.getLifecycleFactoryIterator(), DEFAULT_LIFECYCLE_FACTORY);
733 setFactories(FactoryFinder.RENDER_KIT_FACTORY, _dispenser.getRenderKitFactoryIterator(), DEFAULT_RENDER_KIT_FACTORY);
734 }
735
736
737 private void setFactories(String factoryName, Iterator factories, String defaultFactory)
738 {
739 FactoryFinder.setFactory(factoryName, defaultFactory);
740 while (factories.hasNext())
741 {
742 FactoryFinder.setFactory(factoryName, (String) factories.next());
743 }
744 }
745
746
747 private void configureApplication()
748 {
749 Application application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
750 application.setActionListener((ActionListener) getApplicationObject(ActionListener.class, _dispenser.getActionListenerIterator(), null));
751
752 if (_dispenser.getDefaultLocale() != null)
753 {
754 application.setDefaultLocale(
755 LocaleUtils.toLocale(_dispenser.getDefaultLocale()));
756 }
757
758 if (_dispenser.getDefaultRenderKitId() != null)
759 {
760 application.setDefaultRenderKitId(_dispenser.getDefaultRenderKitId());
761 }
762
763 if (_dispenser.getMessageBundle() != null)
764 {
765 application.setMessageBundle(_dispenser.getMessageBundle());
766 }
767
768 application.setNavigationHandler((NavigationHandler) getApplicationObject(NavigationHandler.class,
769 _dispenser.getNavigationHandlerIterator(), application.getNavigationHandler()));
770 application.setPropertyResolver((PropertyResolver) getApplicationObject(PropertyResolver.class,
771 _dispenser.getPropertyResolverIterator(), application.getPropertyResolver()));
772 application.setStateManager((StateManager) getApplicationObject(StateManager.class,
773 _dispenser.getStateManagerIterator(), application.getStateManager()));
774 List locales = new ArrayList();
775 for (Iterator it = _dispenser.getSupportedLocalesIterator(); it.hasNext();)
776 {
777 locales.add(LocaleUtils.toLocale((String) it.next()));
778 }
779 application.setSupportedLocales(locales);
780
781 application.setVariableResolver((VariableResolver) getApplicationObject(VariableResolver.class,
782 _dispenser.getVariableResolverIterator(), application.getVariableResolver()));
783 application.setViewHandler((ViewHandler) getApplicationObject(ViewHandler.class,
784 _dispenser.getViewHandlerIterator(), application.getViewHandler()));
785
786 for (Iterator it = _dispenser.getComponentTypes(); it.hasNext();)
787 {
788 String componentType = (String) it.next();
789 application.addComponent(componentType,
790 _dispenser.getComponentClass(componentType));
791 }
792
793 for (Iterator it = _dispenser.getConverterIds(); it.hasNext();)
794 {
795 String converterId = (String) it.next();
796 application.addConverter(converterId,
797 _dispenser.getConverterClassById(converterId));
798 }
799
800 for (Iterator it = _dispenser.getConverterClasses(); it.hasNext();)
801 {
802 String converterClass = (String) it.next();
803 try
804 {
805 application.addConverter(ClassUtils.simpleClassForName(converterClass),
806 _dispenser.getConverterClassByClass(converterClass));
807 }
808 catch(Exception ex)
809 {
810 log.error("Converter could not be added. Reason:",ex);
811 }
812 }
813
814 for (Iterator it = _dispenser.getValidatorIds(); it.hasNext();)
815 {
816 String validatorId = (String) it.next();
817 application.addValidator(validatorId,
818 _dispenser.getValidatorClass(validatorId));
819 }
820 }
821
822
823 private Object getApplicationObject(Class interfaceClass, Iterator classNamesIterator, Object defaultObject)
824 {
825 Object current = defaultObject;
826
827 while (classNamesIterator.hasNext())
828 {
829 String implClassName = (String) classNamesIterator.next();
830 Class implClass = ClassUtils.simpleClassForName(implClassName);
831
832
833 if (!interfaceClass.isAssignableFrom(implClass))
834 {
835 throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
836 }
837
838 if (current == null)
839 {
840
841 current = ClassUtils.newInstance(implClass);
842 } else
843 {
844
845 try
846 {
847 Constructor delegationConstructor = implClass.getConstructor(new Class[]{interfaceClass});
848
849 try
850 {
851
852 current = delegationConstructor.newInstance(new Object[]{current});
853 } catch (InstantiationException e)
854 {
855 log.error(e.getMessage(), e);
856 throw new FacesException(e);
857 } catch (IllegalAccessException e)
858 {
859 log.error(e.getMessage(), e);
860 throw new FacesException(e);
861 } catch (InvocationTargetException e)
862 {
863 log.error(e.getMessage(), e);
864 throw new FacesException(e);
865 }
866 } catch (NoSuchMethodException e)
867 {
868
869 current = ClassUtils.newInstance(implClass);
870 }
871 }
872 }
873
874 return current;
875 }
876
877
878 private void configureRuntimeConfig()
879 {
880 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext);
881
882 for (Iterator iterator = _dispenser.getManagedBeans(); iterator.hasNext();)
883 {
884 ManagedBean bean = (ManagedBean) iterator.next();
885 ManagedBean oldBean = runtimeConfig.getManagedBean(bean.getManagedBeanName());
886
887 if(log.isWarnEnabled() && oldBean != null)
888 log.warn("More than one managed bean w/ the name of '"
889 + bean.getManagedBeanName() + "' registered. First managed bean was registered in :" +
890 oldBean.getConfigLocation()+", new managed bean was registered in : "+
891 bean.getConfigLocation()+". The first definition of the managed-bean will be ignored by the standard MyFaces variable resolver!");
892
893 runtimeConfig.addManagedBean(bean.getManagedBeanName(), bean);
894
895 }
896
897 removePurgedBeansFromSessionAndApplication(runtimeConfig);
898
899 for (Iterator iterator = _dispenser.getNavigationRules(); iterator.hasNext();)
900 {
901 NavigationRule rule = (NavigationRule) iterator.next();
902 runtimeConfig.addNavigationRule(rule);
903
904 }
905
906 for (Iterator it = _dispenser.getConverterConfigurationByClassName(); it.hasNext();)
907 {
908 String converterClassName = (String) it.next();
909
910 runtimeConfig.addConverterConfiguration(converterClassName,
911 _dispenser.getConverterConfiguration(converterClassName));
912 }
913 }
914
915 private void removePurgedBeansFromSessionAndApplication(RuntimeConfig runtimeConfig) {
916 Map oldManagedBeans = runtimeConfig.getManagedBeansNotReaddedAfterPurge();
917 if(oldManagedBeans!=null) {
918 Iterator it=oldManagedBeans.entrySet().iterator();
919 while(it.hasNext()) {
920 Map.Entry entry = (Map.Entry) it.next();
921 ManagedBean bean = (ManagedBean) entry.getValue();
922
923 String scope = bean.getManagedBeanScope();
924
925 if(scope!=null && scope.equalsIgnoreCase("session")) {
926 _externalContext.getSessionMap().remove(entry.getKey());
927 }
928 else if(scope!=null && scope.equalsIgnoreCase("application")) {
929 _externalContext.getApplicationMap().remove(entry.getKey());
930 }
931 }
932 }
933 runtimeConfig.resetManagedBeansNotReaddedAfterPurge();
934 }
935
936
937 private void configureRenderKits()
938 {
939 RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
940
941 for (Iterator iterator = _dispenser.getRenderKitIds(); iterator.hasNext();)
942 {
943 String renderKitId = (String) iterator.next();
944 String renderKitClass = _dispenser.getRenderKitClass(renderKitId);
945
946 if (renderKitClass == null)
947 {
948 renderKitClass = DEFAULT_RENDER_KIT_CLASS;
949 }
950
951 RenderKit renderKit = (RenderKit) ClassUtils.newInstance(renderKitClass);
952
953 for (Iterator renderers = _dispenser.getRenderers(renderKitId); renderers.hasNext();)
954 {
955 Renderer element = (Renderer) renderers.next();
956 javax.faces.render.Renderer renderer;
957 try {
958 renderer = (javax.faces.render.Renderer) ClassUtils.newInstance(element.getRendererClass());
959 } catch(Throwable e) {
960
961 log.error("failed to configure class " + element.getRendererClass(), e);
962 continue;
963 }
964
965 renderKit.addRenderer(element.getComponentFamily(), element.getRendererType(), renderer);
966 }
967
968 renderKitFactory.addRenderKit(renderKitId, renderKit);
969 }
970 }
971
972
973 private void configureLifecycle()
974 {
975
976 LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
977 Lifecycle lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
978
979
980 for (Iterator iterator = _dispenser.getLifecyclePhaseListeners(); iterator.hasNext();)
981 {
982 String listenerClassName = (String) iterator.next();
983 try
984 {
985 lifecycle.addPhaseListener((PhaseListener) ClassUtils.newInstance(listenerClassName));
986 } catch (ClassCastException e)
987 {
988 log.error("Class " + listenerClassName + " does not implement PhaseListener",e);
989 }
990 }
991 }
992
993
994 private String getLifecycleId()
995 {
996 String id = _externalContext.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
997
998 if (id != null)
999 {
1000 return id;
1001 }
1002
1003 return LifecycleFactory.DEFAULT_LIFECYCLE;
1004 }
1005
1006 public static class VersionInfo
1007 {
1008 private String packageName;
1009 private List jarInfos;
1010
1011 public VersionInfo(String packageName)
1012 {
1013
1014 this.packageName = packageName;
1015 }
1016
1017 public String getPackageName()
1018 {
1019 return packageName;
1020 }
1021
1022 public void setPackageName(String packageName)
1023 {
1024 this.packageName = packageName;
1025 }
1026
1027 public void addJarInfo(String path, String version)
1028 {
1029 if(jarInfos == null)
1030 {
1031 jarInfos = new ArrayList();
1032 }
1033
1034 jarInfos.add(new JarInfo(path, version));
1035 }
1036
1037 public String getLastVersion()
1038 {
1039 if(jarInfos == null)
1040 return null;
1041 if(jarInfos.size()==0)
1042 return null;
1043
1044 return ((JarInfo) jarInfos.get(jarInfos.size()-1)).getVersion();
1045 }
1046
1047
1048
1049
1050
1051 public String getUsedVersion()
1052 {
1053
1054 if(jarInfos == null)
1055 return null;
1056 if(jarInfos.size()==0)
1057 return null;
1058
1059 return ((JarInfo) jarInfos.get(0)).getVersion();
1060 }
1061
1062
1063
1064
1065
1066 public String getUsedVersionPath()
1067 {
1068
1069 if(jarInfos == null)
1070 return null;
1071 if(jarInfos.size()==0)
1072 return null;
1073
1074 return ((JarInfo) jarInfos.get(0)).getUrl();
1075
1076 }
1077 }
1078
1079 public static class JarInfo
1080 {
1081 private String url;
1082 private String version;
1083
1084 public JarInfo(String url, String version)
1085 {
1086 this.url = url;
1087 this.version = version;
1088 }
1089
1090 public String getVersion()
1091 {
1092 return version;
1093 }
1094
1095 public void setVersion(String version)
1096 {
1097 this.version = version;
1098 }
1099
1100 public String getUrl()
1101 {
1102 return url;
1103 }
1104
1105 public void setUrl(String url)
1106 {
1107 this.url = url;
1108 }
1109 }
1110
1111
1112 private void handleSerialFactory(){
1113
1114 String serialProvider = _externalContext.getInitParameter(StateUtils.SERIAL_FACTORY);
1115 SerialFactory serialFactory = null;
1116
1117 if(serialProvider == null)
1118 {
1119 serialFactory = new DefaultSerialFactory();
1120 }
1121 else
1122 {
1123 try
1124 {
1125 serialFactory = (SerialFactory) ClassUtils.newInstance(serialProvider);
1126
1127 }catch(ClassCastException e){
1128 log.error("Make sure '" + serialProvider +
1129 "' implements the correct interface", e);
1130 }
1131 catch(Exception e){
1132 log.error(e);
1133 }
1134 finally
1135 {
1136 if(serialFactory == null)
1137 {
1138 serialFactory = new DefaultSerialFactory();
1139 log.error("Using default serialization provider");
1140 }
1141 }
1142
1143 }
1144
1145 log.info("Serialization provider : " + serialFactory.getClass());
1146 _externalContext.getApplicationMap().put(StateUtils.SERIAL_FACTORY, serialFactory);
1147
1148 }
1149
1150 }