| /* |
| * 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.webapp; |
| |
| import org.apache.myfaces.config.FacesConfigValidator; |
| import org.apache.myfaces.config.FacesConfigurator; |
| import org.apache.myfaces.config.RuntimeConfig; |
| import org.apache.myfaces.context.servlet.StartupFacesContextImpl; |
| import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl; |
| import org.apache.myfaces.application.FacesServletMappingUtils; |
| import org.apache.myfaces.context.ExceptionHandlerImpl; |
| import org.apache.myfaces.application.viewstate.StateUtils; |
| import org.apache.myfaces.util.WebConfigParamUtils; |
| import org.apache.myfaces.cdi.util.BeanEntry; |
| import org.apache.myfaces.spi.InjectionProvider; |
| import org.apache.myfaces.spi.InjectionProviderException; |
| import org.apache.myfaces.spi.InjectionProviderFactory; |
| import org.apache.myfaces.spi.ViewScopeProvider; |
| import org.apache.myfaces.spi.ViewScopeProviderFactory; |
| import org.apache.myfaces.util.ExternalSpecifications; |
| import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl; |
| |
| import javax.el.ExpressionFactory; |
| import javax.faces.application.Application; |
| import javax.faces.application.ProjectStage; |
| import javax.faces.component.UIViewRoot; |
| import javax.faces.context.ExceptionHandler; |
| import javax.faces.context.ExternalContext; |
| import javax.faces.context.FacesContext; |
| import javax.faces.event.PostConstructApplicationEvent; |
| import javax.faces.event.PreDestroyApplicationEvent; |
| import javax.faces.event.SystemEvent; |
| import javax.servlet.ServletContext; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.enterprise.inject.spi.BeanManager; |
| import javax.faces.application.ViewVisitOption; |
| import javax.faces.push.PushContext; |
| import javax.websocket.DeploymentException; |
| import javax.websocket.server.ServerContainer; |
| import javax.websocket.server.ServerEndpointConfig; |
| import org.apache.myfaces.cdi.util.CDIUtils; |
| import org.apache.myfaces.config.MyfacesConfig; |
| import org.apache.myfaces.config.annotation.CdiAnnotationProviderExtension; |
| import org.apache.myfaces.push.EndpointImpl; |
| import org.apache.myfaces.push.WebsocketConfigurator; |
| import org.apache.myfaces.push.WebsocketFacesInit; |
| import org.apache.myfaces.util.lang.ClassUtils; |
| import org.apache.myfaces.spi.FacesFlowProvider; |
| import org.apache.myfaces.spi.FacesFlowProviderFactory; |
| import org.apache.myfaces.spi.ServiceProviderFinder; |
| import org.apache.myfaces.spi.ServiceProviderFinderFactory; |
| import org.apache.myfaces.view.facelets.ViewPoolProcessor; |
| import org.apache.myfaces.util.lang.StringUtils; |
| |
| /** |
| * Performs common initialization tasks. |
| */ |
| public abstract class AbstractFacesInitializer implements FacesInitializer |
| { |
| private static final Logger log = Logger.getLogger(AbstractFacesInitializer.class.getName()); |
| |
| public static final String CDI_BEAN_MANAGER_INSTANCE = "oam.cdi.BEAN_MANAGER_INSTANCE"; |
| |
| private static final String CDI_SERVLET_CONTEXT_BEAN_MANAGER_ATTRIBUTE = |
| "javax.enterprise.inject.spi.BeanManager"; |
| |
| public static final String INJECTED_BEAN_STORAGE_KEY = "org.apache.myfaces.spi.BEAN_ENTRY_STORAGE"; |
| |
| /** |
| * Performs all necessary initialization tasks like configuring this JSF |
| * application. |
| */ |
| @Override |
| public void initFaces(ServletContext servletContext) |
| { |
| try |
| { |
| if (log.isLoggable(Level.FINEST)) |
| { |
| log.finest("Initializing MyFaces"); |
| } |
| |
| // Some parts of the following configuration tasks have been implemented |
| // by using an ExternalContext. However, that's no problem as long as no |
| // one tries to call methods depending on either the ServletRequest or |
| // the ServletResponse. |
| // JSF 2.0: FacesInitializer now has some new methods to |
| // use proper startup FacesContext and ExternalContext instances. |
| FacesContext facesContext = FacesContext.getCurrentInstance(); |
| ExternalContext externalContext = facesContext.getExternalContext(); |
| |
| // Setup ServiceProviderFinder |
| ServiceProviderFinder spf = ServiceProviderFinderFactory.getServiceProviderFinder(externalContext); |
| Map<String, List<String>> spfConfig = spf.calculateKnownServiceProviderMapInfo( |
| externalContext, ServiceProviderFinder.KNOWN_SERVICES); |
| if (spfConfig != null) |
| { |
| spf.initKnownServiceProviderMapInfo(externalContext, spfConfig); |
| } |
| |
| // Parse and validate the web.xml configuration file |
| |
| if (!WebConfigParamUtils.getBooleanInitParameter(externalContext, |
| MyfacesConfig.INITIALIZE_ALWAYS_STANDALONE, false)) |
| { |
| FacesServletMappingUtils.ServletRegistrationInfo facesServletRegistration = |
| FacesServletMappingUtils.getFacesServletRegistration(facesContext, servletContext, false); |
| if (facesServletRegistration == null |
| || facesServletRegistration.getMappings() == null |
| || facesServletRegistration.getMappings().length == 0) |
| { |
| // check to see if the FacesServlet was found by MyFacesContainerInitializer |
| Boolean mappingAdded = (Boolean) servletContext.getAttribute( |
| MyFacesContainerInitializer.FACES_SERVLET_FOUND); |
| |
| if (mappingAdded == null || !mappingAdded) |
| { |
| // check if the FacesServlet has been added dynamically |
| // in a Servlet 3.0 environment by MyFacesContainerInitializer |
| mappingAdded = (Boolean) servletContext.getAttribute( |
| MyFacesContainerInitializer.FACES_SERVLET_ADDED_ATTRIBUTE); |
| |
| if (mappingAdded == null || !mappingAdded) |
| { |
| if (log.isLoggable(Level.WARNING)) |
| { |
| log.warning("No mappings of FacesServlet found. Abort initializing MyFaces."); |
| } |
| return; |
| } |
| } |
| } |
| } |
| |
| initCDIIntegration(servletContext, externalContext); |
| |
| initContainerIntegration(servletContext, externalContext); |
| |
| // log environment integrations |
| ExternalSpecifications.isBeanValidationAvailable(); |
| ExternalSpecifications.isCDIAvailable(externalContext); |
| ExternalSpecifications.isEL3Available(); |
| ExternalSpecifications.isServlet4Available(); |
| |
| ViewScopeProviderFactory viewScopeProviderFactory = |
| ViewScopeProviderFactory.getViewScopeHandlerFactory(externalContext); |
| ViewScopeProvider viewScopeProvider = viewScopeProviderFactory.getViewScopeHandler(externalContext); |
| |
| FacesFlowProviderFactory facesFlowProviderFactory = |
| FacesFlowProviderFactory.getFacesFlowProviderFactory(externalContext); |
| FacesFlowProvider facesFlowProvider = facesFlowProviderFactory.getFacesFlowProvider(externalContext); |
| |
| MyFacesHttpSessionListener listener = (MyFacesHttpSessionListener) |
| externalContext.getApplicationMap().get( |
| MyFacesHttpSessionListener.APPLICATION_MAP_KEY); |
| if (listener != null) |
| { |
| listener.setViewScopeProvider(viewScopeProvider); |
| listener.setFacesFlowProvider(facesFlowProvider); |
| } |
| |
| String useEncryption = servletContext.getInitParameter(StateUtils.USE_ENCRYPTION); |
| if ("false".equals(useEncryption)) |
| { |
| log.warning(StateUtils.USE_ENCRYPTION + " is set to false. " |
| + "This is unsecure and should only be used for local or intranet applications!"); |
| } |
| else |
| { |
| StateUtils.initSecret(servletContext); |
| } |
| |
| _dispatchApplicationEvent(servletContext, PostConstructApplicationEvent.class); |
| |
| initWebsocketIntegration(servletContext, externalContext); |
| |
| if (log.isLoggable(Level.FINEST)) |
| { |
| log.finest("ServletContext initialized"); |
| } |
| |
| WebConfigParamsLogger.logWebContextParams(facesContext); |
| |
| //Force output EL message |
| ExternalSpecifications.isBeanValidationAvailable(); |
| |
| //Start ViewPoolProcessor if necessary |
| ViewPoolProcessor.initialize(facesContext); |
| |
| Boolean automaticExtensionlessMapping = WebConfigParamUtils.getBooleanInitParameter(externalContext, |
| MyfacesConfig.AUTOMATIC_EXTENSIONLESS_MAPPING, |
| MyfacesConfig.AUTOMATIC_EXTENSIONLESS_MAPPING_DEFAULT); |
| if (Boolean.TRUE.equals(automaticExtensionlessMapping)) |
| { |
| initAutomaticExtensionlessMapping(facesContext, servletContext); |
| } |
| |
| // print out a very prominent log message if the project stage is != Production |
| if (!facesContext.isProjectStage(ProjectStage.Production)) |
| { |
| ProjectStage projectStage = facesContext.getApplication().getProjectStage(); |
| StringBuilder message = new StringBuilder("\n\n"); |
| message.append("********************************************************************\n"); |
| message.append("*** WARNING: Apache MyFaces Core is running in "); |
| message.append(projectStage.name().toUpperCase()); |
| message.append(" mode."); |
| int length = projectStage.name().length(); |
| for (int i = 0; i < 11 - length; i++) |
| { |
| message.append(' '); |
| } |
| message.append(" ***\n"); |
| message.append("*** "); |
| for (int i = 0; i < length; i++) |
| { |
| message.append('^'); |
| } |
| for (int i = 0; i < 18 - length; i++) |
| { |
| message.append(' '); |
| } |
| message.append("***\n"); |
| message.append("*** Do NOT deploy to your live server(s) without changing this. ***\n"); |
| message.append("*** See Application#getProjectStage() for more information. ***\n"); |
| message.append("********************************************************************\n"); |
| message.append("\n"); |
| log.log(Level.WARNING, message.toString()); |
| } |
| |
| cleanupAfterStartup(facesContext); |
| } |
| catch (Exception ex) |
| { |
| log.log(Level.SEVERE, "An error occured while initializing MyFaces: " |
| + ex.getMessage(), ex); |
| } |
| } |
| |
| protected void cleanupAfterStartup(FacesContext facesContext) |
| { |
| ExternalContext externalContext = facesContext.getExternalContext(); |
| |
| if (ExternalSpecifications.isCDIAvailable(externalContext)) |
| { |
| BeanManager beanManager = CDIUtils.getBeanManager(externalContext); |
| CdiAnnotationProviderExtension extension = CDIUtils.getOptional(beanManager, |
| CdiAnnotationProviderExtension.class); |
| if (extension != null) |
| { |
| extension.release(); |
| } |
| } |
| } |
| |
| /** |
| * Eventually we can use our plugin infrastructure for this as well |
| * it would be a cleaner interception point than the base class |
| * but for now this position is valid as well |
| * <p/> |
| * Note we add it for now here because the application factory object |
| * leaves no possibility to have a destroy interceptor |
| * and applications are per web application singletons |
| * Note if this does not work out |
| * move the event handler into the application factory |
| * |
| * @param servletContext the servlet context to be passed down |
| * @param eventClass the class to be passed down into the dispatching |
| * code |
| */ |
| private void _dispatchApplicationEvent(ServletContext servletContext, Class<? extends SystemEvent> eventClass) |
| { |
| FacesContext facesContext = FacesContext.getCurrentInstance(); |
| Application application = facesContext.getApplication(); |
| application.publishEvent(facesContext, eventClass, Application.class, application); |
| } |
| |
| /** |
| * Cleans up all remaining resources (well, theoretically). |
| */ |
| @Override |
| public void destroyFaces(ServletContext servletContext) |
| { |
| |
| FacesContext facesContext = FacesContext.getCurrentInstance(); |
| |
| if (!WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(), |
| MyfacesConfig.INITIALIZE_ALWAYS_STANDALONE, false)) |
| { |
| FacesServletMappingUtils.ServletRegistrationInfo facesServletRegistration = |
| FacesServletMappingUtils.getFacesServletRegistration(facesContext, servletContext, false); |
| if (facesServletRegistration == null |
| || facesServletRegistration.getMappings() == null |
| || facesServletRegistration.getMappings().length == 0) |
| { |
| // check to see if the FacesServlet was found by MyFacesContainerInitializer |
| Boolean mappingAdded = (Boolean) servletContext.getAttribute( |
| MyFacesContainerInitializer.FACES_SERVLET_FOUND); |
| |
| if (mappingAdded == null || !mappingAdded) |
| { |
| // check if the FacesServlet has been added dynamically |
| // in a Servlet 3.0 environment by MyFacesContainerInitializer |
| mappingAdded = (Boolean) servletContext.getAttribute( |
| MyFacesContainerInitializer.FACES_SERVLET_ADDED_ATTRIBUTE); |
| |
| if (mappingAdded == null || !mappingAdded) |
| { |
| if (log.isLoggable(Level.WARNING)) |
| { |
| log.warning("No mappings of FacesServlet found. Abort destroy MyFaces."); |
| } |
| return; |
| } |
| } |
| } |
| } |
| |
| _dispatchApplicationEvent(servletContext, PreDestroyApplicationEvent.class); |
| |
| _callPreDestroyOnInjectedJSFArtifacts(facesContext); |
| |
| // clear the cache of MetaRulesetImpl in order to prevent a memory leak |
| MetaRulesetImpl.clearMetadataTargetCache(); |
| |
| if (facesContext.getExternalContext().getApplicationMap().containsKey("org.apache.myfaces.push")) |
| { |
| WebsocketFacesInit.clearWebsocketSessionLRUCache(facesContext.getExternalContext()); |
| } |
| |
| // clear UIViewParameter default renderer map |
| try |
| { |
| Class<?> c = ClassUtils.classForName("javax.faces.component.UIViewParameter"); |
| Method m = c.getDeclaredMethod("releaseRenderer"); |
| m.setAccessible(true); |
| m.invoke(null); |
| } |
| catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) |
| { |
| log.log(Level.SEVERE, e.getMessage(), e); |
| } |
| |
| |
| // TODO is it possible to make a real cleanup? |
| } |
| |
| /** |
| * Configures this JSF application. It's required that every |
| * FacesInitializer (i.e. every subclass) calls this method during |
| * initialization. |
| * |
| * @param servletContext the current ServletContext |
| * @param externalContext the current ExternalContext |
| * @param expressionFactory the ExpressionFactory to use |
| * @return the current runtime configuration |
| */ |
| protected RuntimeConfig buildConfiguration(ServletContext servletContext, |
| ExternalContext externalContext, ExpressionFactory expressionFactory) |
| { |
| RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext); |
| runtimeConfig.setExpressionFactory(expressionFactory); |
| |
| // And configure everything |
| new FacesConfigurator(externalContext).configure(); |
| |
| validateFacesConfig(servletContext, externalContext); |
| |
| return runtimeConfig; |
| } |
| |
| protected void validateFacesConfig(ServletContext servletContext, ExternalContext externalContext) |
| { |
| String validate = servletContext.getInitParameter(MyfacesConfig.VALIDATE); |
| if ("true".equals(validate) && log.isLoggable(Level.WARNING)) // the default value is false |
| { |
| List<String> warnings = FacesConfigValidator.validate(externalContext); |
| |
| for (String warning : warnings) |
| { |
| log.warning(warning); |
| } |
| } |
| } |
| |
| /** |
| * Try to load user-definied ExpressionFactory. Returns <code>null</code>, |
| * if no custom ExpressionFactory was specified. |
| * |
| * @param externalContext the current ExternalContext |
| * @return User-specified ExpressionFactory, or |
| * <code>null</code>, if no no custom implementation was specified |
| */ |
| protected static ExpressionFactory getUserDefinedExpressionFactory(ExternalContext externalContext) |
| { |
| String expressionFactoryClassName |
| = MyfacesConfig.getCurrentInstance(externalContext).getExpressionFactory(); |
| if (StringUtils.isNotBlank(expressionFactoryClassName)) |
| { |
| if (log.isLoggable(Level.FINE)) |
| { |
| log.fine("Attempting to load the ExpressionFactory implementation " |
| + "you've specified: '" + expressionFactoryClassName + "'."); |
| } |
| |
| return loadExpressionFactory(expressionFactoryClassName); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Loads and instantiates the given ExpressionFactory implementation. |
| * |
| * @param expressionFactoryClassName the class name of the ExpressionFactory implementation |
| * @return the newly created ExpressionFactory implementation, or |
| * <code>null</code>, if an error occurred |
| */ |
| protected static ExpressionFactory loadExpressionFactory(String expressionFactoryClassName) |
| { |
| return loadExpressionFactory(expressionFactoryClassName, true); |
| } |
| |
| protected static ExpressionFactory loadExpressionFactory(String expressionFactoryClassName, boolean logMissing) |
| { |
| try |
| { |
| ClassLoader cl = ClassUtils.getContextClassLoader(); |
| if (cl == null) |
| { |
| cl = AbstractFacesInitializer.class.getClassLoader(); |
| } |
| |
| Class<?> expressionFactoryClass = cl.loadClass(expressionFactoryClassName); |
| return (ExpressionFactory) expressionFactoryClass.newInstance(); |
| } |
| catch (Exception ex) |
| { |
| if (log.isLoggable(Level.FINE)) |
| { |
| log.log(Level.FINE, "An error occured while instantiating a new ExpressionFactory. " |
| + "Attempted to load class '" + expressionFactoryClassName + "'.", ex); |
| } |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public FacesContext initStartupFacesContext(ServletContext servletContext) |
| { |
| // We cannot use FacesContextFactory, because it is necessary to initialize |
| // before Application and RenderKit factories, so we should use different object. |
| return _createFacesContext(servletContext, true); |
| } |
| |
| @Override |
| public void destroyStartupFacesContext(FacesContext facesContext) |
| { |
| _releaseFacesContext(facesContext); |
| } |
| |
| @Override |
| public FacesContext initShutdownFacesContext(ServletContext servletContext) |
| { |
| return _createFacesContext(servletContext, false); |
| } |
| |
| @Override |
| public void destroyShutdownFacesContext(FacesContext facesContext) |
| { |
| _releaseFacesContext(facesContext); |
| } |
| |
| private FacesContext _createFacesContext(ServletContext servletContext, boolean startup) |
| { |
| ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, startup); |
| ExceptionHandler exceptionHandler = new ExceptionHandlerImpl(); |
| FacesContext facesContext = new StartupFacesContextImpl(externalContext, |
| externalContext, exceptionHandler, startup); |
| |
| // If getViewRoot() is called during application startup or shutdown, |
| // it should return a new UIViewRoot with its locale set to Locale.getDefault(). |
| UIViewRoot startupViewRoot = new UIViewRoot(); |
| startupViewRoot.setLocale(Locale.getDefault()); |
| facesContext.setViewRoot(startupViewRoot); |
| |
| return facesContext; |
| } |
| |
| private void _releaseFacesContext(FacesContext facesContext) |
| { |
| // make sure that the facesContext gets released. |
| // This is important in an OSGi environment |
| if (facesContext != null) |
| { |
| facesContext.release(); |
| } |
| } |
| |
| /** |
| * Performs initialization tasks depending on the current environment. |
| * |
| * @param servletContext the current ServletContext |
| * @param externalContext the current ExternalContext |
| */ |
| protected abstract void initContainerIntegration( |
| ServletContext servletContext, ExternalContext externalContext); |
| |
| /** |
| * The intention of this method is provide a point where CDI integration is done. |
| * Faces Flow and javax.faces.view.ViewScope requires CDI in order to work, so |
| * this method should set a BeanManager instance on application map under |
| * the key "oam.cdi.BEAN_MANAGER_INSTANCE". The default implementation look on |
| * ServletContext first and then use JNDI. |
| * |
| * @param servletContext |
| * @param externalContext |
| */ |
| protected void initCDIIntegration( |
| ServletContext servletContext, ExternalContext externalContext) |
| { |
| // Lookup bean manager and put it into an application scope attribute to |
| // access it later. Remember the trick here is do not call any CDI api |
| // directly, so if no CDI api is on the classpath no exception will be thrown. |
| |
| // Try with servlet context |
| Object beanManager = servletContext.getAttribute( |
| CDI_SERVLET_CONTEXT_BEAN_MANAGER_ATTRIBUTE); |
| if (beanManager == null) |
| { |
| beanManager = lookupBeanManagerFromCDI(); |
| } |
| if (beanManager == null) |
| { |
| beanManager = lookupBeanManagerFromJndi(); |
| } |
| if (beanManager != null) |
| { |
| externalContext.getApplicationMap().put(CDI_BEAN_MANAGER_INSTANCE, beanManager); |
| } |
| } |
| |
| /** |
| * This method tries to use the CDI-1.1 CDI.current() method to lookup the CDI BeanManager. |
| * We do all this via reflection to not blow up if CDI-1.1 is not on the classpath. |
| * @return the BeanManager or {@code null} if either not in a CDI-1.1 environment |
| * or the BeanManager doesn't exist yet. |
| */ |
| private Object lookupBeanManagerFromCDI() |
| { |
| try |
| { |
| Class cdiClass = null; |
| Method cdiCurrentMethod = null; |
| Method cdiGetBeanManagerMethod = null; |
| cdiClass = simpleClassForNameNoException("javax.enterprise.inject.spi.CDI"); |
| if (cdiClass != null) |
| { |
| cdiCurrentMethod = cdiClass.getMethod("current"); |
| |
| Object cdiInstance = cdiCurrentMethod.invoke(null); |
| |
| cdiGetBeanManagerMethod = cdiClass.getMethod("getBeanManager"); |
| return cdiGetBeanManagerMethod.invoke(cdiInstance); |
| } |
| } |
| catch (Exception e) |
| { |
| // ignore |
| } |
| return null; |
| } |
| |
| private static Class simpleClassForNameNoException(String type) |
| { |
| try |
| { |
| return ClassUtils.classForName(type); |
| } |
| catch (ClassNotFoundException e) |
| { |
| //log.log(Level.SEVERE, "Class " + type + " not found", e); |
| //Ignore |
| return null; |
| } |
| } |
| |
| /** |
| * Try to lookup the CDI BeanManager from JNDI. |
| * We do all this via reflection to not blow up if CDI is not available. |
| */ |
| private Object lookupBeanManagerFromJndi() |
| { |
| Object beanManager = null; |
| // Use reflection to avoid restricted API in GAE |
| Class icclazz = null; |
| Method lookupMethod = null; |
| try |
| { |
| icclazz = ClassUtils.simpleClassForName("javax.naming.InitialContext"); |
| if (icclazz != null) |
| { |
| lookupMethod = icclazz.getMethod("doLookup", String.class); |
| } |
| } |
| catch (Throwable t) |
| { |
| // |
| } |
| if (lookupMethod != null) |
| { |
| // Try with JNDI |
| try |
| { |
| // in an application server |
| //beanManager = InitialContext.doLookup("java:comp/BeanManager"); |
| beanManager = lookupMethod.invoke(icclazz, "java:comp/BeanManager"); |
| } |
| catch (Exception e) |
| { |
| // silently ignore |
| } |
| catch (NoClassDefFoundError e) |
| { |
| //On Google App Engine, javax.naming.Context is a restricted class. |
| //In that case, NoClassDefFoundError is thrown. stageName needs to be configured |
| //below by context parameter. |
| } |
| |
| if (beanManager == null) |
| { |
| try |
| { |
| // in a servlet container |
| //beanManager = InitialContext.doLookup("java:comp/env/BeanManager"); |
| beanManager = lookupMethod.invoke(icclazz, "java:comp/env/BeanManager"); |
| } |
| catch (Exception e) |
| { |
| // silently ignore |
| } |
| catch (NoClassDefFoundError e) |
| { |
| //On Google App Engine, javax.naming.Context is a restricted class. |
| //In that case, NoClassDefFoundError is thrown. stageName needs to be configured |
| //below by context parameter. |
| } |
| } |
| } |
| |
| return beanManager; |
| } |
| |
| public void _callPreDestroyOnInjectedJSFArtifacts(FacesContext facesContext) |
| { |
| InjectionProvider injectionProvider = InjectionProviderFactory.getInjectionProviderFactory( |
| facesContext.getExternalContext()).getInjectionProvider(facesContext.getExternalContext()); |
| List<BeanEntry> injectedBeanStorage = |
| (List<BeanEntry>)facesContext.getExternalContext().getApplicationMap().get(INJECTED_BEAN_STORAGE_KEY); |
| |
| if (injectedBeanStorage != null) |
| { |
| for (BeanEntry entry : injectedBeanStorage) |
| { |
| try |
| { |
| injectionProvider.preDestroy(entry.getInstance(), entry.getCreationMetaData()); |
| } |
| catch (InjectionProviderException ex) |
| { |
| log.log(Level.INFO, "Exception on PreDestroy", ex); |
| } |
| } |
| injectedBeanStorage.clear(); |
| } |
| } |
| |
| protected void initWebsocketIntegration( |
| ServletContext servletContext, ExternalContext externalContext) |
| { |
| Boolean b = WebConfigParamUtils.getBooleanInitParameter(externalContext, |
| PushContext.ENABLE_WEBSOCKET_ENDPOINT_PARAM_NAME); |
| |
| if (Boolean.TRUE.equals(b)) |
| { |
| // get the instance |
| // see https://docs.oracle.com/javaee/7/api/javax/websocket/server/ServerContainer.html) |
| final ServerContainer serverContainer = (ServerContainer) |
| servletContext.getAttribute(ServerContainer.class.getName()); |
| if (serverContainer == null) |
| { |
| log.log(Level.INFO, "f:websocket support enabled but cannot found websocket ServerContainer instance " |
| + "on current context."); |
| return; |
| } |
| |
| try |
| { |
| serverContainer.addEndpoint(ServerEndpointConfig.Builder |
| .create(EndpointImpl.class, EndpointImpl.JAVAX_FACES_PUSH_PATH) |
| .configurator(new WebsocketConfigurator(externalContext)).build()); |
| |
| //Init LRU cache |
| WebsocketFacesInit.initWebsocketSessionLRUCache(externalContext); |
| |
| externalContext.getApplicationMap().put("org.apache.myfaces.push", "true"); |
| } |
| catch (DeploymentException e) |
| { |
| log.log(Level.INFO, "Exception on initialize Websocket Endpoint: ", e); |
| } |
| } |
| } |
| |
| /** |
| * |
| * @since 2.3 |
| * @param facesContext |
| * @param servletContext |
| */ |
| protected void initAutomaticExtensionlessMapping(FacesContext facesContext, ServletContext servletContext) |
| { |
| FacesServletMappingUtils.ServletRegistrationInfo facesServletRegistration = |
| FacesServletMappingUtils.getFacesServletRegistration(facesContext, servletContext, false); |
| if (facesServletRegistration != null) |
| { |
| facesContext.getApplication().getViewHandler().getViews(facesContext, "/", |
| ViewVisitOption.RETURN_AS_MINIMAL_IMPLICIT_OUTCOME).forEach(s -> { |
| facesServletRegistration.getRegistration().addMapping(s); |
| }); |
| } |
| } |
| |
| |
| } |