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