| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.myfaces.config; |
| |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| import java.util.function.Predicate; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| import javax.el.ELResolver; |
| import javax.faces.FacesException; |
| import javax.faces.FacesWrapper; |
| import javax.faces.FactoryFinder; |
| import javax.faces.application.Application; |
| import javax.faces.application.ApplicationFactory; |
| import javax.faces.application.ConfigurableNavigationHandler; |
| import javax.faces.application.NavigationHandler; |
| import javax.faces.application.ProjectStage; |
| import javax.faces.application.ResourceHandler; |
| import javax.faces.application.StateManager; |
| import javax.faces.application.ViewHandler; |
| import javax.faces.component.search.SearchExpressionHandler; |
| import javax.faces.component.search.SearchKeywordResolver; |
| import javax.faces.context.ExternalContext; |
| import javax.faces.context.FacesContext; |
| import javax.faces.event.ActionListener; |
| import javax.faces.event.ComponentSystemEvent; |
| import javax.faces.event.PhaseListener; |
| import javax.faces.event.PostConstructApplicationEvent; |
| import javax.faces.event.SystemEvent; |
| import javax.faces.flow.FlowHandler; |
| import javax.faces.flow.FlowHandlerFactory; |
| import javax.faces.lifecycle.ClientWindow; |
| import javax.faces.lifecycle.Lifecycle; |
| import javax.faces.lifecycle.LifecycleFactory; |
| import javax.faces.render.RenderKit; |
| import javax.faces.render.RenderKitFactory; |
| import javax.faces.validator.BeanValidator; |
| import javax.faces.webapp.FacesServlet; |
| |
| import org.apache.myfaces.application.ApplicationFactoryImpl; |
| import org.apache.myfaces.application.BackwardsCompatibleNavigationHandlerWrapper; |
| import org.apache.myfaces.component.visit.VisitContextFactoryImpl; |
| import org.apache.myfaces.config.element.Behavior; |
| import org.apache.myfaces.config.element.ClientBehaviorRenderer; |
| import org.apache.myfaces.config.element.ComponentTagDeclaration; |
| import org.apache.myfaces.config.element.ContractMapping; |
| import org.apache.myfaces.config.element.FaceletsProcessing; |
| import org.apache.myfaces.config.element.FacesConfig; |
| import org.apache.myfaces.config.element.FacesConfigData; |
| import org.apache.myfaces.config.element.FacesFlowCall; |
| import org.apache.myfaces.config.element.FacesFlowDefinition; |
| import org.apache.myfaces.config.element.FacesFlowMethodCall; |
| import org.apache.myfaces.config.element.FacesFlowMethodParameter; |
| import org.apache.myfaces.config.element.FacesFlowParameter; |
| import org.apache.myfaces.config.element.FacesFlowReturn; |
| import org.apache.myfaces.config.element.FacesFlowSwitch; |
| import org.apache.myfaces.config.element.FacesFlowView; |
| import org.apache.myfaces.config.element.NamedEvent; |
| import org.apache.myfaces.config.element.NavigationCase; |
| import org.apache.myfaces.config.element.NavigationRule; |
| import org.apache.myfaces.config.element.Renderer; |
| import org.apache.myfaces.config.element.ResourceBundle; |
| import org.apache.myfaces.config.element.SystemEventListener; |
| import org.apache.myfaces.config.impl.FacesConfigDispenserImpl; |
| import org.apache.myfaces.context.ExceptionHandlerFactoryImpl; |
| import org.apache.myfaces.context.ExternalContextFactoryImpl; |
| import org.apache.myfaces.context.FacesContextFactoryImpl; |
| import org.apache.myfaces.context.PartialViewContextFactoryImpl; |
| import org.apache.myfaces.context.servlet.ServletFlashFactoryImpl; |
| import org.apache.myfaces.lifecycle.clientwindow.ClientWindowFactoryImpl; |
| import org.apache.myfaces.flow.FlowCallNodeImpl; |
| import org.apache.myfaces.flow.FlowHandlerFactoryImpl; |
| import org.apache.myfaces.flow.FlowImpl; |
| import org.apache.myfaces.flow.MethodCallNodeImpl; |
| import org.apache.myfaces.flow.ParameterImpl; |
| import org.apache.myfaces.flow.ReturnNodeImpl; |
| import org.apache.myfaces.flow.SwitchCaseImpl; |
| import org.apache.myfaces.flow.SwitchNodeImpl; |
| import org.apache.myfaces.flow.ViewNodeImpl; |
| import org.apache.myfaces.flow.impl.AnnotatedFlowConfigurator; |
| import org.apache.myfaces.lifecycle.LifecycleFactoryImpl; |
| import org.apache.myfaces.renderkit.RenderKitFactoryImpl; |
| import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl; |
| import org.apache.myfaces.resource.ResourceLoaderUtils; |
| import org.apache.myfaces.util.lang.ClassUtils; |
| import org.apache.myfaces.util.LocaleUtils; |
| import org.apache.myfaces.application.viewstate.StateUtils; |
| import org.apache.myfaces.util.lang.StringUtils; |
| import org.apache.myfaces.util.WebConfigParamUtils; |
| import org.apache.myfaces.cdi.util.BeanEntry; |
| import org.apache.myfaces.component.search.SearchExpressionContextFactoryImpl; |
| import org.apache.myfaces.config.element.FaceletsTemplateMapping; |
| import org.apache.myfaces.config.element.ViewPoolMapping; |
| import org.apache.myfaces.config.element.facelets.FaceletTagLibrary; |
| import org.apache.myfaces.config.impl.FacesConfigUnmarshallerImpl; |
| import org.apache.myfaces.lifecycle.LifecycleImpl; |
| import org.apache.myfaces.renderkit.LazyRenderKit; |
| import org.apache.myfaces.spi.impl.DefaultSerialFactory; |
| import org.apache.myfaces.spi.SerialFactory; |
| import org.apache.myfaces.spi.FacesConfigurationMerger; |
| import org.apache.myfaces.spi.FacesConfigurationMergerFactory; |
| import org.apache.myfaces.spi.InjectionProvider; |
| import org.apache.myfaces.spi.InjectionProviderException; |
| import org.apache.myfaces.spi.InjectionProviderFactory; |
| import org.apache.myfaces.spi.ResourceLibraryContractsProvider; |
| import org.apache.myfaces.spi.ResourceLibraryContractsProviderFactory; |
| import org.apache.myfaces.util.ExternalSpecifications; |
| import org.apache.myfaces.util.NavigationUtils; |
| import org.apache.myfaces.view.ViewDeclarationLanguageFactoryImpl; |
| import org.apache.myfaces.view.facelets.el.ELText; |
| import org.apache.myfaces.view.facelets.impl.FaceletCacheFactoryImpl; |
| import org.apache.myfaces.view.facelets.tag.jsf.TagHandlerDelegateFactoryImpl; |
| import org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener; |
| import org.apache.myfaces.webapp.AbstractFacesInitializer; |
| |
| /** |
| * Configures everything for a given context. The FacesConfigurator is independent of the concrete implementations that |
| * lie behind FacesConfigUnmarshaller and FacesConfigDispenser. |
| * |
| * @author Manfred Geiler (latest modification by $Author$) |
| * @version $Revision$ $Date$ |
| */ |
| @SuppressWarnings("deprecation") |
| public class FacesConfigurator |
| { |
| private final Class<?>[] NO_PARAMETER_TYPES = new Class[]{}; |
| private final Object[] NO_PARAMETERS = new Object[]{}; |
| |
| private static final Logger log = Logger.getLogger(FacesConfigurator.class.getName()); |
| |
| private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class.getName(); |
| private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class.getName(); |
| private static final String DEFAULT_EXTERNAL_CONTEXT_FACTORY = ExternalContextFactoryImpl.class.getName(); |
| private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class.getName(); |
| private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class.getName(); |
| private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class.getName(); |
| private static final String DEFAULT_PARTIAL_VIEW_CONTEXT_FACTORY = PartialViewContextFactoryImpl.class.getName(); |
| private static final String DEFAULT_VISIT_CONTEXT_FACTORY = VisitContextFactoryImpl.class.getName(); |
| private static final String DEFAULT_VIEW_DECLARATION_LANGUAGE_FACTORY |
| = ViewDeclarationLanguageFactoryImpl.class.getName(); |
| private static final String DEFAULT_EXCEPTION_HANDLER_FACTORY = ExceptionHandlerFactoryImpl.class.getName(); |
| private static final String DEFAULT_TAG_HANDLER_DELEGATE_FACTORY = TagHandlerDelegateFactoryImpl.class.getName(); |
| private static final String DEFAULT_FACELET_CACHE_FACTORY = FaceletCacheFactoryImpl.class.getName(); |
| private static final String DEFAULT_FLASH_FACTORY = ServletFlashFactoryImpl.class.getName(); |
| private static final String DEFAULT_CLIENT_WINDOW_FACTORY = ClientWindowFactoryImpl.class.getName(); |
| private static final String DEFAULT_FLOW_FACTORY = FlowHandlerFactoryImpl.class.getName(); |
| private static final String DEFAULT_SEARCH_EXPRESSION_CONTEXT_FACTORY = |
| SearchExpressionContextFactoryImpl.class.getName(); |
| private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml"; |
| |
| /** |
| * Set this attribute if the current configuration requires enable window mode |
| */ |
| public static final String ENABLE_DEFAULT_WINDOW_MODE = |
| "org.apache.myfaces.ENABLE_DEFAULT_WINDOW_MODE"; |
| |
| private final ExternalContext _externalContext; |
| private FacesContext _facesContext; |
| private FacesConfigUnmarshaller<? extends FacesConfig> _unmarshaller; |
| private FacesConfigData _dispenser; |
| |
| private RuntimeConfig _runtimeConfig; |
| private MyfacesConfig _myfacesConfig; |
| |
| private Application _application; |
| |
| private InjectionProvider _injectionProvider; |
| |
| private static long lastUpdate; |
| |
| public FacesConfigurator(ExternalContext externalContext) |
| { |
| if (externalContext == null) |
| { |
| throw new IllegalArgumentException("external context must not be null"); |
| } |
| _externalContext = externalContext; |
| |
| // In dev mode a new Faces Configurator is created for every request so only |
| // create a new bean storage list if we don't already have one which will be |
| // the case first time through during init. |
| if (_externalContext.getApplicationMap().get(AbstractFacesInitializer.INJECTED_BEAN_STORAGE_KEY) == null) |
| { |
| _externalContext.getApplicationMap().put(AbstractFacesInitializer.INJECTED_BEAN_STORAGE_KEY, |
| new CopyOnWriteArrayList()); |
| } |
| |
| _myfacesConfig = MyfacesConfig.getCurrentInstance(_externalContext); |
| _runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext); |
| } |
| |
| /** |
| * @param unmarshaller |
| * the unmarshaller to set |
| */ |
| public void setUnmarshaller(FacesConfigUnmarshaller<? extends FacesConfig> unmarshaller) |
| { |
| _unmarshaller = unmarshaller; |
| } |
| |
| /** |
| * @return the unmarshaller |
| */ |
| protected FacesConfigUnmarshaller<? extends FacesConfig> getUnmarshaller() |
| { |
| if (_unmarshaller == null) |
| { |
| _unmarshaller = new FacesConfigUnmarshallerImpl(_externalContext); |
| } |
| |
| return _unmarshaller; |
| } |
| |
| /** |
| * @param dispenser |
| * the dispenser to set |
| */ |
| public void setDispenser(FacesConfigData dispenser) |
| { |
| _dispenser = dispenser; |
| } |
| |
| /** |
| * @return the dispenser |
| */ |
| protected FacesConfigData getDispenser() |
| { |
| if (_dispenser == null) |
| { |
| _dispenser = new FacesConfigDispenserImpl(); |
| } |
| |
| return _dispenser; |
| } |
| |
| private long getResourceLastModified(String resource) |
| { |
| try |
| { |
| URL url = _externalContext.getResource(resource); |
| if (url != null) |
| { |
| return ResourceLoaderUtils.getResourceLastModified(url); |
| } |
| } |
| catch (IOException e) |
| { |
| log.log(Level.SEVERE, "Could not read resource " + resource, e); |
| } |
| return 0; |
| } |
| |
| private long getLastModifiedTime() |
| { |
| long lastModified = 0; |
| long resModified; |
| |
| resModified = getResourceLastModified(DEFAULT_FACES_CONFIG); |
| if (resModified > lastModified) |
| { |
| lastModified = resModified; |
| } |
| |
| // perf: method getConfigFilesList() creates a ArrayList |
| List<String> configFilesList = getConfigFilesList(); |
| for (int i = 0, size = configFilesList.size(); i < size; i++) |
| { |
| String systemId = configFilesList.get(i); |
| resModified = getResourceLastModified(systemId); |
| if (resModified > lastModified) |
| { |
| lastModified = resModified; |
| } |
| } |
| |
| // get last modified from .taglib.xml |
| String faceletsFiles = WebConfigParamUtils.getStringInitParameter(_externalContext, |
| ViewHandler.FACELETS_LIBRARIES_PARAM_NAME); |
| if (faceletsFiles != null) |
| { |
| String[] faceletFilesList = StringUtils.trim(faceletsFiles.split(";")); |
| for (int i = 0, size = faceletFilesList.length; i < size; i++) |
| { |
| String systemId = faceletFilesList[i]; |
| resModified = getResourceLastModified(systemId); |
| if (resModified > lastModified) |
| { |
| lastModified = resModified; |
| } |
| } |
| } |
| |
| // get last modified from -flow.xml |
| Set<String> directoryPaths = _externalContext.getResourcePaths("/"); |
| if (directoryPaths != null) |
| { |
| List<String> contextSpecifiedList = configFilesList; |
| for (String dirPath : directoryPaths) |
| { |
| if (dirPath.equals("/WEB-INF/")) |
| { |
| // Look on /WEB-INF/<flow-Name>/<flowName>-flow.xml |
| Set<String> webDirectoryPaths = _externalContext.getResourcePaths(dirPath); |
| for (String webDirPath : webDirectoryPaths) |
| { |
| if (webDirPath.endsWith("/") && |
| !webDirPath.equals("/WEB-INF/classes/")) |
| { |
| String flowName = webDirPath.substring(9, webDirPath.length() - 1); |
| String filePath = webDirPath+flowName+"-flow.xml"; |
| if (!contextSpecifiedList.contains(filePath)) |
| { |
| resModified = getResourceLastModified(filePath); |
| if (resModified > lastModified) |
| { |
| lastModified = resModified; |
| } |
| } |
| } |
| } |
| } |
| else if (!dirPath.startsWith("/META-INF") && dirPath.endsWith("/")) |
| { |
| // Look on /<flowName>/<flowName>-flow.xml |
| String flowName = dirPath.substring(1, dirPath.length() - 1); |
| String filePath = dirPath+flowName+"-flow.xml"; |
| if (!contextSpecifiedList.contains(filePath)) |
| { |
| resModified = getResourceLastModified(filePath); |
| if (resModified > lastModified) |
| { |
| lastModified = resModified; |
| } |
| } |
| } |
| } |
| } |
| |
| return lastModified; |
| } |
| |
| public void update() |
| { |
| long refreshPeriod = (MyfacesConfig.getCurrentInstance(_externalContext).getConfigRefreshPeriod()) * 1000; |
| if (refreshPeriod > 0) |
| { |
| long ttl = lastUpdate + refreshPeriod; |
| if ((System.currentTimeMillis() > ttl) && (getLastModifiedTime() > ttl)) |
| { |
| boolean purged = false; |
| try |
| { |
| purged = purgeConfiguration(); |
| } |
| catch (NoSuchMethodException e) |
| { |
| log.severe("Configuration objects do not support clean-up. Update aborted"); |
| |
| // We still want to update the timestamp to avoid running purge on every subsequent |
| // request after this one. |
| // |
| lastUpdate = System.currentTimeMillis(); |
| |
| return; |
| } |
| catch (IllegalAccessException | InvocationTargetException e) |
| { |
| log.severe("Error during configuration clean-up" + e.getMessage()); |
| } |
| if (purged) |
| { |
| configure(); |
| |
| // JSF 2.0 Publish PostConstructApplicationEvent after all configuration resources |
| // has been parsed and processed |
| FacesContext facesContext = getFacesContext(); |
| Application application = facesContext.getApplication(); |
| |
| application.publishEvent(facesContext, PostConstructApplicationEvent.class, |
| Application.class, application); |
| } |
| } |
| } |
| } |
| |
| private boolean purgeConfiguration() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException |
| { |
| |
| Method appFactoryPurgeMethod; |
| Method renderKitPurgeMethod; |
| Method lifecyclePurgeMethod; |
| Method facesContextPurgeMethod; |
| |
| // Check that we have access to all of the necessary purge methods before purging anything |
| // |
| ApplicationFactory applicationFactory |
| = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); |
| appFactoryPurgeMethod = getPurgeMethod(applicationFactory, "purgeApplication", NO_PARAMETER_TYPES); |
| |
| RenderKitFactory renderKitFactory |
| = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); |
| renderKitPurgeMethod = getPurgeMethod(renderKitFactory, "purgeRenderKit", NO_PARAMETER_TYPES); |
| |
| LifecycleFactory lifecycleFactory |
| = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); |
| lifecyclePurgeMethod = getPurgeMethod(lifecycleFactory, "purgeLifecycle", NO_PARAMETER_TYPES); |
| |
| FacesContext facesContext = getFacesContext(); |
| facesContextPurgeMethod = getPurgeMethod(facesContext, "purgeFacesContext", NO_PARAMETER_TYPES); |
| |
| // If there was no exception so far, now we can purge |
| // |
| if (appFactoryPurgeMethod != null && renderKitPurgeMethod != null && lifecyclePurgeMethod != null && |
| facesContextPurgeMethod != null) |
| { |
| appFactoryPurgeMethod.invoke(applicationFactory, NO_PARAMETERS); |
| renderKitPurgeMethod.invoke(renderKitFactory, NO_PARAMETERS); |
| RuntimeConfig.getCurrentInstance(_externalContext).purge(); |
| lifecyclePurgeMethod.invoke(lifecycleFactory, NO_PARAMETERS); |
| facesContextPurgeMethod.invoke(facesContext, NO_PARAMETERS); |
| |
| // factories and serial factory need not be purged... |
| |
| // Remove first request processed so we can initialize it again |
| _externalContext.getApplicationMap().remove(LifecycleImpl.FIRST_REQUEST_PROCESSED_PARAM); |
| return true; |
| } |
| return false; |
| } |
| |
| private Method getPurgeMethod(Object instance, String methodName, Class<?>[] parameters) |
| { |
| while (instance != null) |
| { |
| Method purgeMethod = null; |
| try |
| { |
| purgeMethod = instance.getClass().getMethod(methodName, parameters); |
| } |
| catch (NoSuchMethodException e) |
| { |
| // No op, it is expected to found this case, so in that case |
| // look for the parent to do the purge |
| } |
| if (purgeMethod != null) |
| { |
| return purgeMethod; |
| } |
| if (instance instanceof FacesWrapper) |
| { |
| instance = ((FacesWrapper)instance).getWrapped(); |
| } |
| } |
| return null; |
| } |
| |
| public void configure() throws FacesException |
| { |
| // get FacesConfigurationMerger SPI implementation |
| FacesConfigurationMerger facesConfigurationMerger = FacesConfigurationMergerFactory |
| .getFacesConfigurationMergerFactory(_externalContext).getFacesConfigurationMerger(_externalContext); |
| |
| // get all faces-config data, merge it and set it as Dispenser |
| setDispenser(facesConfigurationMerger.getFacesConfigData(_externalContext)); |
| |
| configureFactories(); |
| configureApplication(); |
| configureRenderKits(); |
| |
| configureRuntimeConfig(); |
| configureLifecycle(); |
| handleSerialFactory(); |
| configureFlowHandler(); |
| |
| configureProtectedViews(); |
| |
| // record the time of update |
| lastUpdate = System.currentTimeMillis(); |
| } |
| |
| private List<String> getConfigFilesList() |
| { |
| String configFiles = _externalContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR); |
| List<String> configFilesList = new ArrayList<>(); |
| if (configFiles != null) |
| { |
| StringTokenizer st = new StringTokenizer(configFiles, ",", false); |
| while (st.hasMoreTokens()) |
| { |
| String systemId = st.nextToken().trim(); |
| |
| if (DEFAULT_FACES_CONFIG.equals(systemId)) |
| { |
| if (log.isLoggable(Level.WARNING)) |
| { |
| log.warning(DEFAULT_FACES_CONFIG + " has been specified in the " |
| + FacesServlet.CONFIG_FILES_ATTR |
| + " context parameter of " |
| + "the deployment descriptor. This will automatically be removed, " |
| + "if we wouldn't do this, it would be loaded twice. See JSF spec 1.1, 10.3.2"); |
| } |
| } |
| else |
| { |
| configFilesList.add(systemId); |
| } |
| } |
| } |
| return configFilesList; |
| } |
| |
| private void configureFactories() |
| { |
| FacesConfigData dispenser = getDispenser(); |
| setFactories(FactoryFinder.APPLICATION_FACTORY, dispenser.getApplicationFactoryIterator(), |
| DEFAULT_APPLICATION_FACTORY); |
| setFactories(FactoryFinder.EXCEPTION_HANDLER_FACTORY, dispenser.getExceptionHandlerFactoryIterator(), |
| DEFAULT_EXCEPTION_HANDLER_FACTORY); |
| setFactories(FactoryFinder.EXTERNAL_CONTEXT_FACTORY, dispenser.getExternalContextFactoryIterator(), |
| DEFAULT_EXTERNAL_CONTEXT_FACTORY); |
| setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, dispenser.getFacesContextFactoryIterator(), |
| DEFAULT_FACES_CONTEXT_FACTORY); |
| setFactories(FactoryFinder.LIFECYCLE_FACTORY, dispenser.getLifecycleFactoryIterator(), |
| DEFAULT_LIFECYCLE_FACTORY); |
| setFactories(FactoryFinder.RENDER_KIT_FACTORY, dispenser.getRenderKitFactoryIterator(), |
| DEFAULT_RENDER_KIT_FACTORY); |
| setFactories(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY, dispenser.getTagHandlerDelegateFactoryIterator(), |
| DEFAULT_TAG_HANDLER_DELEGATE_FACTORY); |
| setFactories(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY, dispenser.getPartialViewContextFactoryIterator(), |
| DEFAULT_PARTIAL_VIEW_CONTEXT_FACTORY); |
| setFactories(FactoryFinder.VISIT_CONTEXT_FACTORY, dispenser.getVisitContextFactoryIterator(), |
| DEFAULT_VISIT_CONTEXT_FACTORY); |
| setFactories(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY, |
| dispenser.getViewDeclarationLanguageFactoryIterator(), |
| DEFAULT_VIEW_DECLARATION_LANGUAGE_FACTORY); |
| setFactories(FactoryFinder.FACELET_CACHE_FACTORY, dispenser.getFaceletCacheFactoryIterator(), |
| DEFAULT_FACELET_CACHE_FACTORY); |
| setFactories(FactoryFinder.FLASH_FACTORY, dispenser.getFlashFactoryIterator(), |
| DEFAULT_FLASH_FACTORY); |
| setFactories(FactoryFinder.CLIENT_WINDOW_FACTORY, dispenser.getClientWindowFactoryIterator(), |
| DEFAULT_CLIENT_WINDOW_FACTORY); |
| setFactories(FactoryFinder.FLOW_HANDLER_FACTORY, dispenser.getFlowHandlerFactoryIterator(), |
| DEFAULT_FLOW_FACTORY); |
| setFactories(FactoryFinder.SEARCH_EXPRESSION_CONTEXT_FACTORY, |
| dispenser.getSearchExpressionContextFactoryIterator(), |
| DEFAULT_SEARCH_EXPRESSION_CONTEXT_FACTORY); |
| } |
| |
| private void setFactories(String factoryName, Collection<String> factories, String defaultFactory) |
| { |
| FactoryFinder.setFactory(factoryName, defaultFactory); |
| for (String factory : factories) |
| { |
| if (!factory.equals(defaultFactory)) |
| { |
| FactoryFinder.setFactory(factoryName, factory); |
| } |
| } |
| } |
| |
| private void configureApplication() |
| { |
| Application application = ((ApplicationFactory) |
| FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication(); |
| |
| FacesConfigData dispenser = getDispenser(); |
| ActionListener actionListener = ClassUtils.buildApplicationObject(ActionListener.class, |
| dispenser.getActionListenerIterator(), null); |
| _callInjectAndPostConstruct(actionListener); |
| application.setActionListener(actionListener); |
| |
| if (dispenser.getDefaultLocale() != null) |
| { |
| application.setDefaultLocale(LocaleUtils.toLocale(dispenser.getDefaultLocale())); |
| } |
| |
| if (dispenser.getDefaultRenderKitId() != null) |
| { |
| application.setDefaultRenderKitId(dispenser.getDefaultRenderKitId()); |
| } |
| |
| if (dispenser.getMessageBundle() != null) |
| { |
| application.setMessageBundle(dispenser.getMessageBundle()); |
| } |
| |
| // First build the object |
| NavigationHandler navigationHandler = ClassUtils.buildApplicationObject(NavigationHandler.class, |
| ConfigurableNavigationHandler.class, null, |
| dispenser.getNavigationHandlerIterator(), |
| application.getNavigationHandler()); |
| // Invoke inject and post construct |
| _callInjectAndPostConstruct(navigationHandler); |
| // Finally wrap the object with the BackwardsCompatibleNavigationHandlerWrapper if it is not assignable |
| // from ConfigurableNavigationHandler |
| navigationHandler = ClassUtils.wrapBackwardCompatible(NavigationHandler.class, |
| ConfigurableNavigationHandler.class, |
| BackwardsCompatibleNavigationHandlerWrapper.class, |
| application.getNavigationHandler(), |
| navigationHandler); |
| application.setNavigationHandler(navigationHandler); |
| |
| StateManager stateManager = ClassUtils.buildApplicationObject(StateManager.class, |
| dispenser.getStateManagerIterator(), |
| application.getStateManager()); |
| _callInjectAndPostConstruct(stateManager); |
| application.setStateManager(stateManager); |
| |
| ResourceHandler resourceHandler = ClassUtils.buildApplicationObject(ResourceHandler.class, |
| dispenser.getResourceHandlerIterator(), |
| application.getResourceHandler()); |
| _callInjectAndPostConstruct(resourceHandler); |
| application.setResourceHandler(resourceHandler); |
| |
| List<Locale> locales = new ArrayList<>(); |
| for (String locale : dispenser.getSupportedLocalesIterator()) |
| { |
| locales.add(LocaleUtils.toLocale(locale)); |
| } |
| |
| application.setSupportedLocales(locales); |
| |
| application.setViewHandler(ClassUtils.buildApplicationObject(ViewHandler.class, |
| dispenser.getViewHandlerIterator(), |
| application.getViewHandler())); |
| |
| application.setSearchExpressionHandler(ClassUtils.buildApplicationObject(SearchExpressionHandler.class, |
| dispenser.getSearchExpressionHandlerIterator(), |
| application.getSearchExpressionHandler())); |
| |
| for (SystemEventListener systemEventListener : dispenser.getSystemEventListeners()) |
| { |
| try |
| { |
| //note here used to be an instantiation to deal with the explicit source type in the registration, |
| // that cannot work because all system events need to have the source being passed in the constructor |
| //instead we now rely on the standard system event types and map them to their appropriate |
| // constructor types |
| Class eventClass = ClassUtils.classForName((systemEventListener.getSystemEventClass() != null) |
| ? systemEventListener.getSystemEventClass() |
| : SystemEvent.class.getName()); |
| |
| javax.faces.event.SystemEventListener listener = (javax.faces.event.SystemEventListener) |
| ClassUtils.newInstance(systemEventListener.getSystemEventListenerClass()); |
| _callInjectAndPostConstruct(listener); |
| if (systemEventListener.getSourceClass() != null && systemEventListener.getSourceClass().length() > 0) |
| { |
| application.subscribeToEvent( |
| (Class<? extends SystemEvent>) eventClass, |
| ClassUtils.classForName(systemEventListener.getSourceClass()), |
| listener); |
| } |
| else |
| { |
| application.subscribeToEvent((Class<? extends SystemEvent>) eventClass, listener); |
| } |
| } |
| catch (ClassNotFoundException e) |
| { |
| log.log(Level.SEVERE, "System event listener could not be initialized, reason:", e); |
| } |
| } |
| |
| for (Map.Entry<String, String> entry : dispenser.getComponentClassesByType().entrySet()) |
| { |
| application.addComponent(entry.getKey(), entry.getValue()); |
| } |
| |
| for (Map.Entry<String, String> entry : dispenser.getConverterClassesById().entrySet()) |
| { |
| application.addConverter(entry.getKey(), entry.getValue()); |
| } |
| |
| for (Map.Entry<String, String> entry : dispenser.getConverterClassesByClass().entrySet()) |
| { |
| try |
| { |
| application.addConverter(ClassUtils.classForName(entry.getKey()), |
| entry.getValue()); |
| } |
| catch (Exception ex) |
| { |
| log.log(Level.SEVERE, "Converter could not be added. Reason:", ex); |
| } |
| } |
| |
| for (Map.Entry<String, String> entry : dispenser.getValidatorClassesById().entrySet()) |
| { |
| application.addValidator(entry.getKey(), entry.getValue()); |
| } |
| |
| // programmatically add the BeanValidator if the following requirements are met: |
| // - bean validation has not been disabled |
| // - bean validation is available in the classpath |
| String beanValidatorDisabled = _externalContext.getInitParameter( |
| BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME); |
| final boolean defaultBeanValidatorDisabled = (beanValidatorDisabled != null |
| && beanValidatorDisabled.toLowerCase().equals("true")); |
| boolean beanValidatorInstalledProgrammatically = false; |
| if (!defaultBeanValidatorDisabled |
| && ExternalSpecifications.isBeanValidationAvailable()) |
| { |
| // add the BeanValidator as default validator |
| application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID); |
| beanValidatorInstalledProgrammatically = true; |
| } |
| |
| // add the default-validators from the config files |
| for (String validatorId : dispenser.getDefaultValidatorIds()) |
| { |
| application.addDefaultValidatorId(validatorId); |
| } |
| |
| // do some checks if the BeanValidator was not installed as a |
| // default-validator programmatically, but via a config file. |
| if (!beanValidatorInstalledProgrammatically |
| && application.getDefaultValidatorInfo() |
| .containsKey(BeanValidator.VALIDATOR_ID)) |
| { |
| if (!ExternalSpecifications.isBeanValidationAvailable()) |
| { |
| // the BeanValidator was installed via a config file, |
| // but bean validation is not available |
| log.log(Level.WARNING, "The BeanValidator was installed as a " + |
| "default-validator from a faces-config file, but bean " + |
| "validation is not available on the classpath, " + |
| "thus it will not work!"); |
| } |
| else if (defaultBeanValidatorDisabled) |
| { |
| // the user disabled the default bean validator in web.xml, |
| // but a config file added it, which is ok with the spec |
| // (section 11.1.3: "though manual installation is still possible") |
| // --> inform the user about this scenario |
| log.log(Level.INFO, "The BeanValidator was disabled as a " + |
| "default-validator via the config parameter " + |
| BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME + |
| " in web.xml, but a faces-config file added it, " + |
| "thus it actually was installed as a default-validator."); |
| } |
| } |
| |
| for (Behavior behavior : dispenser.getBehaviors()) |
| { |
| application.addBehavior(behavior.getBehaviorId(), behavior.getBehaviorClass()); |
| } |
| |
| //JSF 2.2 set FlowHandler from factory. |
| FlowHandlerFactory flowHandlerFactory = (FlowHandlerFactory) |
| FactoryFinder.getFactory(FactoryFinder.FLOW_HANDLER_FACTORY); |
| FlowHandler flowHandler = flowHandlerFactory.createFlowHandler( |
| getFacesContext()); |
| application.setFlowHandler(flowHandler); |
| |
| for (ContractMapping mapping : dispenser.getResourceLibraryContractMappings()) |
| { |
| List<String> urlMappingsList = mapping.getUrlPatternList(); |
| for (String urlPattern: urlMappingsList) |
| { |
| for (String contract : mapping.getContractList()) |
| { |
| String[] contracts = StringUtils.trim(StringUtils.splitShortString(contract, ' ')); |
| _runtimeConfig.addContractMapping(urlPattern, contracts); |
| } |
| } |
| } |
| |
| this.setApplication(application); |
| } |
| |
| private void _callInjectAndPostConstruct(Object instance) |
| { |
| try |
| { |
| //invoke the injection over the inner one first |
| if (instance instanceof FacesWrapper) |
| { |
| Object innerInstance = ((FacesWrapper) instance).getWrapped(); |
| if (innerInstance != null) |
| { |
| _callInjectAndPostConstruct(innerInstance); |
| } |
| } |
| List<BeanEntry> injectedBeanStorage = (List<BeanEntry>) _externalContext.getApplicationMap().get( |
| AbstractFacesInitializer.INJECTED_BEAN_STORAGE_KEY); |
| |
| Object creationMetaData = getInjectionProvider().inject(instance); |
| |
| injectedBeanStorage.add(new BeanEntry(instance, creationMetaData)); |
| |
| getInjectionProvider().postConstruct(instance, creationMetaData); |
| } |
| catch (InjectionProviderException ex) |
| { |
| log.log(Level.INFO, "Exception on Injection or PostConstruct", ex); |
| } |
| } |
| |
| private void configureRuntimeConfig() |
| { |
| RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext); |
| FacesConfigData dispenser = getDispenser(); |
| List<String> knownNamespaces = new ArrayList<>(); |
| |
| for (ComponentTagDeclaration declaration : dispenser.getComponentTagDeclarations()) |
| { |
| runtimeConfig.addComponentTagDeclaration(declaration); |
| if (declaration.getNamespace() != null) |
| { |
| knownNamespaces.add(declaration.getNamespace()); |
| } |
| } |
| |
| for (NavigationRule rule : dispenser.getNavigationRules()) |
| { |
| runtimeConfig.addNavigationRule(rule); |
| } |
| |
| for (String converterClassName : dispenser.getConverterConfigurationByClassName()) |
| { |
| runtimeConfig.addConverterConfiguration(converterClassName, |
| _dispenser.getConverterConfiguration(converterClassName)); |
| } |
| |
| for (ResourceBundle bundle : dispenser.getResourceBundles()) |
| { |
| runtimeConfig.addResourceBundle(bundle); |
| } |
| |
| for (String className : dispenser.getElResolvers()) |
| { |
| ELResolver elResolver = (ELResolver) ClassUtils.newInstance(className, ELResolver.class); |
| _callInjectAndPostConstruct(elResolver); |
| runtimeConfig.addFacesConfigElResolver(elResolver); |
| } |
| |
| for (String className : dispenser.getSearchKeywordResolvers()) |
| { |
| SearchKeywordResolver searchKeywordResolver = (SearchKeywordResolver) ClassUtils.newInstance( |
| className, SearchKeywordResolver.class); |
| |
| runtimeConfig.addApplicationSearchExpressionResolver(searchKeywordResolver); |
| } |
| |
| runtimeConfig.setFacesVersion(dispenser.getFacesVersion()); |
| |
| runtimeConfig.setNamedEventManager(new NamedEventManager()); |
| |
| for (NamedEvent event : dispenser.getNamedEvents()) |
| { |
| try |
| { |
| Class<? extends ComponentSystemEvent> clazz = ClassUtils.classForName(event.getEventClass()); |
| runtimeConfig.getNamedEventManager().addNamedEvent(event.getShortName(), clazz); |
| } |
| catch (ClassNotFoundException e) |
| { |
| log.log(Level.SEVERE, "Named event could not be initialized, reason:", e); |
| } |
| } |
| |
| String elResolverComparatorClass = _myfacesConfig.getElResolverComparator(); |
| if (elResolverComparatorClass != null && !elResolverComparatorClass.isEmpty()) |
| { |
| try |
| { |
| Class<Comparator<ELResolver>> clazz = ClassUtils.classForName(elResolverComparatorClass); |
| Comparator<ELResolver> comparator = ClassUtils.newInstance(clazz); |
| runtimeConfig.setELResolverComparator(comparator); |
| } |
| catch (Exception e) |
| { |
| if (log.isLoggable(Level.SEVERE)) |
| { |
| log.log(Level.SEVERE, "Cannot instantiate EL Resolver Comparator " + elResolverComparatorClass |
| + " . Check " + MyfacesConfig.EL_RESOLVER_COMPARATOR + " web config param. " |
| + "Initialization continues with no comparator used.", e); |
| } |
| } |
| } |
| else |
| { |
| runtimeConfig.setELResolverComparator(null); |
| } |
| |
| String elResolverPredicateClass = _myfacesConfig.getElResolverPredicate(); |
| if (elResolverPredicateClass != null && !elResolverPredicateClass.isEmpty()) |
| { |
| try |
| { |
| Class<?> clazz = ClassUtils.classForName(elResolverPredicateClass); |
| Object elResolverPredicate = ClassUtils.newInstance(clazz); |
| if (elResolverPredicate instanceof Predicate) |
| { |
| runtimeConfig.setELResolverPredicate((Predicate) elResolverPredicate); |
| } |
| else |
| { |
| if (log.isLoggable(Level.SEVERE)) |
| { |
| log.log(Level.SEVERE, "EL Resolver Predicate " + elResolverPredicateClass |
| + " must implement " + Predicate.class.getName() |
| + " . Check " + MyfacesConfig.EL_RESOLVER_PREDICATE + " web config param. " |
| + "Initialization continues with no predicate used."); |
| } |
| } |
| } |
| catch (Exception e) |
| { |
| if (log.isLoggable(Level.SEVERE)) |
| { |
| log.log(Level.SEVERE, "Cannot instantiate EL Resolver Predicate " + elResolverPredicateClass |
| + " . Check " + MyfacesConfig.EL_RESOLVER_PREDICATE + " web config param. " |
| + "Initialization continues with no predicate used.", e); |
| } |
| } |
| } |
| else |
| { |
| runtimeConfig.setELResolverPredicate(null); |
| } |
| |
| for (FaceletsProcessing faceletsProcessing : dispenser.getFaceletsProcessing()) |
| { |
| runtimeConfig.addFaceletProcessingConfiguration(faceletsProcessing.getFileExtension(), faceletsProcessing); |
| } |
| |
| ResourceLibraryContractsProvider rlcp = ResourceLibraryContractsProviderFactory. |
| getFacesConfigResourceProviderFactory(_externalContext). |
| createResourceLibraryContractsProvider(_externalContext); |
| |
| try |
| { |
| // JSF 2.2 section 11.4.2.1 scan for available resource library contracts |
| // and store the result in a internal data structure, so it can be used |
| // later in ViewDeclarationLanguage.calculateResourceLibraryContracts( |
| // FacesContext context, String viewId) |
| runtimeConfig.setExternalContextResourceLibraryContracts( |
| rlcp.getExternalContextResourceLibraryContracts(_externalContext)); |
| runtimeConfig.setClassLoaderResourceLibraryContracts( |
| rlcp.getClassloaderResourceLibraryContracts(_externalContext)); |
| } |
| catch (Exception e) |
| { |
| if (log.isLoggable(Level.SEVERE)) |
| { |
| log.log(Level.SEVERE, |
| "An error was found when scanning for resource library contracts", e); |
| } |
| } |
| |
| |
| // JSF 2.2 section 11.4.2.1 check all contracts are loaded |
| if (log.isLoggable(Level.INFO)) |
| { |
| for (List<String> list : runtimeConfig.getContractMappings().values()) |
| { |
| for (String contract : list) |
| { |
| if (!runtimeConfig.getResourceLibraryContracts().contains(contract)) |
| { |
| log.log(Level.INFO, |
| "Resource Library Contract "+ contract + " was not found while scanning for " |
| + "available contracts."); |
| } |
| } |
| } |
| } |
| |
| // JSF 2.2 section 11.4.2.1 if no contractMappings set, all available contracts applies |
| // to all views. |
| if (runtimeConfig.getContractMappings().isEmpty()) |
| { |
| String[] contracts = runtimeConfig.getResourceLibraryContracts().toArray( |
| new String[runtimeConfig.getResourceLibraryContracts().size()]); |
| runtimeConfig.addContractMapping("*", contracts); |
| } |
| |
| for (String resourceResolver : dispenser.getResourceResolvers()) |
| { |
| runtimeConfig.addResourceResolver(resourceResolver); |
| } |
| |
| for (FaceletTagLibrary faceletTagLibrary : dispenser.getTagLibraries()) |
| { |
| runtimeConfig.addFaceletTagLibrary(faceletTagLibrary); |
| if (faceletTagLibrary.getNamespace() != null) |
| { |
| knownNamespaces.add(faceletTagLibrary.getNamespace()); |
| } |
| } |
| |
| // Add default namespaces to the known namespaces |
| knownNamespaces.add("http://xmlns.jcp.org/jsf/core"); |
| knownNamespaces.add("http://java.sun.com/jsf/core"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsf/html"); |
| knownNamespaces.add("http://java.sun.com/jsf/html"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsf/facelets"); |
| knownNamespaces.add("http://java.sun.com/jsf/facelets"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsp/jstl/core"); |
| knownNamespaces.add("http://java.sun.com/jsp/jstl/core"); |
| knownNamespaces.add("http://java.sun.com/jstl/core"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsp/jstl/functions"); |
| knownNamespaces.add("http://java.sun.com/jsp/jstl/functions"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsf/composite"); |
| knownNamespaces.add("http://java.sun.com/jsf/composite"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsf"); |
| knownNamespaces.add("http://java.sun.com/jsf"); |
| knownNamespaces.add("http://xmlns.jcp.org/jsf/passthrough"); |
| knownNamespaces.add("http://java.sun.com/jsf/passthrough"); |
| |
| Map<Integer, String> namespaceById = new HashMap<>(); |
| Map<String, Integer> idByNamespace = new HashMap<>(); |
| // Sort them to ensure the same id |
| Collections.sort(knownNamespaces); |
| for (int i = 0; i < knownNamespaces.size(); i++) |
| { |
| namespaceById.put(i, knownNamespaces.get(i)); |
| idByNamespace.put(knownNamespaces.get(i), i); |
| } |
| runtimeConfig.setNamespaceById(Collections.unmodifiableMap(namespaceById)); |
| runtimeConfig.setIdByNamespace(Collections.unmodifiableMap(idByNamespace)); |
| |
| for (ViewPoolMapping viewPoolMapping : dispenser.getViewPoolMappings()) |
| { |
| runtimeConfig.addViewPoolMapping(viewPoolMapping); |
| } |
| |
| for (FaceletsTemplateMapping faceletsTemplateMapping : dispenser.getFaceletsTemplateMappings()) |
| { |
| runtimeConfig.addFaceletsTemplateMapping(faceletsTemplateMapping); |
| } |
| } |
| |
| private void configureRenderKits() |
| { |
| RenderKitFactory renderKitFactory |
| = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); |
| |
| FacesConfigData dispenser = getDispenser(); |
| for (String renderKitId : dispenser.getRenderKitIds()) |
| { |
| Collection<String> renderKitClass = dispenser.getRenderKitClasses(renderKitId); |
| |
| if (renderKitClass.isEmpty()) |
| { |
| renderKitClass = new ArrayList<String>(1); |
| renderKitClass.add(DEFAULT_RENDER_KIT_CLASS); |
| } |
| |
| RenderKit renderKit = (RenderKit) ClassUtils.buildApplicationObject(RenderKit.class, renderKitClass, null); |
| // If the default html RenderKit instance is wrapped, the top level object will not implement |
| // LazyRenderKit and all renderers will be added using the standard form. |
| boolean lazyRenderKit = renderKit instanceof LazyRenderKit; |
| |
| for (Renderer element : dispenser.getRenderers(renderKitId)) |
| { |
| javax.faces.render.Renderer renderer; |
| |
| if (element.getRendererClass() != null) |
| { |
| if (lazyRenderKit) |
| { |
| // Add renderer using LazyRenderKit interface. This will have the effect of improve startup |
| // time avoiding load renderer classes that are not used. |
| ((LazyRenderKit) renderKit).addRenderer(element.getComponentFamily(), |
| element.getRendererType(), element.getRendererClass()); |
| } |
| else |
| { |
| // Use standard form |
| try |
| { |
| renderer = (javax.faces.render.Renderer) ClassUtils.newInstance( |
| element.getRendererClass()); |
| } |
| catch (Throwable e) |
| { |
| // ignore the failure so that the render kit is configured |
| log.log(Level.SEVERE, "failed to configure class " + element.getRendererClass(), e); |
| continue; |
| } |
| if (renderer != null) |
| { |
| renderKit.addRenderer(element.getComponentFamily(), element.getRendererType(), renderer); |
| } |
| else |
| { |
| log.log(Level.INFO, "Renderer instance cannot be created for "+ |
| element.getRendererClass()+ ", ignoring..." + |
| element.getRendererClass()); |
| } |
| } |
| } |
| else |
| { |
| log.log(Level.INFO, "Renderer element with no rendererClass found, ignoring..." + |
| element.getRendererClass()); |
| } |
| |
| } |
| |
| Collection<ClientBehaviorRenderer> clientBehaviorRenderers |
| = dispenser.getClientBehaviorRenderers(renderKitId); |
| |
| // Add in client behavior renderers. |
| |
| for (ClientBehaviorRenderer clientBehaviorRenderer : clientBehaviorRenderers) |
| { |
| try |
| { |
| javax.faces.render.ClientBehaviorRenderer behaviorRenderer |
| = (javax.faces.render.ClientBehaviorRenderer) |
| ClassUtils.newInstance(clientBehaviorRenderer.getRendererClass()); |
| |
| renderKit.addClientBehaviorRenderer(clientBehaviorRenderer.getRendererType(), behaviorRenderer); |
| } |
| |
| catch (Throwable e) |
| { |
| // Ignore. |
| |
| if (log.isLoggable(Level.SEVERE)) |
| { |
| log.log(Level.SEVERE, "failed to configure client behavior renderer class " + |
| clientBehaviorRenderer.getRendererClass(), e); |
| } |
| } |
| } |
| |
| renderKitFactory.addRenderKit(renderKitId, renderKit); |
| } |
| } |
| |
| private void configureLifecycle() |
| { |
| // create the lifecycle used by the app |
| LifecycleFactory lifecycleFactory |
| = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); |
| |
| for (Iterator<String> it = lifecycleFactory.getLifecycleIds(); it.hasNext();) |
| { |
| Lifecycle lifecycle = lifecycleFactory.getLifecycle(it.next()); |
| |
| // add phase listeners |
| for (String listenerClassName : getDispenser().getLifecyclePhaseListeners()) |
| { |
| try |
| { |
| PhaseListener listener = (PhaseListener) |
| ClassUtils.newInstance(listenerClassName, PhaseListener.class); |
| _callInjectAndPostConstruct(listener); |
| lifecycle.addPhaseListener(listener); |
| } |
| catch (ClassCastException e) |
| { |
| log.severe("Class " + listenerClassName + " does not implement PhaseListener"); |
| } |
| } |
| |
| // if ProjectStage is Development, install the DebugPhaseListener |
| FacesContext facesContext = getFacesContext(); |
| if (facesContext.isProjectStage(ProjectStage.Development) |
| && _myfacesConfig.isDebugPhaseListenerEnabled()) |
| { |
| lifecycle.addPhaseListener(new DebugPhaseListener()); |
| } |
| } |
| } |
| |
| |
| private void handleSerialFactory() |
| { |
| String serialProvider = _externalContext.getInitParameter(StateUtils.SERIAL_FACTORY); |
| SerialFactory serialFactory = null; |
| |
| if (serialProvider == null) |
| { |
| serialFactory = new DefaultSerialFactory(); |
| } |
| else |
| { |
| try |
| { |
| serialFactory = (SerialFactory) ClassUtils.newInstance(serialProvider); |
| |
| } |
| catch (ClassCastException e) |
| { |
| log.log(Level.SEVERE, "Make sure '" + serialProvider + "' implements the correct interface", e); |
| } |
| catch (Exception e) |
| { |
| log.log(Level.SEVERE, "", e); |
| } |
| finally |
| { |
| if (serialFactory == null) |
| { |
| serialFactory = new DefaultSerialFactory(); |
| log.severe("Using default serialization provider"); |
| } |
| } |
| |
| } |
| |
| log.fine("Serialization provider : " + serialFactory.getClass()); |
| _externalContext.getApplicationMap().put(StateUtils.SERIAL_FACTORY, serialFactory); |
| } |
| |
| private void configureFlowHandler() |
| { |
| FacesContext facesContext = getFacesContext(); |
| Application application = getApplication(); |
| |
| FacesConfigData dispenser = getDispenser(); |
| |
| if (!dispenser.getFacesFlowDefinitions().isEmpty()) |
| { |
| // Faces Flow require client window enabled to work. |
| FacesConfigurator.enableDefaultWindowMode(facesContext); |
| } |
| |
| for (FacesFlowDefinition flowDefinition : dispenser.getFacesFlowDefinitions()) |
| { |
| FlowImpl flow = new FlowImpl(); |
| |
| // TODO: configure flow object |
| flow.setId(flowDefinition.getId()); |
| flow.setDefiningDocumentId(flowDefinition.getDefiningDocumentId()); |
| |
| flow.setStartNodeId(flowDefinition.getStartNode()); |
| |
| if (StringUtils.isNotEmpty(flowDefinition.getInitializer())) |
| { |
| flow.setInitializer(application.getExpressionFactory().createMethodExpression( |
| facesContext.getELContext(), flowDefinition.getInitializer(), null, NO_PARAMETER_TYPES)); |
| } |
| if (StringUtils.isNotEmpty(flowDefinition.getFinalizer())) |
| { |
| flow.setFinalizer(application.getExpressionFactory().createMethodExpression( |
| facesContext.getELContext(), flowDefinition.getFinalizer(), null, NO_PARAMETER_TYPES)); |
| } |
| |
| for (FacesFlowCall call : flowDefinition.getFlowCallList()) |
| { |
| FlowCallNodeImpl node = new FlowCallNodeImpl(call.getId()); |
| if (call.getFlowReference() != null) |
| { |
| node.setCalledFlowId(call.getFlowReference().getFlowId()); |
| node.setCalledFlowDocumentId(call.getFlowReference().getFlowDocumentId()); |
| } |
| |
| for (FacesFlowParameter parameter : call.getOutboundParameterList()) |
| { |
| node.putOutboundParameter( parameter.getName(), |
| new ParameterImpl(parameter.getName(), |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), parameter.getValue(), Object.class)) ); |
| } |
| flow.putFlowCall(node.getId(), node); |
| } |
| |
| for (FacesFlowMethodCall methodCall : flowDefinition.getMethodCallList()) |
| { |
| MethodCallNodeImpl node = new MethodCallNodeImpl(methodCall.getId()); |
| if (StringUtils.isNotEmpty(methodCall.getMethod())) |
| { |
| node.setMethodExpression( |
| application.getExpressionFactory().createMethodExpression( |
| facesContext.getELContext(), methodCall.getMethod(), null, NO_PARAMETER_TYPES)); |
| } |
| if (StringUtils.isNotEmpty(methodCall.getDefaultOutcome())) |
| { |
| node.setOutcome( |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), methodCall.getDefaultOutcome(), Object.class)); |
| } |
| for (FacesFlowMethodParameter parameter : methodCall.getParameterList()) |
| { |
| node.addParameter( |
| new ParameterImpl(parameter.getClassName(), |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), parameter.getValue(), Object.class)) ); |
| } |
| flow.addMethodCall(node); |
| } |
| |
| for (FacesFlowParameter parameter : flowDefinition.getInboundParameterList()) |
| { |
| flow.putInboundParameter(parameter.getName(), |
| new ParameterImpl(parameter.getName(), |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), parameter.getValue(), Object.class)) ); |
| } |
| |
| for (NavigationRule rule : flowDefinition.getNavigationRuleList()) |
| { |
| flow.addNavigationCases(rule.getFromViewId(), NavigationUtils.convertNavigationCasesToAPI(rule)); |
| } |
| |
| for (FacesFlowSwitch flowSwitch : flowDefinition.getSwitchList()) |
| { |
| SwitchNodeImpl node = new SwitchNodeImpl(flowSwitch.getId()); |
| |
| if (flowSwitch.getDefaultOutcome() != null && |
| StringUtils.isNotEmpty(flowSwitch.getDefaultOutcome().getFromOutcome())) |
| { |
| if (ELText.isLiteral(flowSwitch.getDefaultOutcome().getFromOutcome())) |
| { |
| node.setDefaultOutcome(flowSwitch.getDefaultOutcome().getFromOutcome()); |
| } |
| else |
| { |
| node.setDefaultOutcome( |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), flowSwitch.getDefaultOutcome().getFromOutcome(), |
| Object.class)); |
| } |
| } |
| |
| for (NavigationCase navCase : flowSwitch.getNavigationCaseList()) |
| { |
| SwitchCaseImpl nodeCase = new SwitchCaseImpl(); |
| nodeCase.setFromOutcome(navCase.getFromOutcome()); |
| if (StringUtils.isNotEmpty(navCase.getIf())) |
| { |
| nodeCase.setCondition( |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), navCase.getIf(), |
| Object.class)); |
| } |
| node.addCase(nodeCase); |
| } |
| |
| flow.putSwitch(node.getId(), node); |
| } |
| |
| for (FacesFlowView view : flowDefinition.getViewList()) |
| { |
| ViewNodeImpl node = new ViewNodeImpl(view.getId(), view.getVdlDocument()); |
| flow.addView(node); |
| } |
| |
| for (FacesFlowReturn flowReturn : flowDefinition.getReturnList()) |
| { |
| ReturnNodeImpl node = new ReturnNodeImpl(flowReturn.getId()); |
| if (flowReturn.getNavigationCase() != null && |
| StringUtils.isNotEmpty(flowReturn.getNavigationCase().getFromOutcome())) |
| { |
| if (ELText.isLiteral(flowReturn.getNavigationCase().getFromOutcome())) |
| { |
| node.setFromOutcome(flowReturn.getNavigationCase().getFromOutcome()); |
| } |
| else |
| { |
| node.setFromOutcome( |
| application.getExpressionFactory().createValueExpression( |
| facesContext.getELContext(), flowReturn.getNavigationCase().getFromOutcome(), |
| Object.class)); |
| } |
| } |
| flow.putReturn(node.getId(), node); |
| } |
| |
| flow.freeze(); |
| |
| // Add the flow, so the config can be processed by the flow system and the |
| // navigation system. |
| application.getFlowHandler().addFlow(facesContext, flow); |
| } |
| |
| AnnotatedFlowConfigurator.configureAnnotatedFlows(facesContext); |
| } |
| |
| public static void enableDefaultWindowMode(FacesContext facesContext) |
| { |
| if (!isEnableDefaultWindowMode(facesContext)) |
| { |
| String windowMode = WebConfigParamUtils.getStringInitParameter( |
| facesContext.getExternalContext(), |
| ClientWindow.CLIENT_WINDOW_MODE_PARAM_NAME, null); |
| |
| if (windowMode == null) |
| { |
| //No window mode set, force window mode to url |
| String defaultWindowMode = WebConfigParamUtils.getStringInitParameter( |
| facesContext.getExternalContext(), |
| ClientWindowFactoryImpl.INIT_PARAM_DEFAULT_WINDOW_MODE, |
| ClientWindowFactoryImpl.WINDOW_MODE_URL); |
| |
| log.info("The current configuration requires client window enabled, setting it to '"+ |
| defaultWindowMode+ '\''); |
| |
| facesContext.getExternalContext().getApplicationMap().put( |
| ENABLE_DEFAULT_WINDOW_MODE, Boolean.TRUE); |
| } |
| } |
| } |
| |
| public static boolean isEnableDefaultWindowMode(FacesContext facesContext) |
| { |
| return Boolean.TRUE.equals(facesContext.getExternalContext(). |
| getApplicationMap().get(ENABLE_DEFAULT_WINDOW_MODE)); |
| } |
| |
| public void configureProtectedViews() |
| { |
| Application application = getApplication(); |
| |
| FacesConfigData dispenser = getDispenser(); |
| //Protected Views |
| ViewHandler viewHandler = application.getViewHandler(); |
| for (String urlPattern : dispenser.getProtectedViewUrlPatterns()) |
| { |
| viewHandler.addProtectedView(urlPattern); |
| } |
| } |
| |
| protected InjectionProvider getInjectionProvider() |
| { |
| if (_injectionProvider == null) |
| { |
| _injectionProvider = InjectionProviderFactory.getInjectionProviderFactory( |
| _externalContext).getInjectionProvider(_externalContext); |
| } |
| return _injectionProvider; |
| } |
| |
| protected FacesContext getFacesContext() |
| { |
| if (_facesContext == null) |
| { |
| _facesContext = FacesContext.getCurrentInstance(); |
| } |
| return _facesContext; |
| } |
| |
| protected Application getApplication() |
| { |
| if (_application == null) |
| { |
| return getFacesContext().getApplication(); |
| } |
| return _application; |
| } |
| |
| protected void setApplication(Application application) |
| { |
| this._application = application; |
| } |
| } |