/*
* JBoss, Home of Professional Open Source
* Copyright 2014, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.jboss.weld.environment.servlet;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequestEvent;
import javax.servlet.http.HttpSessionEvent;
import org.jboss.weld.environment.servlet.logging.WeldServletLogger;
import org.jboss.weld.servlet.api.ServletListener;
import org.jboss.weld.servlet.api.helpers.ForwardingServletListener;
/**
* This listener also implements {@link ServletContainerInitializer} so that it's able to boot Weld before any application code is called, and thus injections
* will succeed for all listeners, servlets, filters etc.
*
* This listener MUST NOT be defined in web.xml because it registers itself during {@link ServletContainerInitializer#onStartup(Set, ServletContext)}
* notification!
*
* {@link ServletContextListener#contextDestroyed(ServletContextEvent)}, ServletRequest and HttpSession notifications are no-op in case of the {@link Listener} is registered as well.
*
* @author Martin Kouba
* @author Jan Bartel
* @author Pete Muir
* @author Ales Justin
* @see Listener
*/
public class EnhancedListener extends ForwardingServletListener implements ServletContainerInitializer {
public static final String ENHANCED_LISTENER_USED_ATTRIBUTE_NAME = EnhancedListener.class.getPackage().getName() + ".enhancedListenerUsed";
private volatile boolean isOriginalListenerUsed = false;
private volatile WeldServletLifecycle lifecycle;
@Override
public void onStartup(Set<Class<?>> classes, ServletContext context) throws ServletException {
WeldServletLogger.LOG.initializeWeldUsingServletContainerInitializer();
context.setAttribute(ENHANCED_LISTENER_USED_ATTRIBUTE_NAME, Boolean.TRUE);
WeldServletLifecycle lifecycle = new WeldServletLifecycle();
// If not initialized properly, don't register itself as a listener
if (lifecycle.initialize(context)) {
this.lifecycle = lifecycle;
context.setAttribute(WeldServletLifecycle.INSTANCE_ATTRIBUTE_NAME, lifecycle);
context.addListener(this);
super.contextInitialized(new ServletContextEvent(context));
}
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// This listener will be always notified after org.jboss.weld.environment.servlet.Listener (if registered)
if (Boolean.TRUE.equals(sce.getServletContext().getAttribute(Listener.LISTENER_USED_ATTRIBUTE_NAME))) {
isOriginalListenerUsed = true;
WeldServletLogger.LOG.listenerUserForServletRequestAndHttpSessionNotifications();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
if (isOriginalListenerUsed) {
// Do not shutdown Weld if org.jboss.weld.environment.servlet.Listener is registered
return;
}
super.contextDestroyed(sce);
lifecycle.destroy(sce.getServletContext());
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
if (isOriginalListenerUsed) {
return;
}
super.requestDestroyed(sre);
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
if (isOriginalListenerUsed) {
return;
}
super.requestInitialized(sre);
}
@Override
public void sessionCreated(HttpSessionEvent se) {
if (isOriginalListenerUsed) {
return;
}
super.sessionCreated(se);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
if (isOriginalListenerUsed) {
return;
}
super.sessionDestroyed(se);
}
@Override
protected ServletListener delegate() {
return lifecycle.getWeldListener();
}
}