FELIX-4060 : Implement HTTP Service Update (RFC-189) - unify request and request attribute listener handling
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1660112 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java b/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java
index 25c2722..40ece55 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java
@@ -19,29 +19,29 @@
import java.io.IOException;
import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import javax.servlet.ServletRequestAttributeEvent;
-import javax.servlet.ServletRequestEvent;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
-import org.apache.felix.http.base.internal.service.listener.ServletRequestAttributeListenerManager;
-import org.apache.felix.http.base.internal.service.listener.ServletRequestListenerManager;
-
+/**
+ * The dispatcher servlet is registered in the container.
+ *
+ * When {@link #init(ServletConfig)} is called, the Http services are registered
+ * and started, when {@link #destroy()} is called the services are stopped
+ * and unregistered.
+ */
public final class DispatcherServlet extends HttpServlet
{
private final HttpServiceController controller;
- public DispatcherServlet(HttpServiceController controller)
+ public DispatcherServlet(final HttpServiceController controller)
{
this.controller = controller;
}
@Override
- public void init(ServletConfig config) throws ServletException
+ public void init(final ServletConfig config) throws ServletException
{
super.init(config);
this.controller.register(getServletContext());
@@ -55,74 +55,9 @@
}
@Override
- protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+ protected void service(final HttpServletRequest req, final HttpServletResponse res)
+ throws ServletException, IOException
{
- ServletRequestListenerManager requestListener = this.controller.getRequestListener();
-
- final ServletRequestEvent sre = new ServletRequestEvent(getServletContext(), req);
- requestListener.requestInitialized(sre);
- try
- {
- req = new AttributeEventRequest(getServletContext(), this.controller.getRequestAttributeListener(), req);
- this.controller.getDispatcher().dispatch(req, res);
- }
- finally
- {
- requestListener.requestDestroyed(sre);
- }
- }
-
- private static class AttributeEventRequest extends HttpServletRequestWrapper
- {
- private final ServletContext servletContext;
- private final ServletRequestAttributeListenerManager listener;
-
- public AttributeEventRequest(ServletContext servletContext, ServletRequestAttributeListenerManager requestAttributeListener, HttpServletRequest request)
- {
- super(request);
- this.servletContext = servletContext;
- this.listener = requestAttributeListener;
- }
-
- @Override
- public void setAttribute(String name, Object value)
- {
- if (value == null)
- {
- this.removeAttribute(name);
- }
- else if (name != null)
- {
- Object oldValue = this.getAttribute(name);
- super.setAttribute(name, value);
-
- if (oldValue == null)
- {
- this.listener.attributeAdded(new ServletRequestAttributeEvent(this.servletContext, this, name, value));
- }
- else
- {
- this.listener.attributeReplaced(new ServletRequestAttributeEvent(this.servletContext, this, name, oldValue));
- }
- }
- }
-
- @Override
- public void removeAttribute(String name)
- {
- Object oldValue = this.getAttribute(name);
- super.removeAttribute(name);
-
- if (oldValue != null)
- {
- this.listener.attributeRemoved(new ServletRequestAttributeEvent(this.servletContext, this, name, oldValue));
- }
- }
-
- @Override
- public String toString()
- {
- return getClass().getSimpleName() + "->" + super.getRequest();
- }
+ this.controller.getDispatcher().dispatch(req, res);
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
index 7c0143e..14fa9c9 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
@@ -29,8 +29,6 @@
import org.apache.felix.http.base.internal.handler.HttpSessionWrapper;
import org.apache.felix.http.base.internal.service.HttpServiceFactory;
import org.apache.felix.http.base.internal.service.listener.ServletContextAttributeListenerManager;
-import org.apache.felix.http.base.internal.service.listener.ServletRequestAttributeListenerManager;
-import org.apache.felix.http.base.internal.service.listener.ServletRequestListenerManager;
import org.apache.felix.http.base.internal.whiteboard.WhiteboardHttpService;
import org.osgi.framework.BundleContext;
@@ -63,16 +61,6 @@
return this.httpServiceFactory.getContextAttributeListener();
}
- ServletRequestListenerManager getRequestListener()
- {
- return this.httpServiceFactory.getRequestListener();
- }
-
- ServletRequestAttributeListenerManager getRequestAttributeListener()
- {
- return this.httpServiceFactory.getRequestAttributeListener();
- }
-
HttpSessionListener getSessionListener()
{
return new HttpSessionListener() {
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
index 0a132c0..23d95ee 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
@@ -126,7 +126,9 @@
return new HttpServiceImpl(bundle, this.context,
this.handlerRegistry.getRegistry(null),
this.contextAttributeListenerManager,
- this.sharedContextAttributes);
+ this.sharedContextAttributes,
+ this.requestListenerManager,
+ this.requestAttributeListenerManager);
}
@Override
@@ -144,16 +146,6 @@
return contextAttributeListenerManager;
}
- public ServletRequestListenerManager getRequestListener()
- {
- return requestListenerManager;
- }
-
- public ServletRequestAttributeListenerManager getRequestAttributeListener()
- {
- return requestAttributeListenerManager;
- }
-
public HttpSessionListener getSessionListener()
{
return sessionListenerManager;
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 30b3172..22d2438 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
@@ -29,6 +29,8 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
import org.apache.felix.http.api.ExtHttpService;
import org.apache.felix.http.base.internal.context.ExtServletContext;
@@ -51,12 +53,20 @@
private final ServletContextManager contextManager;
private final Map<String, ServletHandler> aliasMap = new HashMap<String, ServletHandler>();
-
- public HttpServiceImpl(Bundle bundle, ServletContext context, PerContextHandlerRegistry handlerRegistry, ServletContextAttributeListener servletAttributeListener, boolean sharedContextAttributes)
+
+ public HttpServiceImpl(final Bundle bundle,
+ final ServletContext context,
+ final PerContextHandlerRegistry handlerRegistry,
+ final ServletContextAttributeListener servletAttributeListener,
+ final boolean sharedContextAttributes,
+ final ServletRequestListener reqListener,
+ final ServletRequestAttributeListener reqAttrListener)
{
this.bundle = bundle;
this.handlerRegistry = handlerRegistry;
- this.contextManager = new ServletContextManager(this.bundle, context, servletAttributeListener, sharedContextAttributes);
+ this.contextManager = new ServletContextManager(this.bundle, context,
+ servletAttributeListener, sharedContextAttributes,
+ reqListener, reqAttrListener);
}
@Override
@@ -173,17 +183,17 @@
servletInfo,
servlet);
- synchronized ( this.aliasMap )
+ synchronized ( this.aliasMap )
{
- if ( this.aliasMap.containsKey(alias) )
+ if ( this.aliasMap.containsKey(alias) )
{
- throw new NamespaceException("Alias " + alias + " is already in use.");
+ throw new NamespaceException("Alias " + alias + " is already in use.");
}
if ( this.localServlets.contains(servlet) )
{
- throw new ServletException("Servlet instance " + handler.getName() + " already registered");
+ throw new ServletException("Servlet instance " + handler.getName() + " already registered");
}
-
+
this.handlerRegistry.addServlet(handler);
this.aliasMap.put(alias, handler);
@@ -197,12 +207,12 @@
@Override
public void unregister(final String alias)
{
- synchronized ( this.aliasMap )
+ synchronized ( this.aliasMap )
{
- final ServletHandler handler = this.aliasMap.remove(alias);
+ final ServletHandler handler = this.aliasMap.remove(alias);
if ( handler == null )
{
- throw new IllegalArgumentException("Nothing registered at " + alias);
+ throw new IllegalArgumentException("Nothing registered at " + alias);
}
final Servlet servlet = this.handlerRegistry.removeServlet(handler.getServletInfo(), true);
if (servlet != null)
@@ -263,7 +273,7 @@
i.remove();
break;
}
-
+
}
this.localServlets.remove(servlet);
}
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 5b53585..1871bcf 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
@@ -60,14 +60,30 @@
private final HttpContext httpContext;
private final Map<String, Object> attributes;
private final ServletContextAttributeListener attributeListener;
+ private final HttpSessionAttributeListener httpSessionAttributeListener;
+ private final HttpSessionListener httpSessionListener;
+ private final ServletRequestListener servletRequestListener;
+ private final ServletRequestAttributeListener servletRequestAttributeListener;
- public ServletContextImpl(Bundle bundle, ServletContext context, HttpContext httpContext, ServletContextAttributeListener attributeListener, boolean sharedAttributes)
+ public ServletContextImpl(final Bundle bundle,
+ final ServletContext context,
+ final HttpContext httpContext,
+ final ServletContextAttributeListener attributeListener,
+ final boolean sharedAttributes,
+ final HttpSessionAttributeListener httpSessionAttributeListener,
+ final HttpSessionListener httpSessionListener,
+ final ServletRequestListener servletRequestListener,
+ final ServletRequestAttributeListener servletRequestAttributeListener)
{
this.bundle = bundle;
this.context = context;
this.httpContext = httpContext;
this.attributeListener = attributeListener;
this.attributes = sharedAttributes ? null : new ConcurrentHashMap<String, Object>();
+ this.httpSessionAttributeListener = httpSessionAttributeListener;
+ this.httpSessionListener = httpSessionListener;
+ this.servletRequestAttributeListener = servletRequestAttributeListener;
+ this.servletRequestListener = servletRequestListener;
}
@Override
@@ -377,25 +393,25 @@
@Override
public HttpSessionListener getHttpSessionListener()
{
- return null;
+ return this.httpSessionListener;
}
@Override
public HttpSessionAttributeListener getHttpSessionAttributeListener()
{
- return null;
+ return this.httpSessionAttributeListener;
}
@Override
public ServletRequestListener getServletRequestListener()
{
- return null;
+ return this.servletRequestListener;
}
@Override
public ServletRequestAttributeListener getServletRequestAttributeListener()
{
- return null;
+ return this.servletRequestAttributeListener;
}
@Override
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextManager.java
index 322c949..bfa50f0 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextManager.java
@@ -21,6 +21,8 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.osgi.framework.Bundle;
@@ -33,15 +35,25 @@
private final ServletContextAttributeListener attributeListener;
private final Map<HttpContext, ExtServletContext> contextMap;
private final boolean sharedAttributes;
+ private final ServletRequestListener servletRequestListener;
+ private final ServletRequestAttributeListener servletRequestAttributeListener;
- public ServletContextManager(Bundle bundle, ServletContext context, ServletContextAttributeListener attributeListener, boolean sharedAttributes)
+ public ServletContextManager(
+ final Bundle bundle,
+ final ServletContext context,
+ final ServletContextAttributeListener attributeListener,
+ final boolean sharedAttributes,
+ final ServletRequestListener servletRequestListener,
+ final ServletRequestAttributeListener servletRequestAttributeListener)
{
this.bundle = bundle;
this.context = context;
this.attributeListener = attributeListener;
- // FELIX-4424 : avoid classloader leakage through HttpContext, for now this is sufficient,
- // the real fix should be to remove ExtServletContext's when the usage count of HttpContext
- // drops to zero.
+ this.servletRequestAttributeListener = servletRequestAttributeListener;
+ this.servletRequestListener = servletRequestListener;
+ // FELIX-4424 : avoid classloader leakage through HttpContext, for now this is sufficient,
+ // the real fix should be to remove ExtServletContext's when the usage count of HttpContext
+ // drops to zero.
this.contextMap = new WeakHashMap<HttpContext, ExtServletContext>();
this.sharedAttributes = sharedAttributes;
}
@@ -62,7 +74,15 @@
private ExtServletContext addServletContext(HttpContext httpContext)
{
- ExtServletContext context = new ServletContextImpl(this.bundle, this.context, httpContext, this.attributeListener, this.sharedAttributes);
+ ExtServletContext context = new ServletContextImpl(this.bundle,
+ this.context,
+ httpContext,
+ this.attributeListener,
+ this.sharedAttributes,
+ null,
+ null,
+ servletRequestListener,
+ servletRequestAttributeListener);
this.contextMap.put(httpContext, context);
return context;
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestAttributeListenerManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestAttributeListenerManager.java
index 856e5cd..29d83be 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestAttributeListenerManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestAttributeListenerManager.java
@@ -32,7 +32,9 @@
* interfaces forwarding any event calls to registered OSGi services
* implementing the respective Servlet API 2.4 listener interface.
*/
-public class ServletRequestAttributeListenerManager extends AbstractListenerManager<ServletRequestAttributeListener>
+public class ServletRequestAttributeListenerManager
+ extends AbstractListenerManager<ServletRequestAttributeListener>
+ implements ServletRequestAttributeListener
{
private static org.osgi.framework.Filter createFilter(final BundleContext btx)
{
@@ -54,6 +56,7 @@
super(context, createFilter(context));
}
+ @Override
public void attributeAdded(final ServletRequestAttributeEvent srae)
{
final Iterator<ServletRequestAttributeListener> listeners = getContextListeners();
@@ -63,6 +66,7 @@
}
}
+ @Override
public void attributeRemoved(final ServletRequestAttributeEvent srae)
{
final Iterator<ServletRequestAttributeListener> listeners = getContextListeners();
@@ -72,6 +76,7 @@
}
}
+ @Override
public void attributeReplaced(final ServletRequestAttributeEvent srae)
{
final Iterator<ServletRequestAttributeListener> listeners = getContextListeners();
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestListenerManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestListenerManager.java
index 85c89fb..01a8916 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestListenerManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/listener/ServletRequestListenerManager.java
@@ -32,7 +32,9 @@
* interfaces forwarding any event calls to registered OSGi services
* implementing the respective Servlet API 2.4 listener interface.
*/
-public class ServletRequestListenerManager extends AbstractListenerManager<ServletRequestListener>
+public class ServletRequestListenerManager
+ extends AbstractListenerManager<ServletRequestListener>
+ implements ServletRequestListener
{
private static org.osgi.framework.Filter createFilter(final BundleContext btx)
{
@@ -54,6 +56,7 @@
super(context, createFilter(context));
}
+ @Override
public void requestDestroyed(final ServletRequestEvent sre)
{
final Iterator<ServletRequestListener> listeners = getContextListeners();
@@ -63,6 +66,7 @@
}
}
+ @Override
public void requestInitialized(final ServletRequestEvent sre)
{
final Iterator<ServletRequestListener> listeners = getContextListeners();