001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.myfaces.config;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.apache.myfaces.application.ApplicationFactoryImpl;
024: import org.apache.myfaces.application.ApplicationImpl;
025: import org.apache.myfaces.config.element.ManagedBean;
026: import org.apache.myfaces.config.element.NavigationRule;
027: import org.apache.myfaces.config.element.Renderer;
028: import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
029: import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
030: import org.apache.myfaces.config.impl.digester.elements.ResourceBundle;
031: import org.apache.myfaces.context.FacesContextFactoryImpl;
032: import org.apache.myfaces.el.DefaultPropertyResolver;
033: import org.apache.myfaces.el.VariableResolverImpl;
034: import org.apache.myfaces.lifecycle.LifecycleFactoryImpl;
035: import org.apache.myfaces.renderkit.RenderKitFactoryImpl;
036: import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl;
037: import org.apache.myfaces.shared_impl.util.ClassUtils;
038: import org.apache.myfaces.shared_impl.util.LocaleUtils;
039: import org.apache.myfaces.shared_impl.util.StateUtils;
040: import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
041: import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
042: import org.xml.sax.SAXException;
043:
044: import javax.el.ELResolver;
045: import javax.faces.FacesException;
046: import javax.faces.FactoryFinder;
047: import javax.faces.application.*;
048: import javax.faces.context.ExternalContext;
049: import javax.faces.el.PropertyResolver;
050: import javax.faces.el.VariableResolver;
051: import javax.faces.event.ActionListener;
052: import javax.faces.event.PhaseListener;
053: import javax.faces.lifecycle.Lifecycle;
054: import javax.faces.lifecycle.LifecycleFactory;
055: import javax.faces.render.RenderKit;
056: import javax.faces.render.RenderKitFactory;
057: import javax.faces.webapp.FacesServlet;
058: import java.io.*;
059: import java.lang.reflect.Constructor;
060: import java.lang.reflect.InvocationTargetException;
061: import java.net.URL;
062: import java.net.URLConnection;
063: import java.util.*;
064:
065: /**
066: * Configures everything for a given context. The FacesConfigurator is independent of the concrete implementations that
067: * lie behind FacesConfigUnmarshaller and FacesConfigDispenser.
068: *
069: * @author Manfred Geiler (latest modification by $Author: baranda $)
070: * @version $Revision: 542029 $ $Date: 2007-05-27 22:04:24 +0200 (So, 27 Mai 2007) $
071: */
072: @SuppressWarnings("deprecation")
073: public class FacesConfigurator {
074: private static final Log log = LogFactory
075: .getLog(FacesConfigurator.class);
076:
077: private static final String STANDARD_FACES_CONFIG_RESOURCE = "META-INF/standard-faces-config.xml";
078: private static final String FACES_CONFIG_RESOURCE = "META-INF/faces-config.xml";
079:
080: private static final String META_INF_SERVICES_RESOURCE_PREFIX = "META-INF/services/";
081:
082: private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class
083: .getName();
084: private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class
085: .getName();
086: private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class
087: .getName();
088: private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class
089: .getName();
090: private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class
091: .getName();
092: private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml";
093:
094: private static final Set<String> FACTORY_NAMES = new HashSet<String>();
095: {
096: FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY);
097: FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY);
098: FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY);
099: FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY);
100: }
101:
102: private final ExternalContext _externalContext;
103: private FacesConfigUnmarshaller _unmarshaller;
104: private FacesConfigDispenser _dispenser;
105:
106: private RuntimeConfig _runtimeConfig;
107: private static final String JAR_EXTENSION = ".jar";
108: private static final String META_INF_MANIFEST_SUFFIX = "!/META-INF/MANIFEST.MF";
109: private static final String JAR_PREFIX = "jar:";
110:
111: public static final String MYFACES_API_PACKAGE_NAME = "myfaces-api";
112: public static final String MYFACES_IMPL_PACKAGE_NAME = "myfaces-impl";
113: public static final String MYFACES_TOMAHAWK_PACKAGE_NAME = "tomahawk";
114: public static final String MYFACES_TOMAHAWK_SANDBOX_PACKAGE_NAME = "tomahawk-sandbox";
115: public static final String COMMONS_EL_PACKAGE_NAME = "commons-el";
116: public static final String JSP_API_PACKAGE_NAME = "jsp-api";
117:
118: public FacesConfigurator(ExternalContext externalContext) {
119: if (externalContext == null) {
120: throw new IllegalArgumentException(
121: "external context must not be null");
122: }
123: _externalContext = externalContext;
124:
125: }
126:
127: /**
128: * @param unmarshaller
129: * the unmarshaller to set
130: */
131: public void setUnmarshaller(FacesConfigUnmarshaller unmarshaller) {
132: _unmarshaller = unmarshaller;
133: }
134:
135: /**
136: * @return the unmarshaller
137: */
138: protected FacesConfigUnmarshaller getUnmarshaller() {
139: if (_unmarshaller == null) {
140: _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(
141: _externalContext);
142: }
143: return _unmarshaller;
144: }
145:
146: /**
147: * @param dispenser
148: * the dispenser to set
149: */
150: public void setDispenser(FacesConfigDispenser dispenser) {
151: _dispenser = dispenser;
152: }
153:
154: /**
155: * @return the dispenser
156: */
157: protected FacesConfigDispenser getDispenser() {
158: if (_dispenser == null) {
159: _dispenser = new DigesterFacesConfigDispenserImpl();
160: }
161: return _dispenser;
162: }
163:
164: public void configure() throws FacesException {
165: try {
166: feedStandardConfig();
167: feedMetaInfServicesFactories();
168: feedClassloaderConfigurations();
169: feedContextSpecifiedConfig();
170: feedWebAppConfig();
171:
172: if (log.isInfoEnabled()) {
173: logMetaInf();
174: }
175: } catch (IOException e) {
176: throw new FacesException(e);
177: } catch (SAXException e) {
178: throw new FacesException(e);
179: }
180:
181: configureFactories();
182: configureApplication();
183: configureRenderKits();
184: configureRuntimeConfig();
185: configureLifecycle();
186: handleSerialFactory();
187: }
188:
189: private void feedStandardConfig() throws IOException, SAXException {
190: InputStream stream = ClassUtils
191: .getResourceAsStream(STANDARD_FACES_CONFIG_RESOURCE);
192: if (stream == null)
193: throw new FacesException("Standard faces config "
194: + STANDARD_FACES_CONFIG_RESOURCE + " not found");
195: if (log.isInfoEnabled())
196: log.info("Reading standard config "
197: + STANDARD_FACES_CONFIG_RESOURCE);
198: getDispenser().feed(
199: getUnmarshaller().getFacesConfig(stream,
200: STANDARD_FACES_CONFIG_RESOURCE));
201: stream.close();
202: }
203:
204: /**
205: * This method performs part of the factory search outlined in section 10.2.6.1.
206: */
207: protected void logMetaInf() {
208: try {
209: List<VersionInfo> li = new ArrayList<VersionInfo>();
210: li.add(new VersionInfo(MYFACES_API_PACKAGE_NAME));
211: li.add(new VersionInfo(MYFACES_IMPL_PACKAGE_NAME));
212: li.add(new VersionInfo(
213: MYFACES_TOMAHAWK_SANDBOX_PACKAGE_NAME));
214: li.add(new VersionInfo(MYFACES_TOMAHAWK_PACKAGE_NAME));
215:
216: Iterator it = ClassUtils.getResources(
217: "META-INF/MANIFEST.MF", this );
218: while (it.hasNext()) {
219: URL url = (URL) it.next();
220:
221: for (int i = 0; i < li.size(); i++) {
222: VersionInfo versionInfo = li.get(i);
223: if (checkJar(versionInfo, url))
224: break;
225: }
226: }
227:
228: for (int i = 0; i < li.size(); i++) {
229: VersionInfo versionInfo = li.get(i);
230:
231: if (versionInfo.getUsedVersion() != null) {
232: if (log.isInfoEnabled()) {
233: log.info("Starting up MyFaces-package : "
234: + versionInfo.getPackageName()
235: + " in version : "
236: + versionInfo.getUsedVersion()
237: + " from path : "
238: + versionInfo.getUsedVersionPath());
239: }
240: } else {
241: if (log.isInfoEnabled()) {
242: log.info("MyFaces-package : "
243: + versionInfo.getPackageName()
244: + " not found.");
245: }
246: }
247: }
248: } catch (Throwable e) {
249: throw new FacesException(e);
250: }
251: }
252:
253: private static boolean checkJar(VersionInfo versionInfo, URL path) {
254: int index;
255:
256: String version = versionInfo.getLastVersion();
257:
258: String pathString = path.toString();
259:
260: if (!pathString.startsWith(JAR_PREFIX))
261: return false;
262:
263: if (!(pathString.length() > (META_INF_MANIFEST_SUFFIX.length() + JAR_PREFIX
264: .length()))) {
265: if (log.isDebugEnabled())
266: log.debug("PathString : " + pathString
267: + " not long enough to be parsed.");
268: return false;
269: }
270:
271: pathString = pathString
272: .substring(JAR_PREFIX.length(), pathString.length()
273: - META_INF_MANIFEST_SUFFIX.length());
274:
275: File file = new File(pathString);
276:
277: String fileName = file.getName();
278:
279: if (fileName.endsWith(JAR_EXTENSION)
280: && ((index = fileName.indexOf(versionInfo
281: .getPackageName())) != -1)) {
282: int beginIndex = index
283: + versionInfo.getPackageName().length() + 1;
284:
285: if (beginIndex > fileName.length() - 1) {
286: log.debug("beginIndex out of bounds. fileName: "
287: + fileName);
288: return false;
289: }
290:
291: int endIndex = fileName.length() - JAR_EXTENSION.length();
292:
293: if (endIndex < 0 || endIndex <= beginIndex) {
294: log.debug("endIndex out of bounds. fileName: "
295: + fileName);
296: return false;
297: }
298:
299: String newVersion = fileName
300: .substring(beginIndex, endIndex);
301:
302: if (version == null) {
303: versionInfo.addJarInfo(pathString, newVersion);
304: } else if (version.equals(newVersion)) {
305: versionInfo.addJarInfo(pathString, version);
306: } else {
307: log
308: .error("You are using the MyFaces-package : "
309: + versionInfo.getPackageName()
310: + " in different versions; first (and probably used) version is : "
311: + versionInfo.getUsedVersion()
312: + ", currently encountered version is : "
313: + newVersion
314: + ". This will cause undesired behaviour. Please clean out your class-path."
315: + " The first encountered version is loaded from : "
316: + versionInfo.getUsedVersionPath()
317: + ". The currently encountered version is loaded from : "
318: + path);
319: }
320:
321: return true;
322: }
323:
324: return false;
325: }
326:
327: /**
328: * This method performs part of the factory search outlined in section 10.2.6.1.
329: */
330: protected void feedMetaInfServicesFactories() {
331: try {
332: for (Iterator<String> iterator = FACTORY_NAMES.iterator(); iterator
333: .hasNext();) {
334: String factoryName = iterator.next();
335: Iterator it = ClassUtils
336: .getResources(META_INF_SERVICES_RESOURCE_PREFIX
337: + factoryName, this );
338: while (it.hasNext()) {
339: URL url = (URL) it.next();
340: InputStream stream = openStreamWithoutCache(url);
341: InputStreamReader isr = new InputStreamReader(
342: stream);
343: BufferedReader br = new BufferedReader(isr);
344: String className;
345: try {
346: className = br.readLine();
347: } catch (IOException e) {
348: throw new FacesException(
349: "Unable to read class name from file "
350: + url.toExternalForm(), e);
351: }
352: br.close();
353: isr.close();
354: stream.close();
355:
356: if (log.isInfoEnabled())
357: log.info("Found " + factoryName
358: + " factory implementation: "
359: + className);
360:
361: if (factoryName
362: .equals(FactoryFinder.APPLICATION_FACTORY)) {
363: getDispenser()
364: .feedApplicationFactory(className);
365: } else if (factoryName
366: .equals(FactoryFinder.FACES_CONTEXT_FACTORY)) {
367: getDispenser().feedFacesContextFactory(
368: className);
369: } else if (factoryName
370: .equals(FactoryFinder.LIFECYCLE_FACTORY)) {
371: getDispenser().feedLifecycleFactory(className);
372: } else if (factoryName
373: .equals(FactoryFinder.RENDER_KIT_FACTORY)) {
374: getDispenser().feedRenderKitFactory(className);
375: } else {
376: throw new IllegalStateException(
377: "Unexpected factory name "
378: + factoryName);
379: }
380: }
381: }
382: } catch (Throwable e) {
383: throw new FacesException(e);
384: }
385: }
386:
387: private InputStream openStreamWithoutCache(URL url)
388: throws IOException {
389: URLConnection connection = url.openConnection();
390: connection.setUseCaches(false);
391: return connection.getInputStream();
392: }
393:
394: /*
395: * private Map expandFactoryNames(Set factoryNames) { Map names = new HashMap(); Iterator itr =
396: * factoryNames.iterator(); while (itr.hasNext()) { String name = (String) itr.next();
397: * names.put(META_INF_SERVICES_LOCATION + name, name); } return names; }
398: */
399:
400: /**
401: * This method fixes MYFACES-208
402: */
403: private void feedClassloaderConfigurations() {
404: try {
405: Iterator it = ClassUtils.getResources(
406: FACES_CONFIG_RESOURCE, this );
407: while (it.hasNext()) {
408: URL url = (URL) it.next();
409: InputStream stream = openStreamWithoutCache(url);
410: String systemId = url.toExternalForm();
411: if (log.isInfoEnabled())
412: log.info("Reading config " + systemId);
413: getDispenser().feed(
414: getUnmarshaller().getFacesConfig(stream,
415: systemId));
416: stream.close();
417: }
418: } catch (Throwable e) {
419: throw new FacesException(e);
420: }
421: }
422:
423: private void feedContextSpecifiedConfig() throws IOException,
424: SAXException {
425: String configFiles = _externalContext
426: .getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
427: if (configFiles != null) {
428: StringTokenizer st = new StringTokenizer(configFiles, ",",
429: false);
430: while (st.hasMoreTokens()) {
431: String systemId = st.nextToken().trim();
432:
433: if (log.isWarnEnabled()
434: && DEFAULT_FACES_CONFIG.equals(systemId))
435: log
436: .warn(DEFAULT_FACES_CONFIG
437: + " has been specified in the "
438: + FacesServlet.CONFIG_FILES_ATTR
439: + " context parameter of "
440: + "the deployment descriptor. This should be removed, "
441: + "as it will be loaded twice. See JSF spec 1.2, 10.1.3");
442:
443: InputStream stream = _externalContext
444: .getResourceAsStream(systemId);
445: if (stream == null) {
446: log.error("Faces config resource " + systemId
447: + " not found");
448: continue;
449: }
450:
451: if (log.isInfoEnabled())
452: log.info("Reading config " + systemId);
453: getDispenser().feed(
454: getUnmarshaller().getFacesConfig(stream,
455: systemId));
456: stream.close();
457: }
458: }
459: }
460:
461: private void feedWebAppConfig() throws IOException, SAXException {
462: // web application config
463: InputStream stream = _externalContext
464: .getResourceAsStream(DEFAULT_FACES_CONFIG);
465: if (stream != null) {
466: if (log.isInfoEnabled())
467: log.info("Reading config /WEB-INF/faces-config.xml");
468: getDispenser().feed(
469: getUnmarshaller().getFacesConfig(stream,
470: DEFAULT_FACES_CONFIG));
471: stream.close();
472: }
473: }
474:
475: private void configureFactories() {
476: FacesConfigDispenser dispenser = getDispenser();
477: setFactories(FactoryFinder.APPLICATION_FACTORY, dispenser
478: .getApplicationFactoryIterator(),
479: DEFAULT_APPLICATION_FACTORY);
480: setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, dispenser
481: .getFacesContextFactoryIterator(),
482: DEFAULT_FACES_CONTEXT_FACTORY);
483: setFactories(FactoryFinder.LIFECYCLE_FACTORY, dispenser
484: .getLifecycleFactoryIterator(),
485: DEFAULT_LIFECYCLE_FACTORY);
486: setFactories(FactoryFinder.RENDER_KIT_FACTORY, dispenser
487: .getRenderKitFactoryIterator(),
488: DEFAULT_RENDER_KIT_FACTORY);
489: }
490:
491: private void setFactories(String factoryName, Iterator factories,
492: String defaultFactory) {
493: FactoryFinder.setFactory(factoryName, defaultFactory);
494: while (factories.hasNext()) {
495: String factory = (String) factories.next();
496: if (!factory.equals(defaultFactory))
497: FactoryFinder.setFactory(factoryName, factory);
498: }
499: }
500:
501: private void configureApplication() {
502: Application application = ((ApplicationFactory) FactoryFinder
503: .getFactory(FactoryFinder.APPLICATION_FACTORY))
504: .getApplication();
505: FacesConfigDispenser dispenser = getDispenser();
506: application
507: .setActionListener((ActionListener) getApplicationObject(
508: ActionListener.class, dispenser
509: .getActionListenerIterator(), null));
510:
511: if (dispenser.getDefaultLocale() != null) {
512: application.setDefaultLocale(LocaleUtils.toLocale(dispenser
513: .getDefaultLocale()));
514: }
515:
516: if (dispenser.getDefaultRenderKitId() != null) {
517: application.setDefaultRenderKitId(dispenser
518: .getDefaultRenderKitId());
519: }
520:
521: if (dispenser.getMessageBundle() != null) {
522: application.setMessageBundle(dispenser.getMessageBundle());
523: }
524:
525: application
526: .setNavigationHandler((NavigationHandler) getApplicationObject(
527: NavigationHandler.class, dispenser
528: .getNavigationHandlerIterator(),
529: application.getNavigationHandler()));
530:
531: application
532: .setStateManager((StateManager) getApplicationObject(
533: StateManager.class, dispenser
534: .getStateManagerIterator(), application
535: .getStateManager()));
536: List<Locale> locales = new ArrayList<Locale>();
537: for (Iterator it = dispenser.getSupportedLocalesIterator(); it
538: .hasNext();) {
539: locales.add(LocaleUtils.toLocale((String) it.next()));
540: }
541: application.setSupportedLocales(locales);
542:
543: application.setViewHandler((ViewHandler) getApplicationObject(
544: ViewHandler.class, dispenser.getViewHandlerIterator(),
545: application.getViewHandler()));
546:
547: for (Iterator it = dispenser.getComponentTypes(); it.hasNext();) {
548: String componentType = (String) it.next();
549: application.addComponent(componentType, dispenser
550: .getComponentClass(componentType));
551: }
552:
553: for (Iterator it = dispenser.getConverterIds(); it.hasNext();) {
554: String converterId = (String) it.next();
555: application.addConverter(converterId, dispenser
556: .getConverterClassById(converterId));
557: }
558:
559: for (Iterator it = dispenser.getConverterClasses(); it
560: .hasNext();) {
561: String converterClass = (String) it.next();
562: try {
563: application.addConverter(ClassUtils
564: .simpleClassForName(converterClass), dispenser
565: .getConverterClassByClass(converterClass));
566: } catch (Exception ex) {
567: log.error("Converter could not be added. Reason:", ex);
568: }
569: }
570:
571: if (application instanceof ApplicationImpl) {
572: for (Iterator it = dispenser
573: .getConverterConfigurationByClassName(); it
574: .hasNext();) {
575: String converterClassName = (String) it.next();
576:
577: ((ApplicationImpl) application)
578: .addConverterConfiguration(
579: converterClassName,
580: dispenser
581: .getConverterConfiguration(converterClassName));
582: }
583: }
584:
585: for (Iterator it = dispenser.getValidatorIds(); it.hasNext();) {
586: String validatorId = (String) it.next();
587: application.addValidator(validatorId, dispenser
588: .getValidatorClass(validatorId));
589: }
590:
591: RuntimeConfig runtimeConfig = getRuntimeConfig();
592:
593: runtimeConfig
594: .setPropertyResolverChainHead((PropertyResolver) getApplicationObject(
595: PropertyResolver.class, dispenser
596: .getPropertyResolverIterator(),
597: new DefaultPropertyResolver()));
598:
599: runtimeConfig
600: .setVariableResolverChainHead((VariableResolver) getApplicationObject(
601: VariableResolver.class, dispenser
602: .getVariableResolverIterator(),
603: new VariableResolverImpl()));
604: }
605:
606: /**
607: * @return
608: */
609: protected RuntimeConfig getRuntimeConfig() {
610: if (_runtimeConfig == null) {
611: _runtimeConfig = RuntimeConfig
612: .getCurrentInstance(_externalContext);
613: }
614: return _runtimeConfig;
615: }
616:
617: public void setRuntimeConfig(RuntimeConfig runtimeConfig) {
618: _runtimeConfig = runtimeConfig;
619: }
620:
621: private Object getApplicationObject(Class interfaceClass,
622: Iterator classNamesIterator, Object defaultObject) {
623: Object current = defaultObject;
624:
625: while (classNamesIterator.hasNext()) {
626: String implClassName = (String) classNamesIterator.next();
627: Class implClass = ClassUtils
628: .simpleClassForName(implClassName);
629:
630: // check, if class is of expected interface type
631: if (!interfaceClass.isAssignableFrom(implClass)) {
632: throw new IllegalArgumentException("Class "
633: + implClassName + " is no "
634: + interfaceClass.getName());
635: }
636:
637: if (current == null) {
638: // nothing to decorate
639: current = ClassUtils.newInstance(implClass);
640: } else {
641: // let's check if class supports the decorator pattern
642: try {
643: Constructor delegationConstructor = implClass
644: .getConstructor(new Class[] { interfaceClass });
645: // impl class supports decorator pattern,
646: try {
647: // create new decorator wrapping current
648: current = delegationConstructor
649: .newInstance(new Object[] { current });
650: } catch (InstantiationException e) {
651: log.error(e.getMessage(), e);
652: throw new FacesException(e);
653: } catch (IllegalAccessException e) {
654: log.error(e.getMessage(), e);
655: throw new FacesException(e);
656: } catch (InvocationTargetException e) {
657: log.error(e.getMessage(), e);
658: throw new FacesException(e);
659: }
660: } catch (NoSuchMethodException e) {
661: // no decorator pattern support
662: current = ClassUtils.newInstance(implClass);
663: }
664: }
665: }
666:
667: return current;
668: }
669:
670: private void configureRuntimeConfig() {
671: RuntimeConfig runtimeConfig = RuntimeConfig
672: .getCurrentInstance(_externalContext);
673:
674: FacesConfigDispenser dispenser = getDispenser();
675: for (Iterator iterator = dispenser.getManagedBeans(); iterator
676: .hasNext();) {
677: ManagedBean bean = (ManagedBean) iterator.next();
678:
679: if (log.isWarnEnabled()
680: && runtimeConfig.getManagedBean(bean
681: .getManagedBeanName()) != null)
682: log.warn("More than one managed bean w/ the name of '"
683: + bean.getManagedBeanName()
684: + "' - only keeping the last ");
685:
686: runtimeConfig.addManagedBean(bean.getManagedBeanName(),
687: bean);
688:
689: }
690:
691: for (Iterator iterator = dispenser.getNavigationRules(); iterator
692: .hasNext();) {
693: NavigationRule rule = (NavigationRule) iterator.next();
694: runtimeConfig.addNavigationRule(rule);
695:
696: }
697:
698: for (Iterator<ResourceBundle> iter = dispenser
699: .getResourceBundles(); iter.hasNext();) {
700: runtimeConfig.addResourceBundle(iter.next());
701: }
702:
703: for (Iterator<String> iter = dispenser.getElResolvers(); iter
704: .hasNext();) {
705: runtimeConfig
706: .addFacesConfigElResolver((ELResolver) ClassUtils
707: .newInstance(iter.next(), ELResolver.class));
708: }
709: }
710:
711: private void configureRenderKits() {
712: RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
713: .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
714:
715: FacesConfigDispenser dispenser = getDispenser();
716: for (Iterator iterator = dispenser.getRenderKitIds(); iterator
717: .hasNext();) {
718: String renderKitId = (String) iterator.next();
719: String renderKitClass = dispenser
720: .getRenderKitClass(renderKitId);
721:
722: if (renderKitClass == null) {
723: renderKitClass = DEFAULT_RENDER_KIT_CLASS;
724: }
725:
726: RenderKit renderKit = (RenderKit) ClassUtils
727: .newInstance(renderKitClass);
728:
729: for (Iterator renderers = dispenser
730: .getRenderers(renderKitId); renderers.hasNext();) {
731: Renderer element = (Renderer) renderers.next();
732: javax.faces.render.Renderer renderer;
733: try {
734: renderer = (javax.faces.render.Renderer) ClassUtils
735: .newInstance(element.getRendererClass());
736: } catch (Throwable e) {
737: // ignore the failure so that the render kit is configured
738: log.error("failed to configure class "
739: + element.getRendererClass(), e);
740: continue;
741: }
742:
743: renderKit.addRenderer(element.getComponentFamily(),
744: element.getRendererType(), renderer);
745: }
746:
747: renderKitFactory.addRenderKit(renderKitId, renderKit);
748: }
749: }
750:
751: private void configureLifecycle() {
752: // create the lifecycle used by the app
753: LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
754: .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
755: Lifecycle lifecycle = lifecycleFactory
756: .getLifecycle(getLifecycleId());
757:
758: // add phase listeners
759: for (Iterator iterator = getDispenser()
760: .getLifecyclePhaseListeners(); iterator.hasNext();) {
761: String listenerClassName = (String) iterator.next();
762: try {
763: lifecycle.addPhaseListener((PhaseListener) ClassUtils
764: .newInstance(listenerClassName));
765: } catch (ClassCastException e) {
766: log.error("Class " + listenerClassName
767: + " does not implement PhaseListener");
768: }
769: }
770: }
771:
772: private String getLifecycleId() {
773: String id = _externalContext
774: .getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
775:
776: if (id != null) {
777: return id;
778: }
779:
780: return LifecycleFactory.DEFAULT_LIFECYCLE;
781: }
782:
783: public static class VersionInfo {
784: private String packageName;
785: private List<JarInfo> jarInfos;
786:
787: public VersionInfo(String packageName) {
788:
789: this .packageName = packageName;
790: }
791:
792: public String getPackageName() {
793: return packageName;
794: }
795:
796: public void setPackageName(String packageName) {
797: this .packageName = packageName;
798: }
799:
800: public void addJarInfo(String path, String version) {
801: if (jarInfos == null) {
802: jarInfos = new ArrayList<JarInfo>();
803: }
804:
805: jarInfos.add(new JarInfo(path, version));
806: }
807:
808: public String getLastVersion() {
809: if (jarInfos == null)
810: return null;
811: if (jarInfos.size() == 0)
812: return null;
813:
814: return jarInfos.get(jarInfos.size() - 1).getVersion();
815: }
816:
817: /**
818: * Probably, the first encountered version will be used.
819: *
820: * @return probably used version
821: */
822: public String getUsedVersion() {
823:
824: if (jarInfos == null)
825: return null;
826: if (jarInfos.size() == 0)
827: return null;
828:
829: return jarInfos.get(0).getVersion();
830: }
831:
832: /**
833: * Probably, the first encountered version will be used.
834: *
835: * @return probably used classpath
836: */
837: public String getUsedVersionPath() {
838:
839: if (jarInfos == null)
840: return null;
841: if (jarInfos.size() == 0)
842: return null;
843:
844: return jarInfos.get(0).getUrl();
845:
846: }
847: }
848:
849: public static class JarInfo {
850: private String url;
851: private String version;
852:
853: public JarInfo(String url, String version) {
854: this .url = url;
855: this .version = version;
856: }
857:
858: public String getVersion() {
859: return version;
860: }
861:
862: public void setVersion(String version) {
863: this .version = version;
864: }
865:
866: public String getUrl() {
867: return url;
868: }
869:
870: public void setUrl(String url) {
871: this .url = url;
872: }
873: }
874:
875: private void handleSerialFactory() {
876:
877: String serialProvider = _externalContext
878: .getInitParameter(StateUtils.SERIAL_FACTORY);
879: SerialFactory serialFactory = null;
880:
881: if (serialProvider == null) {
882: serialFactory = new DefaultSerialFactory();
883: } else {
884: try {
885: serialFactory = (SerialFactory) ClassUtils
886: .newInstance(serialProvider);
887:
888: } catch (ClassCastException e) {
889: log.error("Make sure '" + serialProvider
890: + "' implements the correct interface", e);
891: } catch (Exception e) {
892: log.error(e);
893: } finally {
894: if (serialFactory == null) {
895: serialFactory = new DefaultSerialFactory();
896: log.error("Using default serialization provider");
897: }
898: }
899:
900: }
901:
902: log
903: .info("Serialization provider : "
904: + serialFactory.getClass());
905: _externalContext.getApplicationMap().put(
906: StateUtils.SERIAL_FACTORY, serialFactory);
907:
908: }
909:
910: }
|