FELIX-4545 : Implement Servlet Context Helper
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1656012 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
index 64cc5a8..d19b424 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
@@ -39,9 +39,11 @@
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
+import org.apache.felix.http.base.internal.whiteboard.HttpContextBridge;
import org.osgi.framework.Bundle;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.NamespaceException;
+import org.osgi.service.http.context.ServletContextHelper;
public final class HttpServiceImpl implements ExtHttpService
{
@@ -187,17 +189,10 @@
}
/**
- * TODO As the servlet can be registered with multiple patterns
- * we shouldn't pass the servlet object around in order to
- * be able to get different instances (prototype scope).
- * Or we do the splitting into single pattern registrations
- * already before calling registerServlet()
- * @param servlet
- * @param servletInfo
- * @throws ServletException
- * @throws NamespaceException
*/
- public void registerServlet(final ServletInfo servletInfo)
+ public void registerServlet(final ServletContextHelper context,
+ final String prefix,
+ final ServletInfo servletInfo)
{
if (servletInfo == null)
{
@@ -208,6 +203,15 @@
throw new IllegalArgumentException("ServletInfo must at least have one pattern or error page!");
}
+ final ExtServletContext httpContext;
+ if ( context != null )
+ {
+ httpContext = getServletContext(new HttpContextBridge(context));
+ }
+ else
+ {
+ httpContext = getServletContext(servletInfo.getContext());
+ }
for(final String alias : servletInfo.getPatterns())
{
// create a handler for each alias
@@ -217,10 +221,11 @@
servlet = this.bundle.getBundleContext().getServiceObjects(servletInfo.getServiceReference()).getService();
// TODO - handle null
}
- final ServletHandler handler = new ServletHandler(getServletContext(servletInfo.getContext()),
+ final String pattern = (prefix == null ? alias : prefix + alias);
+ final ServletHandler handler = new ServletHandler(httpContext,
servletInfo,
servlet,
- alias);
+ pattern);
try {
this.handlerRegistry.addServlet(handler);
} catch (ServletException e) {
@@ -292,7 +297,7 @@
final ServletInfo info = new ServletInfo(null, alias, 0, paramMap, servlet, context);
- this.registerServlet(info);
+ this.registerServlet(null, null, info);
}
@Override
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/HttpContextBridge.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/HttpContextBridge.java
index 802ddd3..f4bb94c 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/HttpContextBridge.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/HttpContextBridge.java
@@ -29,7 +29,7 @@
private final ServletContextHelper delegatee;
- HttpContextBridge(final ServletContextHelper delegatee)
+ public HttpContextBridge(final ServletContextHelper delegatee)
{
this.delegatee = delegatee;
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
index 0c804b4..93d9498 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
@@ -20,10 +20,13 @@
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.felix.http.base.internal.runtime.AbstractInfo;
import org.apache.felix.http.base.internal.runtime.ContextInfo;
@@ -47,6 +50,7 @@
private final HttpServiceImpl httpService;
private final ServiceRegistration<ServletContextHelper> defaultContextRegistration;
+
/**
* Create a new servlet context helper manager
* and the default context
@@ -95,7 +99,7 @@
if ( entry.getKey().getContextSelectionFilter().match(holder.getInfo().getServiceReference()) )
{
entry.getValue().add(holder);
- this.httpService.registerServlet(entry.getKey());
+ this.registerServlet(entry.getKey(), holder);
}
}
}
@@ -108,7 +112,7 @@
final Map.Entry<ServletInfo, List<ContextHolder>> entry = i.next();
if ( entry.getValue().remove(holder) )
{
- this.httpService.unregisterServlet(entry.getKey());
+ this.unregisterServlet(entry.getKey(), holder);
if ( entry.getValue().isEmpty() ) {
i.remove();
}
@@ -199,6 +203,18 @@
return result;
}
+ private void registerServlet(final ServletInfo servletInfo, final ContextHolder holder)
+ {
+ final ServletContextHelper helper = holder.getContext(servletInfo.getServiceReference().getBundle());
+ String prefix = holder.getPrefix();
+ this.httpService.registerServlet(helper, prefix, servletInfo);
+ }
+
+ private void unregisterServlet(final ServletInfo servletInfo, final ContextHolder holder)
+ {
+ this.httpService.unregisterServlet(servletInfo);
+ }
+
/**
* Add a new servlet.
* @param servletInfo The servlet info
@@ -211,7 +227,7 @@
this.servletList.put(servletInfo, holderList);
for(final ContextHolder h : holderList)
{
- this.httpService.registerServlet(servletInfo);
+ this.registerServlet(servletInfo, h);
}
}
}
@@ -229,7 +245,7 @@
{
for(final ContextHolder h : holderList)
{
- this.httpService.unregisterServlet(servletInfo);
+ this.unregisterServlet(servletInfo, h);
}
}
}
@@ -242,9 +258,19 @@
{
private final ContextInfo info;
+ private final String prefix;
+
public ContextHolder(final ContextInfo info)
{
this.info = info;
+ if ( info.getPath().equals("/") )
+ {
+ prefix = null;
+ }
+ else
+ {
+ prefix = info.getPath().substring(0, info.getPath().length() - 1);
+ }
}
public ContextInfo getInfo()
@@ -252,11 +278,22 @@
return this.info;
}
+ public String getPrefix()
+ {
+ return this.prefix;
+ }
+
@Override
public int compareTo(final ContextHolder o)
{
return this.info.compareTo(o.info);
}
+
+ public ServletContextHelper getContext(final Bundle b)
+ {
+ // TODO - we should somehow keep track of these objects to later on dispose them
+ return b.getBundleContext().getServiceObjects(this.info.getServiceReference()).getService();
+ }
}
}