blob: e497573d272cbda70f5663b17a71943b40784afc [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.felix.http.base.internal.whiteboard;
import static org.apache.felix.http.base.internal.util.UriUtils.decodePath;
import static org.apache.felix.http.base.internal.util.UriUtils.removeDotSegments;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
import org.apache.felix.http.base.internal.dispatch.RequestDispatcherImpl;
import org.apache.felix.http.base.internal.dispatch.RequestInfo;
import org.apache.felix.http.base.internal.handler.ServletHandler;
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.registry.PathResolution;
import org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry;
import org.apache.felix.http.base.internal.registry.ServletResolution;
import org.apache.felix.http.base.internal.util.UriUtils;
/**
* This servlet context implementation represents the shared
* part for a servlet context backed by a servlet context helper.
*
* For each using bundle, a {@link PerBundleServletContextImpl} is created.
*/
public class SharedServletContextImpl implements ServletContext
{
private final ServletContext context;
private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
private final String contextPath;
private final String name;
private final PerContextHandlerRegistry registry;
private final ServletContextAttributeListener attributeListener;
private final Map<String, String> initParameters = new HashMap<String, String>();
public SharedServletContextImpl(final ServletContext webContext,
final String name,
final String path,
final Map<String, String> initParameters,
final PerContextHandlerRegistry registry)
{
this.context = webContext;
if ( path.equals("/") )
{
this.contextPath = webContext.getContextPath();
}
else
{
this.contextPath = webContext.getContextPath() + path;
}
this.name = name;
if ( initParameters != null )
{
this.initParameters.putAll(initParameters);
}
this.attributeListener = registry.getEventListenerRegistry();
this.registry = registry;
}
@Override
public ClassLoader getClassLoader()
{
// is implemented by {@link PerBundleServletContextImpl}.
return null;
}
/**
* @see javax.servlet.ServletContext#getResource(java.lang.String)
*/
@Override
public URL getResource(String path)
{
// is implemented by {@link PerBundleServletContextImpl}.
return null;
}
@Override
public String getMimeType(String file)
{
// is implemented by {@link PerBundleServletContextImpl}.
return null;
}
@Override
public String getRealPath(String path)
{
// is implemented by {@link PerBundleServletContextImpl}.
return null;
}
@Override
public Set<String> getResourcePaths(final String path)
{
// is implemented by {@link PerBundleServletContextImpl}.
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(final String filterName, final Class<? extends Filter> type)
{
throw new UnsupportedOperationException();
}
@Override
public FilterRegistration.Dynamic addFilter(final String filterName, final Filter filter)
{
throw new UnsupportedOperationException();
}
@Override
public FilterRegistration.Dynamic addFilter(final String filterName, final String className)
{
throw new UnsupportedOperationException();
}
@Override
public void addListener(final Class<? extends EventListener> type)
{
throw new UnsupportedOperationException();
}
@Override
public void addListener(final String className)
{
throw new UnsupportedOperationException();
}
@Override
public <T extends EventListener> void addListener(final T listener)
{
throw new UnsupportedOperationException();
}
@Override
public ServletRegistration.Dynamic addServlet(final String servletName, final Class<? extends Servlet> type)
{
throw new UnsupportedOperationException();
}
@Override
public ServletRegistration.Dynamic addServlet(final String servletName, final Servlet servlet)
{
throw new UnsupportedOperationException();
}
@Override
public ServletRegistration.Dynamic addServlet(final String servletName, final String className)
{
throw new UnsupportedOperationException();
}
@Override
public <T extends Filter> T createFilter(final Class<T> type) throws ServletException
{
throw new UnsupportedOperationException();
}
@Override
public <T extends EventListener> T createListener(final Class<T> type) throws ServletException
{
throw new UnsupportedOperationException();
}
@Override
public <T extends Servlet> T createServlet(final Class<T> type) throws ServletException
{
throw new UnsupportedOperationException();
}
@Override
public void declareRoles(final String... roleNames)
{
throw new UnsupportedOperationException();
}
@Override
public String getVirtualServerName() {
return context.getVirtualServerName();
}
@Override
public Object getAttribute(final String name)
{
return this.attributes.get(name);
}
@Override
public Enumeration<String> getAttributeNames()
{
return Collections.enumeration(this.attributes.keySet());
}
@Override
public ServletContext getContext(final String uri)
{
return this.context.getContext(uri);
}
@Override
public String getContextPath()
{
return this.contextPath;
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
{
return this.context.getDefaultSessionTrackingModes();
}
@Override
public int getEffectiveMajorVersion()
{
return this.context.getEffectiveMajorVersion();
}
@Override
public int getEffectiveMinorVersion()
{
return this.context.getEffectiveMinorVersion();
}
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
{
return this.context.getEffectiveSessionTrackingModes();
}
@Override
public FilterRegistration getFilterRegistration(final String filterName)
{
return this.context.getFilterRegistration(filterName);
}
@Override
public Map<String, ? extends FilterRegistration> getFilterRegistrations()
{
return this.context.getFilterRegistrations();
}
@Override
public String getInitParameter(final String name)
{
return this.initParameters.get(name);
}
@Override
public Enumeration<String> getInitParameterNames()
{
return Collections.enumeration(this.initParameters.keySet());
}
@Override
public JspConfigDescriptor getJspConfigDescriptor()
{
return null;
}
@Override
public int getMajorVersion()
{
return this.context.getMajorVersion();
}
@Override
public int getMinorVersion()
{
return this.context.getMinorVersion();
}
@Override
public RequestDispatcher getNamedDispatcher(final String name)
{
if (name == null)
{
return null;
}
final RequestDispatcher dispatcher;
final ServletHandler servletHandler = this.registry.resolveServletByName(name);
if ( servletHandler != null )
{
final ServletResolution resolution = new ServletResolution();
resolution.handler = servletHandler;
resolution.handlerRegistry = this.registry;
// TODO - what is the path of a named servlet?
final RequestInfo requestInfo = new RequestInfo("", null, null, null);
dispatcher = new RequestDispatcherImpl(resolution, requestInfo);
}
else
{
dispatcher = null;
}
return dispatcher;
}
@Override
public RequestDispatcher getRequestDispatcher(String path)
{
// See section 9.1 of Servlet 3.x specification...
if (path == null || (!path.startsWith("/") && !"".equals(path)))
{
return null;
}
String query = null;
int q = 0;
if ((q = path.indexOf('?')) > 0)
{
query = path.substring(q + 1);
path = path.substring(0, q);
}
// TODO remove path parameters...
final String encodedRequestURI = path == null ? "" : removeDotSegments(path);
final String requestURI = decodePath(encodedRequestURI);
final RequestDispatcher dispatcher;
final PathResolution pathResolution = this.registry.resolve(requestURI);
if ( pathResolution != null )
{
final ServletResolution resolution = new ServletResolution();
resolution.handler = pathResolution.handler;
resolution.handlerRegistry = this.registry;
final RequestInfo requestInfo = new RequestInfo(pathResolution.servletPath, pathResolution.pathInfo, query,
UriUtils.concat(this.contextPath, encodedRequestURI));
dispatcher = new RequestDispatcherImpl(resolution, requestInfo);
}
else
{
dispatcher = null;
}
return dispatcher;
}
@Override
public InputStream getResourceAsStream(final String path)
{
// is implemented by {@link PerBundleServletContextImpl}.
return null;
}
@Override
public String getServerInfo()
{
return this.context.getServerInfo();
}
@SuppressWarnings("deprecation")
@Override
public Servlet getServlet(final String name) throws ServletException
{
return this.context.getServlet(name);
}
@Override
public String getServletContextName()
{
return this.name;
}
@SuppressWarnings("deprecation")
@Override
public Enumeration<String> getServletNames()
{
return this.context.getServletNames();
}
@Override
public ServletRegistration getServletRegistration(final String servletName)
{
return this.context.getServletRegistration(servletName);
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations()
{
return this.context.getServletRegistrations();
}
@SuppressWarnings("deprecation")
@Override
public Enumeration<Servlet> getServlets()
{
return this.context.getServlets();
}
@Override
public SessionCookieConfig getSessionCookieConfig()
{
return this.context.getSessionCookieConfig();
}
@SuppressWarnings("deprecation")
@Override
public void log(final Exception cause, final String message)
{
SystemLogger.error(message, cause);
}
@Override
public void log(final String message)
{
SystemLogger.info(message);
}
@Override
public void log(final String message, final Throwable cause)
{
SystemLogger.error(message, cause);
}
@Override
public void removeAttribute(final String name)
{
final Object oldValue = this.attributes.remove(name);
if (oldValue != null)
{
this.attributeListener.attributeRemoved(new ServletContextAttributeEvent(this, name, oldValue));
}
}
@Override
public void setAttribute(final String name, final Object value)
{
if (value == null)
{
this.removeAttribute(name);
}
else if (name != null)
{
Object oldValue = this.attributes.put(name, value);
if (oldValue == null)
{
this.attributeListener.attributeAdded(new ServletContextAttributeEvent(this, name, value));
}
else
{
this.attributeListener.attributeReplaced(new ServletContextAttributeEvent(this, name, oldValue));
}
}
}
@Override
public boolean setInitParameter(final String name, final String value)
{
throw new IllegalStateException();
}
@Override
public void setSessionTrackingModes(final Set<SessionTrackingMode> modes)
{
throw new IllegalStateException();
}
}