/* * 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.isis.core.webapp; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import com.google.inject.Guice; import com.google.inject.Injector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.isis.core.commons.config.IsisConfigurationDefault; import org.apache.isis.core.commons.config.NotFoundPolicy; import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder; import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath; import org.apache.isis.core.commons.resource.ResourceStreamSourceCurrentClassClassPath; import org.apache.isis.core.commons.resource.ResourceStreamSourceFileSystem; import org.apache.isis.core.metamodel.deployment.DeploymentCategory; import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer; import org.apache.isis.core.runtime.runner.IsisInjectModule; import org.apache.isis.core.runtime.runner.opts.OptionHandlerInitParameters; import org.apache.isis.core.runtime.system.DeploymentType; import org.apache.isis.core.runtime.system.SystemConstants; import org.apache.isis.core.runtime.system.session.IsisSessionFactory; import org.apache.isis.core.runtime.system.session.IsisSessionFactoryBuilder; import org.apache.isis.core.webapp.config.ResourceStreamSourceForWebInf; /** * Initialize the {@link IsisSessionFactoryBuilder} when the web application starts, and * destroys it when it ends. * <p> * Implementation note: we use a number of helper builders to keep this class as * small and focused as possible. The builders are available for reuse by other * bootstrappers. */ public class IsisWebAppBootstrapper implements ServletContextListener { private static final Logger LOG = LoggerFactory.getLogger(IsisWebAppBootstrapper.class); private final IsisLoggingConfigurer loggingConfigurer = new IsisLoggingConfigurer(); @com.google.inject.Inject private IsisSessionFactory isisSessionFactory; /** * Convenience for servlets that need to obtain the {@link IsisSessionFactoryBuilder}. */ public static IsisSessionFactoryBuilder getSystemBoundTo(final ServletContext servletContext) { final Object system = servletContext.getAttribute(WebAppConstants.ISIS_SESSION_FACTORY); return (IsisSessionFactoryBuilder) system; } // ///////////////////////////////////////////////////// // Initialization // ///////////////////////////////////////////////////// @Override public void contextInitialized(final ServletContextEvent servletContextEvent) { try { final ServletContext servletContext = servletContextEvent.getServletContext(); final String webInfDir = servletContext.getRealPath("/WEB-INF"); loggingConfigurer.configureLogging(webInfDir, new String[0]); final IsisConfigurationBuilder isisConfigurationBuilder = obtainIsisConfigurationBuilder(servletContext); isisConfigurationBuilder.addDefaultConfigurationResourcesAndPrimers(); final DeploymentType deploymentType = determineDeploymentType(servletContext, isisConfigurationBuilder); addConfigurationResourcesForDeploymentType(isisConfigurationBuilder, deploymentType); final String webappDir = servletContext.getRealPath("/"); isisConfigurationBuilder.add(WebAppConstants.WEB_APP_DIR, webappDir); final IsisConfigurationDefault isisConfiguration = isisConfigurationBuilder.getConfiguration(); final DeploymentCategory deploymentCategory = deploymentType.getDeploymentCategory(); final IsisInjectModule isisModule = new IsisInjectModule(deploymentCategory, isisConfiguration); final Injector injector = Guice.createInjector(isisModule); injector.injectMembers(this); servletContext.setAttribute(WebAppConstants.ISIS_SESSION_FACTORY, isisSessionFactory); } catch (final RuntimeException e) { LOG.error("startup failed", e); throw e; } LOG.info("server started"); } protected IsisConfigurationBuilder obtainIsisConfigurationBuilder(final ServletContext servletContext) { return obtainConfigBuilderFrom(servletContext); } /** * publis so can also be used by Wicket viewer. */ public static IsisConfigurationBuilder obtainConfigBuilderFrom(final ServletContext servletContext) { final IsisConfigurationBuilder isisConfigurationBuilder = lookupIsisConfigurationBuilder(servletContext); isisConfigurationBuilder.primeWith(new OptionHandlerInitParameters(servletContext)); addResourceStreamSources(servletContext, isisConfigurationBuilder); return isisConfigurationBuilder; } public static IsisConfigurationBuilder lookupIsisConfigurationBuilder(final ServletContext servletContext) { IsisConfigurationBuilder isisConfigurationBuilder = (IsisConfigurationBuilder) servletContext.getAttribute(WebAppConstants.CONFIGURATION_BUILDER_KEY); if(isisConfigurationBuilder == null) { isisConfigurationBuilder = new IsisConfigurationBuilder(); } return isisConfigurationBuilder; } private static void addResourceStreamSources( final ServletContext servletContext, final IsisConfigurationBuilder isisConfigurationBuilder) { // will load either from WEB-INF, from the classpath or from config directory. final String configLocation = servletContext.getInitParameter(WebAppConstants.CONFIG_DIR_PARAM); if ( configLocation != null ) { LOG.info( "Config override location: " + configLocation ); isisConfigurationBuilder.addResourceStreamSource(ResourceStreamSourceFileSystem.create(configLocation)); } else { LOG.info( "Config override location: No override location configured" ); isisConfigurationBuilder.addResourceStreamSource(ResourceStreamSourceContextLoaderClassPath.create()); isisConfigurationBuilder.addResourceStreamSource(new ResourceStreamSourceCurrentClassClassPath()); isisConfigurationBuilder.addResourceStreamSource(new ResourceStreamSourceForWebInf(servletContext)); } } private Injector createGuiceInjector( final IsisConfigurationDefault isisConfiguration, final DeploymentCategory deploymentCategory) { final IsisInjectModule isisModule = new IsisInjectModule(deploymentCategory, isisConfiguration); return Guice.createInjector(isisModule); } /** * Checks {@link IsisConfigurationBuilder configuration} for * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}, (that is, from the command * line), but otherwise searches in the {@link ServletContext}, first for * {@value WebAppConstants#DEPLOYMENT_TYPE_KEY} and also * {@value SystemConstants#DEPLOYMENT_TYPE_KEY}. * <p> * If no setting is found, defaults to {@link WebAppConstants#DEPLOYMENT_TYPE_DEFAULT}. */ protected DeploymentType determineDeploymentType( final ServletContext servletContext, final IsisConfigurationBuilder isisConfigurationBuilder) { String deploymentTypeStr = determineDeploymentTypeStr(servletContext, isisConfigurationBuilder); return DeploymentType.lookup(deploymentTypeStr); } private String determineDeploymentTypeStr( final ServletContext servletContext, final IsisConfigurationBuilder isisConfigurationBuilder) { String deploymentTypeStr; deploymentTypeStr = servletContext.getInitParameter(WebAppConstants.DEPLOYMENT_TYPE_KEY); if (deploymentTypeStr != null) { return deploymentTypeStr; } deploymentTypeStr = servletContext.getInitParameter(SystemConstants.DEPLOYMENT_TYPE_KEY); if (deploymentTypeStr != null) { return deploymentTypeStr; } deploymentTypeStr = isisConfigurationBuilder.peekConfiguration().getString(SystemConstants.DEPLOYMENT_TYPE_KEY); if (deploymentTypeStr != null) { return deploymentTypeStr; } return WebAppConstants.DEPLOYMENT_TYPE_DEFAULT; } protected void addConfigurationResourcesForDeploymentType( final IsisConfigurationBuilder isisConfigurationBuilder, final DeploymentType deploymentType) { final String resourceName = deploymentType.name().toLowerCase() + ".properties"; isisConfigurationBuilder.addConfigurationResource(resourceName, NotFoundPolicy.CONTINUE, IsisConfigurationDefault.ContainsPolicy.IGNORE); } // ///////////////////////////////////////////////////// // Destroy // ///////////////////////////////////////////////////// @Override public void contextDestroyed(final ServletContextEvent ev) { LOG.info("server shutting down"); final ServletContext servletContext = ev.getServletContext(); try { final IsisSessionFactory isisSessionFactory = (IsisSessionFactory) servletContext.getAttribute(WebAppConstants.ISIS_SESSION_FACTORY); if (isisSessionFactory != null) { LOG.info("calling system shutdown"); isisSessionFactory.destroyServicesAndShutdown(); } } finally { servletContext.removeAttribute(WebAppConstants.ISIS_SESSION_FACTORY); LOG.info("server shut down"); } } }