/*
* 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;
import org.exoplatform.container.util.Utils;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletRegistration.Dynamic;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
/**
* This class is used to merge all the {@link ServletContext} related to a given portal container.
* It will used the {@link WebAppInitContext} that have been defined in the related portal container.
* It will always consider that the {@link WebAppInitContext}
* with the highest priority has always right, in other words for example in the method
* getInitParameter, it will try to get the init parameter in the {@link WebAppInitContext}
* of the highest priority, if it cans not find it, it will try the {@link WebAppInitContext}
* with the second highest priority and so on. The priority of the {@link WebAppInitContext} is
* the order given by the method PortalContainer.getWebAppInitContexts(),
* the last {@link WebAppInitContext} is the one with the highest priority.
*
* Created by The eXo Platform SAS
* Author : Nicolas Filotto
* nicolas.filotto@exoplatform.com
* 14 sept. 2009
*/
class PortalContainerContext implements ServletContext
{
/**
* The weak reference to the related portal container
*/
private volatile WeakReference<PortalContainer> containerRef;
/**
* The name of the related portal container used in case of developing mode
*/
private final String portalContainerName;
PortalContainerContext(PortalContainer container)
{
// In case of developing mode we want to avoid to use hard reference in case
// we would like to reload the container
this.containerRef = new WeakReference<PortalContainer>(container);
this.portalContainerName = container.getName();
}
private WebAppInitContext[] getWebAppInitContexts()
{
final Set<WebAppInitContext> contexts = getPortalContainer().getWebAppInitContexts();
final WebAppInitContext[] aContexts = new WebAppInitContext[contexts.size()];
return (WebAppInitContext[])contexts.toArray(aContexts);
}
private PortalContainer getPortalContainer()
{
PortalContainer container = containerRef.get();
if (container != null)
{
return container;
}
container = RootContainer.getInstance().getPortalContainer(portalContainerName);
containerRef = new WeakReference<PortalContainer>(container);
return container;
}
private ServletContext getPortalContext()
{
return getPortalContainer().portalContext;
}
/**
* {@inheritDoc}
*/
public Object getAttribute(String name)
{
return getPortalContext().getAttribute(name);
}
/**
* {@inheritDoc}
*/
public Enumeration<String> getAttributeNames()
{
return getPortalContext().getAttributeNames();
}
/**
* {@inheritDoc}
*/
public ServletContext getContext(String uripath)
{
return getPortalContext().getContext(uripath);
}
/**
* {@inheritDoc}
*/
public String getInitParameter(String name)
{
final WebAppInitContext[] contexts = getWebAppInitContexts();
for (int i = contexts.length - 1; i >= 0; i--)
{
final ServletContext context = contexts[i].getServletContext();
String param = context.getInitParameter(name);
if (param != null)
{
return param;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public Enumeration<String> getInitParameterNames()
{
final Set<WebAppInitContext> contexts = getPortalContainer().getWebAppInitContexts();
Set<String> names = null;
for (WebAppInitContext context : contexts)
{
Enumeration<String> eNames = context.getServletContext().getAttributeNames();
if (eNames != null)
{
if (names == null)
{
names = new HashSet<String>();
}
names.addAll(Collections.list(eNames));
}
}
if (names == null)
{
return null;
}
return Collections.enumeration(names);
}
/**
* {@inheritDoc}
*/
public int getMajorVersion()
{
return getPortalContext().getMajorVersion();
}
/**
* {@inheritDoc}
*/
public String getMimeType(String file)
{
final WebAppInitContext[] contexts = getWebAppInitContexts();
for (int i = contexts.length - 1; i >= 0; i--)
{
final ServletContext context = contexts[i].getServletContext();
String mimeType = context.getMimeType(file);
if (mimeType != null)
{
return mimeType;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public int getMinorVersion()
{
return getPortalContext().getMinorVersion();
}
/**
* {@inheritDoc}
*/
public RequestDispatcher getNamedDispatcher(String name)
{
return getPortalContext().getNamedDispatcher(name);
}
/**
* {@inheritDoc}
*/
public String getRealPath(String path)
{
final WebAppInitContext[] contexts = getWebAppInitContexts();
for (int i = contexts.length - 1; i >= 0; i--)
{
final ServletContext context = contexts[i].getServletContext();
final InputStream is = context.getResourceAsStream(path);
if (is != null)
{
// The resource exists within this servlet context
return context.getRealPath(path);
}
}
return null;
}
/**
* {@inheritDoc}
*/
public RequestDispatcher getRequestDispatcher(String path)
{
final WebAppInitContext[] contexts = getWebAppInitContexts();
for (int i = contexts.length - 1; i >= 0; i--)
{
final ServletContext context = contexts[i].getServletContext();
final InputStream is = context.getResourceAsStream(Utils.getPathOnly(path));
if (is != null)
{
// The resource exists within this servlet context
return context.getRequestDispatcher(path);
}
}
return null;
}
/**
* {@inheritDoc}
*/
public URL getResource(String path) throws MalformedURLException
{
final WebAppInitContext[] contexts = getWebAppInitContexts();
for (int i = contexts.length - 1; i >= 0; i--)
{
final ServletContext context = contexts[i].getServletContext();
final URL url = context.getResource(path);
if (url != null)
{
return url;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public InputStream getResourceAsStream(String path)
{
final WebAppInitContext[] contexts = getWebAppInitContexts();
for (int i = contexts.length - 1; i >= 0; i--)
{
final ServletContext context = contexts[i].getServletContext();
final InputStream is = context.getResourceAsStream(path);
if (is != null)
{
return is;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public Set<String> getResourcePaths(String path)
{
final Set<WebAppInitContext> contexts = getPortalContainer().getWebAppInitContexts();
Set<String> paths = null;
for (WebAppInitContext context : contexts)
{
Set<String> sPaths = context.getServletContext().getResourcePaths(path);
if (sPaths != null)
{
if (paths == null)
{
paths = new LinkedHashSet<String>();
}
paths.addAll(sPaths);
}
}
return paths;
}
/**
* {@inheritDoc}
*/
public String getServerInfo()
{
return getPortalContext().getServerInfo();
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("deprecation")
public Servlet getServlet(String name) throws ServletException
{
return getPortalContext().getServlet(name);
}
/**
* {@inheritDoc}
*/
public String getServletContextName()
{
return getPortalContext().getServletContextName();
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("deprecation")
public Enumeration<String> getServletNames()
{
return getPortalContext().getServletNames();
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("deprecation")
public Enumeration<Servlet> getServlets()
{
return getPortalContext().getServlets();
}
/**
* {@inheritDoc}
*/
public void log(String message)
{
getPortalContext().log(message);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("deprecation")
public void log(Exception exception, String message)
{
getPortalContext().log(exception, message);
}
/**
* {@inheritDoc}
*/
public void log(String message, Throwable throwable)
{
getPortalContext().log(message, throwable);
}
/**
* {@inheritDoc}
*/
public void removeAttribute(String name)
{
getPortalContext().removeAttribute(name);
}
/**
* {@inheritDoc}
*/
public void setAttribute(String name, Object object)
{
getPortalContext().setAttribute(name, object);
}
/**
* {@inheritDoc}
*/
public String getContextPath()
{
return getPortalContext().getContextPath();
}
// servlet 3.0. API
/**
* {@inheritDoc}
*/
public int getEffectiveMajorVersion()
{
return getPortalContext().getEffectiveMajorVersion();
}
/**
* {@inheritDoc}
*/
public int getEffectiveMinorVersion()
{
return getPortalContext().getEffectiveMinorVersion();
}
/**
* {@inheritDoc}
*/
public boolean setInitParameter(String name, String value)
{
return getPortalContext().setInitParameter(name, value);
}
/**
* {@inheritDoc}
*/
public Dynamic addServlet(String servletName, String className)
{
return getPortalContext().addServlet(servletName, className);
}
/**
* {@inheritDoc}
*/
public Dynamic addServlet(String servletName, Servlet servlet)
{
return getPortalContext().addServlet(servletName, servlet);
}
/**
* {@inheritDoc}
*/
public Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)
{
return getPortalContext().addServlet(servletName, servletClass);
}
/**
* {@inheritDoc}
*/
public <T extends Servlet> T createServlet(Class<T> clazz) throws ServletException
{
return getPortalContext().createServlet(clazz);
}
/**
* {@inheritDoc}
*/
public ServletRegistration getServletRegistration(String servletName)
{
return getPortalContext().getServletRegistration(servletName);
}
/**
* {@inheritDoc}
*/
public Map<String, ? extends ServletRegistration> getServletRegistrations()
{
return getPortalContext().getServletRegistrations();
}
/**
* {@inheritDoc}
*/
public javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, String className)
{
return getPortalContext().addFilter(filterName, className);
}
/**
* {@inheritDoc}
*/
public javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, Filter filter)
{
return getPortalContext().addFilter(filterName, filter);
}
/**
* {@inheritDoc}
*/
public javax.servlet.FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass)
{
return getPortalContext().addFilter(filterName, filterClass);
}
/**
* {@inheritDoc}
*/
public <T extends Filter> T createFilter(Class<T> clazz) throws ServletException
{
return getPortalContext().createFilter(clazz);
}
/**
* {@inheritDoc}
*/
public FilterRegistration getFilterRegistration(String filterName)
{
return getPortalContext().getFilterRegistration(filterName);
}
/**
* {@inheritDoc}
*/
public Map<String, ? extends FilterRegistration> getFilterRegistrations()
{
return getPortalContext().getFilterRegistrations();
}
/**
* {@inheritDoc}
*/
public SessionCookieConfig getSessionCookieConfig()
{
return getPortalContext().getSessionCookieConfig();
}
/**
* {@inheritDoc}
*/
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
{
getPortalContext().setSessionTrackingModes(sessionTrackingModes);
}
/**
* {@inheritDoc}
*/
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
{
return getPortalContext().getDefaultSessionTrackingModes();
}
/**
* {@inheritDoc}
*/
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
{
return getPortalContext().getEffectiveSessionTrackingModes();
}
/**
* {@inheritDoc}
*/
public void addListener(String className)
{
getPortalContext().addListener(className);
}
/**
* {@inheritDoc}
*/
public <T extends EventListener> void addListener(T t)
{
getPortalContext().addListener(t);
}
/**
* {@inheritDoc}
*/
public void addListener(Class<? extends EventListener> listenerClass)
{
getPortalContext().addListener(listenerClass);
}
/**
* {@inheritDoc}
*/
public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
{
return getPortalContext().createListener(clazz);
}
/**
* {@inheritDoc}
*/
public JspConfigDescriptor getJspConfigDescriptor()
{
return getPortalContext().getJspConfigDescriptor();
}
/**
* {@inheritDoc}
*/
public ClassLoader getClassLoader()
{
return getPortalContainer().getPortalClassLoader();
}
/**
* {@inheritDoc}
*/
public void declareRoles(String... roleNames)
{
getPortalContext().declareRoles(roleNames);
}
}