FELIX-4781 : Implement various listeners
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1659618 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java b/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java
index ef9f9a0..95e0743 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java
@@ -19,6 +19,8 @@
import java.io.IOException;
import javax.servlet.ServletContext;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionAttributeListener;
@@ -31,4 +33,8 @@
HttpSessionAttributeListener getHttpSessionAttributeListener();
HttpSessionListener getHttpSessionListener();
+
+ ServletRequestListener getServletRequestListener();
+
+ ServletRequestAttributeListener getServletRequestAttributeListener();
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java
index 23b1a24..2f8d866 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java
@@ -36,6 +36,8 @@
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
@@ -394,6 +396,18 @@
}
@Override
+ public ServletRequestListener getServletRequestListener()
+ {
+ return null;
+ }
+
+ @Override
+ public ServletRequestAttributeListener getServletRequestAttributeListener()
+ {
+ return null;
+ }
+
+ @Override
public boolean handleSecurity(HttpServletRequest req, HttpServletResponse res) throws IOException
{
return this.httpContext.handleSecurity(req, res);
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 c657215..b322bdc 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
@@ -40,6 +40,8 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
@@ -475,6 +477,41 @@
}
@Override
+ public void setAttribute(final String name, final Object value)
+ {
+ if ( value == null )
+ {
+ this.removeAttribute(name);
+ }
+ final Object oldValue = this.getAttribute(name);
+ super.setAttribute(name, value);
+ if ( this.servletContext.getServletRequestAttributeListener() != null )
+ {
+ if ( oldValue == null )
+ {
+ this.servletContext.getServletRequestAttributeListener().attributeAdded(new ServletRequestAttributeEvent(this.servletContext, this, name, value));
+ }
+ else
+ {
+ this.servletContext.getServletRequestAttributeListener().attributeReplaced(new ServletRequestAttributeEvent(this.servletContext, this, name, oldValue));
+ }
+ }
+ }
+
+ @Override
+ public void removeAttribute(final String name) {
+ final Object oldValue = this.getAttribute(name);
+ if ( oldValue != null )
+ {
+ super.removeAttribute(name);
+ if ( this.servletContext.getServletRequestAttributeListener() != null )
+ {
+ this.servletContext.getServletRequestAttributeListener().attributeRemoved(new ServletRequestAttributeEvent(this.servletContext, this, name, oldValue));
+ }
+ }
+ }
+
+ @Override
public String toString()
{
return getClass().getSimpleName() + "->" + super.getRequest();
@@ -574,10 +611,15 @@
ExtServletContext servletContext = (servletHandler != null) ? servletHandler.getContext() : null;
RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString);
+ final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, servletHandler.getContextServiceId());
+ final FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, req.getDispatcherType(), requestURI);
+
try
{
- final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, servletHandler.getContextServiceId());
- final FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, req.getDispatcherType(), requestURI);
+ if ( servletContext.getServletRequestListener() != null )
+ {
+ servletContext.getServletRequestListener().requestInitialized(new ServletRequestEvent(servletContext, wrappedRequest));
+ }
invokeChain(filterHandlers, servletHandler, wrappedRequest, wrappedResponse);
}
catch ( final Exception e)
@@ -587,6 +629,13 @@
wrappedResponse.sendError(500);
}
+ finally
+ {
+ if ( servletContext.getServletRequestListener() != null )
+ {
+ servletContext.getServletRequestListener().requestDestroyed(new ServletRequestEvent(servletContext, wrappedRequest));
+ }
+ }
}
@Override
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
index 346c53c..3926bae 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
@@ -393,6 +393,12 @@
public void setAttribute(final String name, final Object value)
{
this.checkInvalid();
+ if ( value == null )
+ {
+ this.removeAttribute(name);
+ return;
+ }
+
final Object oldValue = this.getAttribute(name);
// wrap http session binding listener to avoid container calling it!
if ( this.keyPrefix != null && value instanceof HttpSessionBindingListener )
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 af5bc80..f89186f 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
@@ -26,6 +26,10 @@
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
@@ -37,6 +41,8 @@
import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
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.osgi.framework.Bundle;
import org.osgi.framework.ServiceObjects;
import org.osgi.framework.ServiceReference;
@@ -68,6 +74,14 @@
private final Map<ServiceReference<HttpSessionListener>, HttpSessionListener> sessionListeners =
new ConcurrentSkipListMap<ServiceReference<HttpSessionListener>, HttpSessionListener>();
+ /** Request listeners. */
+ private final Map<ServiceReference<ServletRequestListener>, ServletRequestListener> requestListeners =
+ new ConcurrentSkipListMap<ServiceReference<ServletRequestListener>, ServletRequestListener>();
+
+ /** Request attribute listeners. */
+ private final Map<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener> requestAttributeListeners =
+ new ConcurrentSkipListMap<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener>();
+
/** The http bundle. */
private final Bundle bundle;
@@ -168,7 +182,9 @@
this.sharedContext,
holder.servletContextHelper,
this.getSessionListener(),
- this.getSessionAttributeListener());
+ this.getSessionAttributeListener(),
+ this.getServletRequestListener(),
+ this.getServletRequestAttributeListener());
this.contextMap.put(key, holder);
}
}
@@ -299,6 +315,72 @@
}
}
+ /**
+ * Add request listener
+ * @param info
+ */
+ public void addListener(@Nonnull final ServletRequestListenerInfo info)
+ {
+ final ServiceObjects<ServletRequestListener> so = bundle.getBundleContext().getServiceObjects(info.getServiceReference());
+ if ( so != null )
+ {
+ final ServletRequestListener service = bundle.getBundleContext().getServiceObjects(info.getServiceReference()).getService();
+ if ( service != null )
+ {
+ this.requestListeners.put(info.getServiceReference(), service);
+ }
+ }
+ }
+
+ /**
+ * Remove request listener
+ * @param info
+ */
+ public void removeListener(@Nonnull final ServletRequestListenerInfo info)
+ {
+ final ServletRequestListener service = this.requestListeners.remove(info.getServiceReference());
+ if ( service != null )
+ {
+ final ServiceObjects<ServletRequestListener> so = bundle.getBundleContext().getServiceObjects(info.getServiceReference());
+ if ( so != null ) {
+ so.ungetService(service);
+ }
+ }
+ }
+
+ /**
+ * Add request attribute listener
+ * @param info
+ */
+ public void addListener(@Nonnull final ServletRequestAttributeListenerInfo info)
+ {
+ final ServiceObjects<ServletRequestAttributeListener> so = bundle.getBundleContext().getServiceObjects(info.getServiceReference());
+ if ( so != null )
+ {
+ final ServletRequestAttributeListener service = bundle.getBundleContext().getServiceObjects(info.getServiceReference()).getService();
+ if ( service != null )
+ {
+ this.requestAttributeListeners.put(info.getServiceReference(), service);
+ }
+ }
+ }
+
+ /**
+ * Remove request attribute listener
+ * @param info
+ */
+ public void removeListener(@Nonnull final ServletRequestAttributeListenerInfo info)
+ {
+ final ServletRequestAttributeListener service = this.requestAttributeListeners.remove(info.getServiceReference());
+ if ( service != null )
+ {
+ final ServiceObjects<ServletRequestAttributeListener> so = bundle.getBundleContext().getServiceObjects(info.getServiceReference());
+ if ( so != null ) {
+ so.ungetService(service);
+ }
+ }
+ }
+
private static final class ContextHolder
{
public long counter;
@@ -387,4 +469,56 @@
}
};
}
+
+ private ServletRequestListener getServletRequestListener()
+ {
+ return new ServletRequestListener() {
+
+ @Override
+ public void requestDestroyed(final ServletRequestEvent sre) {
+ for(final ServletRequestListener l : requestListeners.values())
+ {
+ l.requestDestroyed(sre);
+ }
+ }
+
+ @Override
+ public void requestInitialized(final ServletRequestEvent sre) {
+ for(final ServletRequestListener l : requestListeners.values())
+ {
+ l.requestInitialized(sre);
+ }
+ }
+ };
+ }
+
+ private ServletRequestAttributeListener getServletRequestAttributeListener()
+ {
+ return new ServletRequestAttributeListener() {
+
+ @Override
+ public void attributeAdded(final ServletRequestAttributeEvent srae) {
+ for(final ServletRequestAttributeListener l : requestAttributeListeners.values())
+ {
+ l.attributeAdded(srae);
+ }
+ }
+
+ @Override
+ public void attributeRemoved(final ServletRequestAttributeEvent srae) {
+ for(final ServletRequestAttributeListener l : requestAttributeListeners.values())
+ {
+ l.attributeRemoved(srae);
+ }
+ }
+
+ @Override
+ public void attributeReplaced(final ServletRequestAttributeEvent srae) {
+ for(final ServletRequestAttributeListener l : requestAttributeListeners.values())
+ {
+ l.attributeReplaced(srae);
+ }
+ }
+ };
+ }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java
index e64db90..c152ce7 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java
@@ -32,6 +32,8 @@
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;
@@ -58,18 +60,24 @@
private final ServletContextHelper contextHelper;
private final HttpSessionListener sessionListener;
private final HttpSessionAttributeListener sessionAttributeListener;
+ private final ServletRequestListener requestListener;
+ private final ServletRequestAttributeListener requestAttributeListener;
public PerBundleServletContextImpl(final Bundle bundle,
final ServletContext sharedContext,
final ServletContextHelper delegatee,
final HttpSessionListener sessionListener,
- final HttpSessionAttributeListener sessionAttributeListener)
+ final HttpSessionAttributeListener sessionAttributeListener,
+ final ServletRequestListener requestListener,
+ final ServletRequestAttributeListener requestAttributeListener)
{
this.bundle = bundle;
this.delegatee = sharedContext;
this.contextHelper = delegatee;
this.sessionListener = sessionListener;
this.sessionAttributeListener = sessionAttributeListener;
+ this.requestListener = requestListener;
+ this.requestAttributeListener = requestAttributeListener;
}
@Override
@@ -93,6 +101,18 @@
}
@Override
+ public ServletRequestListener getServletRequestListener()
+ {
+ return this.requestListener;
+ }
+
+ @Override
+ public ServletRequestAttributeListener getServletRequestAttributeListener()
+ {
+ return this.requestAttributeListener;
+ }
+
+ @Override
public ClassLoader getClassLoader()
{
return this.bundle.adapt(BundleWiring.class).getClassLoader();
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 2319dfe..7ea4967 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
@@ -40,6 +40,8 @@
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
+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.apache.felix.http.base.internal.util.MimeTypes;
import org.osgi.framework.Bundle;
@@ -393,6 +395,14 @@
{
handler.addListener((HttpSessionListenerInfo)info );
}
+ else if ( info instanceof ServletRequestListenerInfo )
+ {
+ handler.addListener((ServletRequestListenerInfo)info );
+ }
+ else if ( info instanceof ServletRequestAttributeListenerInfo )
+ {
+ handler.addListener((ServletRequestAttributeListenerInfo)info );
+ }
}
/**
@@ -426,6 +436,14 @@
{
handler.removeListener((HttpSessionListenerInfo)info );
}
+ else if ( info instanceof ServletRequestListenerInfo )
+ {
+ handler.removeListener((ServletRequestListenerInfo)info );
+ }
+ else if ( info instanceof ServletRequestAttributeListenerInfo )
+ {
+ handler.removeListener((ServletRequestAttributeListenerInfo)info );
+ }
}
/**