blob: 4e4a7968a698898a1b45855189d1e4cc84b174da [file] [log] [blame]
/*
* 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.webbeans.web.lifecycle;
import org.apache.webbeans.annotation.InitializedLiteral;
import org.apache.webbeans.config.OWBLogConst;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.el.ELContextStore;
import org.apache.webbeans.exception.WebBeansException;
import org.apache.webbeans.lifecycle.AbstractLifeCycle;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.spi.ResourceInjectionService;
import org.apache.webbeans.spi.adaptor.ELAdaptor;
import org.apache.webbeans.web.util.ServletCompatibilityUtil;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Singleton;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspFactory;
import java.util.logging.Level;
/**
* Manages container lifecycle.
*
* <p>
* Behaves according to the request, session, and application
* contexts of the web application.
* </p>
*
* @version $Rev: 911764 $ $Date: 2010-02-19 11:52:54 +0200 (Fri, 19 Feb 2010) $
* @see org.apache.webbeans.servlet.WebBeansConfigurationListener
*/
public final class WebContainerLifecycle extends AbstractLifeCycle
{
/**
* Creates a new lifecycle instance and initializes
* the instance variables.
*/
public WebContainerLifecycle()
{
super(null);
this.logger = WebBeansLoggerFacade.getLogger(WebContainerLifecycle.class);
}
/**
* Creates a new lifecycle instance and initializes
* the instance variables.
*/
public WebContainerLifecycle(WebBeansContext webBeansContext)
{
super(null, webBeansContext);
this.logger = WebBeansLoggerFacade.getLogger(WebContainerLifecycle.class);
}
/**
* {@inheritDoc}
*/
@Override
public void startApplication(Object startupObject)
{
ServletContext servletContext = getServletContext(startupObject);
super.startApplication(servletContext);
}
/**
* {@inheritDoc}
*/
@Override
public void stopApplication(Object endObject)
{
ServletContext servletContext = getServletContext(endObject);
super.stopApplication(servletContext);
}
/**
* {@inheritDoc}
*/
@Override
protected void afterStartApplication(final Object startupObject)
{
//Application is configured as JSP
if(getWebBeansContext().getOpenWebBeansConfiguration().isJspApplication())
{
ELAdaptor elAdaptor = getWebBeansContext().getService(ELAdaptor.class);
logger.log(Level.FINE, "Application is configured as JSP. Adding EL Resolver.");
setJspELFactory((ServletContext) startupObject, elAdaptor.getOwbELResolver());
}
ServletContext servletContext = null;
if (startupObject instanceof ServletContext)
{
servletContext = (ServletContext)(startupObject);
// Add BeanManager to the 'javax.enterprise.inject.spi.BeanManager' servlet context attribute
servletContext.setAttribute(BeanManager.class.getName(), getBeanManager());
}
// fire @Initialized(ApplicationScoped.class) if any observer for it exists
if (webBeansContext.getBeanManagerImpl().getNotificationManager().
hasContextLifecycleObserver(InitializedLiteral.INSTANCE_APPLICATION_SCOPED))
{
// we need to temporarily start the ReqeustContext
webBeansContext.getContextsService().startContext(RequestScoped.class, null);
webBeansContext.getBeanManagerImpl().fireEvent(
servletContext != null ? servletContext : new Object(), InitializedLiteral.INSTANCE_APPLICATION_SCOPED);
// shut down the RequestContext again
webBeansContext.getContextsService().endContext(RequestScoped.class, null);
}
}
@Override
protected void beforeStartApplication(Object startupObject)
{
this.scannerService.init(startupObject);
}
/**
* {@inheritDoc}
*/
@Override
protected void beforeStopApplication(Object stopObject)
{
webBeansContext.getContextsService().endContext(RequestScoped.class, null);
webBeansContext.getContextsService().endContext(ConversationScoped.class, null);
webBeansContext.getContextsService().endContext(SessionScoped.class, null);
webBeansContext.getContextsService().endContext(ApplicationScoped.class, null);
webBeansContext.getContextsService().endContext(Singleton.class, null);
// clean up the EL caches after each request
ELContextStore elStore = ELContextStore.getInstance(false);
if (elStore != null)
{
elStore.destroyELContextStore();
}
}
/**
* {@inheritDoc}
*/
@Override
protected void afterStopApplication(Object stopObject)
{
ServletContext servletContext;
if(stopObject instanceof ServletContext)
{
servletContext = (ServletContext)stopObject;
}
else
{
servletContext = getServletContext(stopObject);
}
//Clear the resource injection service
ResourceInjectionService injectionServices = getWebBeansContext().getService(ResourceInjectionService.class);
if(injectionServices != null)
{
injectionServices.clear();
}
//Comment out for commit OWB-502
//ContextFactory.cleanUpContextFactory();
this.cleanupShutdownThreadLocals();
if (logger.isLoggable(Level.INFO))
{
logger.log(Level.INFO, OWBLogConst.INFO_0002, ServletCompatibilityUtil.getServletInfo(servletContext));
}
}
/**
* Ensures that all ThreadLocals, which could have been set in this
* (shutdown-) Thread, are removed in order to prevent memory leaks.
*/
private void cleanupShutdownThreadLocals()
{
contextsService.removeThreadLocals();
}
/**
* Returns servelt context otherwise throws exception.
* @param object object
* @return servlet context
*/
private ServletContext getServletContext(Object object)
{
if(object != null)
{
if(object instanceof ServletContextEvent)
{
object = ((ServletContextEvent) object).getServletContext();
return (ServletContext)object;
}
else
{
throw new WebBeansException(WebBeansLoggerFacade.getTokenString(OWBLogConst.EXCEPT_0018));
}
}
throw new IllegalArgumentException("ServletContextEvent object but found null");
}
protected void setJspELFactory(ServletContext startupObject, Object resolver)
{
JspFactory factory = JspFactory.getDefaultFactory();
if (factory == null)
{
try
{
try
{ // no need of using the tccl since in OSGi it is init elsewhere and using container shortcut can just make it faster
Class.forName("org.apache.jasper.servlet.JasperInitializer", true, WebContainerLifecycle.class.getClassLoader());
}
catch (final Throwable th)
{
Class.forName("org.apache.jasper.compiler.JspRuntimeContext", true, WebContainerLifecycle.class.getClassLoader());
}
factory = JspFactory.getDefaultFactory();
}
catch (final Exception e)
{
// ignore
}
}
if (factory != null)
{
JspApplicationContext applicationCtx = factory.getJspApplicationContext(startupObject);
applicationCtx.addELResolver(javax.el.ELResolver.class.cast(resolver));
}
else
{
logger.log(Level.FINE, "Default JSPFactroy instance has not found");
}
}
}