FELIX-4060 : Implement HTTP Service Update (RFC-189) - correct context and path handling
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1659798 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContextWrapper.java b/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContextWrapper.java
new file mode 100644
index 0000000..6a04c24
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContextWrapper.java
@@ -0,0 +1,412 @@
+/*
+ * 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.context;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.EventListener;
+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.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspConfigDescriptor;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionListener;
+
+/**
+ * Wrapper of an {code ExtServletContex}.
+ * This implementation simply forwards to the delegate.
+ */
+public abstract class ExtServletContextWrapper implements ExtServletContext
+{
+ private final ExtServletContext delegate;
+
+ public ExtServletContextWrapper(final ExtServletContext delegate)
+ {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public boolean handleSecurity(final HttpServletRequest req,
+ final HttpServletResponse res) throws IOException
+ {
+ return delegate.handleSecurity(req, res);
+ }
+
+ @Override
+ public HttpSessionAttributeListener getHttpSessionAttributeListener()
+ {
+ return delegate.getHttpSessionAttributeListener();
+ }
+
+ @Override
+ public HttpSessionListener getHttpSessionListener()
+ {
+ return delegate.getHttpSessionListener();
+ }
+
+ @Override
+ public ServletRequestListener getServletRequestListener()
+ {
+ return delegate.getServletRequestListener();
+ }
+
+ @Override
+ public ServletRequestAttributeListener getServletRequestAttributeListener()
+ {
+ return delegate.getServletRequestAttributeListener();
+ }
+
+ @Override
+ public String getContextPath()
+ {
+ return delegate.getContextPath();
+ }
+
+ @Override
+ public ServletContext getContext(final String uripath)
+ {
+ return delegate.getContext(uripath);
+ }
+
+ @Override
+ public int getMajorVersion()
+ {
+ return delegate.getMajorVersion();
+ }
+
+ @Override
+ public int getMinorVersion()
+ {
+ return delegate.getMinorVersion();
+ }
+
+ @Override
+ public int getEffectiveMajorVersion()
+ {
+ return delegate.getEffectiveMajorVersion();
+ }
+
+ @Override
+ public int getEffectiveMinorVersion()
+ {
+ return delegate.getEffectiveMinorVersion();
+ }
+
+ @Override
+ public String getMimeType(final String file)
+ {
+ return delegate.getMimeType(file);
+ }
+
+ @Override
+ public Set<String> getResourcePaths(final String path)
+ {
+ return delegate.getResourcePaths(path);
+ }
+
+ @Override
+ public URL getResource(final String path) throws MalformedURLException
+ {
+ return delegate.getResource(path);
+ }
+
+ @Override
+ public InputStream getResourceAsStream(final String path)
+ {
+ return delegate.getResourceAsStream(path);
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(final String path)
+ {
+ return delegate.getRequestDispatcher(path);
+ }
+
+ @Override
+ public RequestDispatcher getNamedDispatcher(final String name)
+ {
+ return delegate.getNamedDispatcher(name);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public Servlet getServlet(final String name) throws ServletException
+ {
+ return delegate.getServlet(name);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public Enumeration<Servlet> getServlets()
+ {
+ return delegate.getServlets();
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public Enumeration<String> getServletNames()
+ {
+ return delegate.getServletNames();
+ }
+
+ @Override
+ public void log(final String msg)
+ {
+ delegate.log(msg);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void log(final Exception exception, final String msg)
+ {
+ delegate.log(exception, msg);
+ }
+
+ @Override
+ public void log(final String message, final Throwable throwable)
+ {
+ delegate.log(message, throwable);
+ }
+
+ @Override
+ public String getRealPath(final String path)
+ {
+ return delegate.getRealPath(path);
+ }
+
+ @Override
+ public String getServerInfo()
+ {
+ return delegate.getServerInfo();
+ }
+
+ @Override
+ public String getInitParameter(final String name)
+ {
+ return delegate.getInitParameter(name);
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames()
+ {
+ return delegate.getInitParameterNames();
+ }
+
+ @Override
+ public boolean setInitParameter(final String name, final String value)
+ {
+ return delegate.setInitParameter(name, value);
+ }
+
+ @Override
+ public Object getAttribute(final String name)
+ {
+ return delegate.getAttribute(name);
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames()
+ {
+ return delegate.getAttributeNames();
+ }
+
+ @Override
+ public void setAttribute(final String name, final Object object)
+ {
+ delegate.setAttribute(name, object);
+ }
+
+ @Override
+ public void removeAttribute(final String name)
+ {
+ delegate.removeAttribute(name);
+ }
+
+ @Override
+ public String getServletContextName() {
+ return delegate.getServletContextName();
+ }
+
+ @Override
+ public Dynamic addServlet(final String servletName, final String className)
+ {
+ return delegate.addServlet(servletName, className);
+ }
+
+ @Override
+ public Dynamic addServlet(final String servletName, final Servlet servlet)
+ {
+ return delegate.addServlet(servletName, servlet);
+ }
+
+ @Override
+ public Dynamic addServlet(final String servletName,
+ final Class<? extends Servlet> servletClass)
+ {
+ return delegate.addServlet(servletName, servletClass);
+ }
+
+ @Override
+ public <T extends Servlet> T createServlet(final Class<T> clazz)
+ throws ServletException
+ {
+ return delegate.createServlet(clazz);
+ }
+
+ @Override
+ public ServletRegistration getServletRegistration(final String servletName)
+ {
+ return delegate.getServletRegistration(servletName);
+ }
+
+ @Override
+ public Map<String, ? extends ServletRegistration> getServletRegistrations()
+ {
+ return delegate.getServletRegistrations();
+ }
+
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ final String filterName, final String className)
+ {
+ return delegate.addFilter(filterName, className);
+ }
+
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ final String filterName, final Filter filter)
+ {
+ return delegate.addFilter(filterName, filter);
+ }
+
+ @Override
+ public javax.servlet.FilterRegistration.Dynamic addFilter(
+ final String filterName, final Class<? extends Filter> filterClass)
+ {
+ return delegate.addFilter(filterName, filterClass);
+ }
+
+ @Override
+ public <T extends Filter> T createFilter(final Class<T> clazz)
+ throws ServletException
+ {
+ return delegate.createFilter(clazz);
+ }
+
+ @Override
+ public FilterRegistration getFilterRegistration(final String filterName)
+ {
+ return delegate.getFilterRegistration(filterName);
+ }
+
+ @Override
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations()
+ {
+ return delegate.getFilterRegistrations();
+ }
+
+ @Override
+ public SessionCookieConfig getSessionCookieConfig()
+ {
+ return delegate.getSessionCookieConfig();
+ }
+
+ @Override
+ public void setSessionTrackingModes(
+ final Set<SessionTrackingMode> sessionTrackingModes)
+ {
+ delegate.setSessionTrackingModes(sessionTrackingModes);
+ }
+
+ @Override
+ public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
+ {
+ return delegate.getDefaultSessionTrackingModes();
+ }
+
+ @Override
+ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
+ {
+ return delegate.getEffectiveSessionTrackingModes();
+ }
+
+ @Override
+ public void addListener(final String className)
+ {
+ delegate.addListener(className);
+ }
+
+ @Override
+ public <T extends EventListener> void addListener(final T t)
+ {
+ delegate.addListener(t);
+ }
+
+ @Override
+ public void addListener(final Class<? extends EventListener> listenerClass)
+ {
+ delegate.addListener(listenerClass);
+ }
+
+ @Override
+ public <T extends EventListener> T createListener(final Class<T> clazz)
+ throws ServletException
+ {
+ return delegate.createListener(clazz);
+ }
+
+ @Override
+ public JspConfigDescriptor getJspConfigDescriptor()
+ {
+ return delegate.getJspConfigDescriptor();
+ }
+
+ @Override
+ public ClassLoader getClassLoader()
+ {
+ return delegate.getClassLoader();
+ }
+
+ @Override
+ public void declareRoles(final String... roleNames)
+ {
+ delegate.declareRoles(roleNames);
+ }
+
+ @Override
+ public String getVirtualServerName()
+ {
+ return delegate.getVirtualServerName();
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
index b322bdc..07b68d3 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
@@ -327,29 +327,7 @@
@Override
public String getContextPath()
{
- /*
- * FELIX-2030 Calculate the context path for the Http Service
- * registered servlets from the container context and servlet paths
- */
- // if (contextPath == null)
- // {
- // final String context = super.getContextPath();
- // final String servlet = super.getServletPath();
- // if (context == null || context.length() == 0)
- // {
- // contextPath = servlet;
- // }
- // else if (servlet == null || servlet.length() == 0)
- // {
- // contextPath = context;
- // }
- // else
- // {
- // contextPath = context + servlet;
- // }
- // }
-
- return super.getContextPath();
+ return this.getServletContext().getContextPath();
}
@Override
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java
index 2bf1eff..2c1439f 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java
@@ -22,12 +22,13 @@
import javax.servlet.RequestDispatcher;
import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.context.ExtServletContextWrapper;
import org.apache.felix.http.base.internal.service.ServletContextImpl;
/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-class ServletContextWrapper extends ServletContextImpl
+class ServletContextWrapper extends ExtServletContextWrapper
{
private final RequestDispatcherProvider provider;
@@ -36,7 +37,7 @@
/**
* Creates a new {@link ServletContextWrapper} instance.
*/
- public ServletContextWrapper(Long contextId, ExtServletContext delegate, RequestDispatcherProvider provider)
+ public ServletContextWrapper(final Long contextId, final ExtServletContext delegate, final RequestDispatcherProvider provider)
{
super(delegate);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java
index a85b31a..72dfd90 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java
@@ -47,6 +47,7 @@
void addErrorServlet(String errorPage, ServletHandler handler) throws ServletException
{
+ // TODO Handle special values 4xx and 5xx
if (ERROR_CODE_PATTERN.matcher(errorPage).matches())
{
Integer errorCode = Integer.valueOf(errorPage);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
index 0a00329..7bc6984 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
@@ -148,7 +148,7 @@
{
return r.getErrorsMapping();
}
- else if ( serviceId == null && requestURI.startsWith(r.getPrefixPath()) )
+ else if ( serviceId == null && r.isMatching(requestURI) != null )
{
return r.getErrorsMapping();
}
@@ -205,9 +205,10 @@
final List<PerContextHandlerRegistry> regs = this.registrations;
for(final PerContextHandlerRegistry r : regs)
{
- if ( requestURI.startsWith(r.getPrefixPath()))
- {
- final ServletHandler handler = r.getServletHander(requestURI.substring(r.getPrefixPath().length() - 1));
+ final String pathInContext = r.isMatching(requestURI);
+ if ( pathInContext != null )
+ {
+ final ServletHandler handler = r.getServletHander(pathInContext);
if ( handler != null )
{
return handler;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
index 4f34b90..c6b1f4d 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
@@ -45,19 +45,30 @@
private final int ranking;
- private final String prefixPath;
+ private final String path;
+
+ private final String prefix;
public PerContextHandlerRegistry() {
this.serviceId = 0;
this.ranking = Integer.MAX_VALUE;
- this.prefixPath = "/";
+ this.path = "/";
+ this.prefix = null;
}
public PerContextHandlerRegistry(final ServletContextHelperInfo info)
{
this.serviceId = info.getServiceId();
this.ranking = info.getRanking();
- this.prefixPath = info.getPath();
+ this.path = info.getPath();
+ if ( this.path.equals("/") )
+ {
+ prefix = null;
+ }
+ else
+ {
+ prefix = this.path + "/";
+ }
}
public synchronized void addFilter(FilterHandler handler) throws ServletException
@@ -76,7 +87,7 @@
@Override
public int compareTo(final PerContextHandlerRegistry other)
{
- final int result = other.prefixPath.compareTo(this.prefixPath);
+ final int result = other.path.compareTo(this.path);
if ( result == 0 ) {
if (other.ranking == this.ranking)
{
@@ -332,9 +343,21 @@
this.servletMapping = new HandlerMapping<ServletHandler>(this.servletMap.values());
}
- public String getPrefixPath()
+ public String isMatching(final String requestURI)
{
- return this.prefixPath;
+ if ( requestURI.equals(this.path) )
+ {
+ return "";
+ }
+ if ( this.prefix == null )
+ {
+ return requestURI;
+ }
+ if ( requestURI.startsWith(this.prefix) )
+ {
+ return requestURI.substring(this.prefix.length() - 1);
+ }
+ return null;
}
public long getContextServiceId()
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
index 06694b7..182e31c 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
@@ -39,8 +39,6 @@
private final String path;
- private final String prefix;
-
/**
* The filter initialization parameters as provided during registration of the filter.
*/
@@ -51,15 +49,6 @@
super(ref);
this.name = this.getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME);
this.path = this.getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH);
- String prefix = null;
- if ( !isEmpty(this.path) )
- {
- if ( !this.path.equals("/") && this.path.length() > 1 )
- {
- prefix = this.path.substring(0, this.path.length() - 1);
- }
- }
- this.prefix = prefix;
this.initParams = getInitParams(ref, CONTEXT_INIT_PREFIX);
}
@@ -67,8 +56,12 @@
{
if ( !this.isEmpty(path) )
{
+ if ( path.equals("/") )
+ {
+ return true;
+ }
// TODO we need more validation
- if ( path.startsWith("/") && path.endsWith("/") )
+ if ( path.startsWith("/") && !path.endsWith("/") )
{
return true;
}
@@ -93,11 +86,6 @@
return this.path;
}
- public String getPrefix()
- {
- return this.prefix;
- }
-
public Map<String, String> getInitParameters()
{
return initParams;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java
index 3dd59e8..5b53585 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java
@@ -70,16 +70,6 @@
this.attributes = sharedAttributes ? null : new ConcurrentHashMap<String, Object>();
}
- protected ServletContextImpl(ExtServletContext delegate)
- {
- ServletContextImpl impl = (ServletContextImpl) delegate;
- this.bundle = impl.bundle;
- this.context = impl.context;
- this.httpContext = impl.httpContext;
- this.attributeListener = impl.attributeListener;
- this.attributes = impl.attributes;
- }
-
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> type)
{
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
index f89186f..b3703b1 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
@@ -18,7 +18,9 @@
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
@@ -43,6 +45,7 @@
import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
+import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceObjects;
import org.osgi.framework.ServiceReference;
@@ -53,12 +56,15 @@
/** The info object for the context. */
private final ServletContextHelperInfo info;
- /** A map of all created servlet contexts. */
- private final Map<Long, ContextHolder> contextMap = new HashMap<Long, ContextHolder>();
-
/** The shared part of the servlet context. */
private final ServletContext sharedContext;
+ /** The http bundle. */
+ private final Bundle bundle;
+
+ /** A map of all created servlet contexts. Each bundle gets it's own instance. */
+ private final Map<Long, ContextHolder> perBundleContextMap = new HashMap<Long, ContextHolder>();
+
/** Servlet context listeners. */
private final Map<Long, ServletContextListener> listeners = new HashMap<Long, ServletContextListener>();
@@ -82,8 +88,8 @@
private final Map<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener> requestAttributeListeners =
new ConcurrentSkipListMap<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener>();
- /** The http bundle. */
- private final Bundle bundle;
+ /** All whiteboard services - servlets, filters, resources. */
+ private final Set<WhiteboardServiceInfo<?>> whiteboardServices = new ConcurrentSkipListSet<WhiteboardServiceInfo<?>>();
/**
* Create new handler.
@@ -98,7 +104,7 @@
this.bundle = bundle;
this.sharedContext = new SharedServletContextImpl(webContext,
info.getName(),
- info.getPrefix(),
+ info.getPath(),
info.getInitParameters(),
getContextAttributeListener());
}
@@ -125,6 +131,7 @@
public void deactivate()
{
this.ungetServletContext(bundle);
+ this.whiteboardServices.clear();
}
public void initialized(@Nonnull final ServletContextListenerInfo listenerInfo)
@@ -167,9 +174,9 @@
public ExtServletContext getServletContext(@Nonnull final Bundle bundle)
{
final Long key = bundle.getBundleId();
- synchronized ( this.contextMap )
+ synchronized ( this.perBundleContextMap )
{
- ContextHolder holder = this.contextMap.get(key);
+ ContextHolder holder = this.perBundleContextMap.get(key);
if ( holder == null )
{
final ServiceObjects<ServletContextHelper> so = bundle.getBundleContext().getServiceObjects(this.info.getServiceReference());
@@ -185,7 +192,7 @@
this.getSessionAttributeListener(),
this.getServletRequestListener(),
this.getServletRequestAttributeListener());
- this.contextMap.put(key, holder);
+ this.perBundleContextMap.put(key, holder);
}
}
holder.counter++;
@@ -197,15 +204,15 @@
public void ungetServletContext(@Nonnull final Bundle bundle)
{
final Long key = bundle.getBundleId();
- synchronized ( this.contextMap )
+ synchronized ( this.perBundleContextMap )
{
- ContextHolder holder = this.contextMap.get(key);
+ ContextHolder holder = this.perBundleContextMap.get(key);
if ( holder != null )
{
holder.counter--;
if ( holder.counter <= 0 )
{
- this.contextMap.remove(key);
+ this.perBundleContextMap.remove(key);
final ServiceObjects<ServletContextHelper> so = bundle.getBundleContext().getServiceObjects(this.info.getServiceReference());
if ( so != null )
{
@@ -521,4 +528,19 @@
}
};
}
+
+ public void addWhiteboardService(final WhiteboardServiceInfo<?> info)
+ {
+ this.whiteboardServices.add(info);
+ }
+
+ public void removeWhiteboardService(final WhiteboardServiceInfo<?> info)
+ {
+ this.whiteboardServices.remove(info);
+ }
+
+ public Set<WhiteboardServiceInfo<?>> getWhiteboardServices()
+ {
+ return this.whiteboardServices;
+ }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java
index 8b934fd..ccab6aa 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java
@@ -60,18 +60,18 @@
public SharedServletContextImpl(final ServletContext webContext,
final String name,
- final String prefix,
+ final String path,
final Map<String, String> initParameters,
final ServletContextAttributeListener servletContextAttributeListener)
{
this.context = webContext;
- if ( prefix == null )
+ if ( path.equals("/") )
{
this.contextPath = webContext.getContextPath();
}
else
{
- this.contextPath = webContext.getContextPath() + prefix;
+ this.contextPath = webContext.getContextPath() + path;
}
this.name = name;
if ( initParameters != null )
@@ -372,7 +372,6 @@
@Override
public SessionCookieConfig getSessionCookieConfig()
{
- // TODO
return this.context.getSessionCookieConfig();
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
index e197517..889f0cc 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
@@ -25,6 +25,7 @@
import java.util.Set;
import javax.annotation.Nonnull;
+import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
@@ -39,6 +40,7 @@
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.ResourceInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
+import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
import org.apache.felix.http.base.internal.service.HttpServiceFactory;
import org.apache.felix.http.base.internal.whiteboard.tracker.FilterTracker;
import org.apache.felix.http.base.internal.whiteboard.tracker.HttpSessionAttributeListenerTracker;
@@ -184,6 +186,7 @@
servlet);
try {
this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addServlet(handler);
+ contextHandler.addWhiteboardService(servletInfo);
} catch (final ServletException e) {
so.ungetService(servlet);
// TODO create failure DTO
@@ -204,6 +207,7 @@
{
this.bundleContext.getServiceObjects(servletInfo.getServiceReference()).ungetService(instance);
contextHandler.ungetServletContext(servletInfo.getServiceReference().getBundle());
+ contextHandler.removeWhiteboardService(servletInfo);
}
}
@@ -225,6 +229,7 @@
filterInfo);
try {
this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addFilter(handler);
+ contextHandler.addWhiteboardService(filterInfo);
} catch (final ServletException e) {
// TODO create failure DTO
}
@@ -243,6 +248,7 @@
{
this.bundleContext.getServiceObjects(filterInfo.getServiceReference()).ungetService(instance);
contextHandler.ungetServletContext(filterInfo.getServiceReference().getBundle());
+ contextHandler.removeWhiteboardService(filterInfo);
}
}
@@ -263,6 +269,7 @@
servlet);
try {
this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addServlet(handler);
+ contextHandler.addWhiteboardService(resourceInfo);
} catch (ServletException e) {
// TODO create failure DTO
}
@@ -277,6 +284,7 @@
{
final ServletInfo servletInfo = new ServletInfo(resourceInfo);
this.unregisterServlet(contextHandler, servletInfo);
+ contextHandler.removeWhiteboardService(resourceInfo);
}
public void registerContext(@Nonnull final ContextHandler contextHandler)
@@ -348,11 +356,77 @@
}
}
- dto.errorPageDTOs = new ErrorPageDTO[0]; // TODO
- dto.filterDTOs = new FilterDTO[0]; // TODO
+ final List<ErrorPageDTO> errorPages = new ArrayList<ErrorPageDTO>();
+ final List<FilterDTO> filters = new ArrayList<FilterDTO>();
+ final List<ServletDTO> servlets = new ArrayList<ServletDTO>();
+ final List<ResourceDTO> resources = new ArrayList<ResourceDTO>();
+ for(final WhiteboardServiceInfo<?> info : handler.getWhiteboardServices())
+ {
+ if ( info instanceof ServletInfo )
+ {
+ final ServletInfo si = (ServletInfo)info;
+ if ( si.getErrorPage() != null )
+ {
+ final ErrorPageDTO page = new ErrorPageDTO();
+ errorPages.add(page);
+ page.asyncSupported = si.isAsyncSupported();
+ page.errorCodes = new long[0]; // TODO
+ page.exceptions = toStringArray(si.getErrorPage()); // TODO
+ page.initParams = new HashMap<String, String>(si.getInitParameters());
+ page.name = si.getName();
+ page.serviceId = si.getServiceId();
+ page.servletContextId = handler.getContextInfo().getServiceId();
+ page.servletInfo = null; // TODO
+ }
+ if ( si.getPatterns() != null )
+ {
+ final ServletDTO servlet = new ServletDTO();
+ servlets.add(servlet);
+ servlet.asyncSupported = si.isAsyncSupported();
+ servlet.initParams = new HashMap<String, String>(si.getInitParameters());
+ servlet.name = si.getName();
+ servlet.patterns = toStringArray(si.getPatterns());
+ servlet.serviceId = si.getServiceId();
+ servlet.servletContextId = handler.getContextInfo().getServiceId();
+ servlet.servletInfo = null; // TODO
+ }
+ }
+ else if ( info instanceof ResourceInfo )
+ {
+ final ResourceDTO rsrc = new ResourceDTO();
+ resources.add(rsrc);
+ rsrc.patterns = ((ResourceInfo)info).getPatterns();
+ rsrc.prefix = ((ResourceInfo)info).getPrefix();
+ rsrc.serviceId = info.getServiceId();
+ rsrc.servletContextId = handler.getContextInfo().getServiceId();
+ }
+ else if ( info instanceof FilterInfo )
+ {
+ final FilterDTO filter = new FilterDTO();
+ filters.add(filter);
+ filter.asyncSupported = ((FilterInfo)info).isAsyncSupported();
+ final DispatcherType[] dTypes = ((FilterInfo)info).getDispatcher();
+ filter.dispatcher = new String[dTypes.length];
+ int index = 0;
+ for(final DispatcherType dt : dTypes)
+ {
+ filter.dispatcher[index++] = dt.name();
+ }
+ filter.initParams = new HashMap<String, String>(((FilterInfo)info).getInitParameters());
+ filter.name = ((FilterInfo)info).getName();
+ filter.patterns = toStringArray(((FilterInfo)info).getPatterns());
+ filter.regexs = toStringArray(((FilterInfo)info).getRegexs());
+ filter.serviceId = info.getServiceId();
+ filter.servletContextId = handler.getContextInfo().getServiceId();
+ filter.servletNames = toStringArray(((FilterInfo)info).getServletNames());
+ }
+ }
+ dto.errorPageDTOs = errorPages.toArray(new ErrorPageDTO[errorPages.size()]);
+ dto.filterDTOs = filters.toArray(new FilterDTO[filters.size()]);
+ dto.resourceDTOs = resources.toArray(new ResourceDTO[resources.size()]);
+ dto.servletDTOs = servlets.toArray(new ServletDTO[servlets.size()]);
+
dto.listenerDTOs = new ListenerDTO[0]; // TODO
- dto.resourceDTOs = new ResourceDTO[0]; // TODO
- dto.servletDTOs = new ServletDTO[0]; // TODO
}
finally
{
@@ -378,4 +452,13 @@
return null;
}
+ private static final String[] EMPTY_ARRAY = new String[0];
+ private String[] toStringArray(final String[] array)
+ {
+ if ( array == null )
+ {
+ return EMPTY_ARRAY;
+ }
+ return array;
+ }
}