/* * Copyright (C) 2009 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.container.web; import org.exoplatform.commons.utils.PropertyManager; import org.exoplatform.container.ExoContainer; import org.exoplatform.container.ExoContainerContext; import org.exoplatform.container.PortalContainer; import org.exoplatform.container.RootContainer; import org.exoplatform.container.util.ContainerUtil; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * Created by The eXo Platform SAS * Author : Nicolas Filotto * nicolas.filotto@exoplatform.com * 29 sept. 2009 */ public abstract class AbstractHttpSessionListener implements HttpSessionListener { /** * The logger */ private static final Log LOG = ExoLogger.getLogger("exo.kernel.container.AbstractHttpSessionListener"); /** * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent) */ public final void sessionCreated(HttpSessionEvent event) { final ExoContainer oldContainer = ExoContainerContext.getCurrentContainerIfPresent(); // Keep the old ClassLoader final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); ExoContainer container = null; boolean hasBeenSet = false; try { container = getContainer(event); if (container == null) return; if (!container.equals(oldContainer)) { if (container instanceof PortalContainer) { PortalContainer.setInstance((PortalContainer)container); } ExoContainerContext.setCurrentContainer(container); hasBeenSet = true; } if (requirePortalEnvironment()) { final String ctxName = ContainerUtil.getServletContextName(event.getSession().getServletContext()); if (!PortalContainer.isPortalContainerNameDisabled(ctxName) && container instanceof PortalContainer) { if (PortalContainer.getInstanceIfPresent() == null) { // The portal container has not been set PortalContainer.setInstance((PortalContainer)container); hasBeenSet = true; } // Set the full classloader of the portal container Thread.currentThread().setContextClassLoader(((PortalContainer)container).getPortalClassLoader()); } else { if (PropertyManager.isDevelopping()) { LOG.info("The portal environment could not be set for the webapp '" + ctxName + "' because this servlet context has not been defined as a " + "dependency of any portal container or it is a disabled portal" + " container, the sessionCreated event will be ignored"); } return; } } onSessionCreated(container, event); } finally { if (hasBeenSet) { if (container instanceof PortalContainer) { // Remove the current Portal Container and the current ExoContainer PortalContainer.setInstance(null); } // Re-set the old container ExoContainerContext.setCurrentContainer(oldContainer); } if (requirePortalEnvironment()) { // Re-set the old classloader Thread.currentThread().setContextClassLoader(currentClassLoader); } } } /** * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) */ public final void sessionDestroyed(HttpSessionEvent event) { final ExoContainer oldContainer = ExoContainerContext.getCurrentContainerIfPresent(); // Keep the old ClassLoader final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); ExoContainer container = null; boolean hasBeenSet = false; try { container = getContainer(event); if (container == null) return; if (!container.equals(oldContainer)) { if (container instanceof PortalContainer) { PortalContainer.setInstance((PortalContainer)container); } ExoContainerContext.setCurrentContainer(container); hasBeenSet = true; } if (requirePortalEnvironment()) { final String ctxName = ContainerUtil.getServletContextName(event.getSession().getServletContext()); if (!PortalContainer.isPortalContainerNameDisabled(ctxName) && container instanceof PortalContainer) { if (PortalContainer.getInstanceIfPresent() == null) { // The portal container has not been set PortalContainer.setInstance((PortalContainer)container); hasBeenSet = true; } // Set the full classloader of the portal container Thread.currentThread().setContextClassLoader(((PortalContainer)container).getPortalClassLoader()); } else { if (PropertyManager.isDevelopping()) { LOG.info("The portal environment could not be set for the webapp '" + ctxName + "' because this servlet context has not been defined as a " + "dependency of any portal container or it is a disabled portal" + " container, the sessionDestroyed event will be ignored"); } return; } } onSessionDestroyed(container, event); } finally { if (hasBeenSet) { if (container instanceof PortalContainer) { // Remove the current Portal Container and the current ExoContainer PortalContainer.setInstance(null); } // Re-set the old container ExoContainerContext.setCurrentContainer(oldContainer); } if (requirePortalEnvironment()) { // Re-set the old classloader Thread.currentThread().setContextClassLoader(currentClassLoader); } } } /** * Indicates if it requires that a full portal environment must be set * @return <code>true</code> if it requires the portal environment <code>false</code> otherwise. */ protected abstract boolean requirePortalEnvironment(); /** * Allow sub-classes to execute an action when a session is created * @param container the eXo container * @param event the {@link HttpSessionEvent} */ protected abstract void onSessionCreated(ExoContainer container, HttpSessionEvent event); /** * Allow sub-classes to execute an action when a session is destroyed * @param container the eXo container * @param event the {@link HttpSessionEvent} */ protected abstract void onSessionDestroyed(ExoContainer container, HttpSessionEvent event); /** * @return Gives the {@link ExoContainer} that fits best with the current context */ protected final ExoContainer getContainer(HttpSessionEvent event) { ExoContainer container = ExoContainerContext.getCurrentContainerIfPresent(); if (container instanceof RootContainer) { // The top container is a RootContainer, thus we assume that we are in a portal mode container = PortalContainer.getCurrentInstance(event.getSession().getServletContext()); if (container == null) { container = ExoContainerContext.getTopContainer(); } } // The container is a PortalContainer or a StandaloneContainer return container; } }