Bug 460720 - [http whiteboard] add support for Servlet 3.1 javax.servlet.http.HttpSessionIdListener as suggested by the draft spec
Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
diff --git a/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java b/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java
index 19b0800..542d2ef 100644
--- a/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java
+++ b/bundles/org.eclipse.equinox.http.jetty9/src/org/eclipse/equinox/http/jetty/internal/HttpServerManager.java
@@ -14,8 +14,12 @@
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.*;
import javax.servlet.*;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionIdListener;
import org.eclipse.equinox.http.jetty.JettyConstants;
import org.eclipse.equinox.http.jetty.JettyCustomizer;
import org.eclipse.equinox.http.servlet.HttpServiceServlet;
@@ -128,6 +132,13 @@
httpContext.addServlet(holder, "/*"); //$NON-NLS-1$
server.setHandler(httpContext);
+ SessionManager sessionManager = httpContext.getSessionHandler().getSessionManager();
+ try {
+ sessionManager.addEventListener((HttpSessionIdListener) holder.getServlet());
+ } catch (ServletException e) {
+ throw new ConfigurationException(pid, e.getMessage(), e);
+ }
+
try {
server.start();
} catch (Exception e) {
@@ -298,15 +309,23 @@
}
}
- public static class InternalHttpServiceServlet implements Servlet {
+ public static class InternalHttpServiceServlet implements HttpSessionIdListener, Servlet {
// private static final long serialVersionUID = 7477982882399972088L;
private Servlet httpServiceServlet = new HttpServiceServlet();
private ClassLoader contextLoader;
+ private Method method;
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER);
+ Class<?> clazz = httpServiceServlet.getClass();
+ try {
+ method = clazz.getMethod("sessionIdChanged", new Class<?>[] {String.class});
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+
Thread thread = Thread.currentThread();
ClassLoader current = thread.getContextClassLoader();
thread.setContextClassLoader(contextLoader);
@@ -347,6 +366,23 @@
public String getServletInfo() {
return httpServiceServlet.getServletInfo();
}
+
+ public void sessionIdChanged(HttpSessionEvent event, String oldSessionId) {
+ Thread thread = Thread.currentThread();
+ ClassLoader current = thread.getContextClassLoader();
+ thread.setContextClassLoader(contextLoader);
+ try {
+ method.invoke(httpServiceServlet, oldSessionId);
+ } catch (IllegalAccessException e) {
+ // not likely
+ } catch (IllegalArgumentException e) {
+ // not likely
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getCause());
+ } finally {
+ thread.setContextClassLoader(current);
+ }
+ }
}
// deleteDirectory is a convenience method to recursively delete a directory
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
index 3fb46fd..05bbc0c 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
@@ -54,7 +54,7 @@
this.servletServiceFilter = createServletFilter(consumingContext);
this.resourceServiceFilter = createResourceFilter(consumingContext);
this.filterServiceFilter = createFilterFilter(consumingContext);
- this.listenerServiceFilter = createListenerFilter(consumingContext);
+ this.listenerServiceFilter = createListenerFilter(consumingContext, parentServletContext);
this.parentServletContext = parentServletContext;
this.attributes = Collections.unmodifiableMap(attributes);
@@ -954,7 +954,7 @@
}
}
- private static org.osgi.framework.Filter createListenerFilter(BundleContext context) {
+ private static org.osgi.framework.Filter createListenerFilter(BundleContext context, ServletContext servletContext) {
StringBuilder sb = new StringBuilder();
sb.append("(&"); //$NON-NLS-1$
@@ -966,6 +966,11 @@
sb.append("(objectClass=").append(ServletRequestAttributeListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("(objectClass=").append(HttpSessionListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("(objectClass=").append(HttpSessionAttributeListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ if ((servletContext.getMajorVersion() >= 3) && (servletContext.getMinorVersion() > 0)) {
+ sb.append("(objectClass=").append(javax.servlet.http.HttpSessionIdListener.class.getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
sb.append(")"); //$NON-NLS-1$
sb.append(")"); //$NON-NLS-1$
@@ -1082,6 +1087,12 @@
failedServletDTOs.remove(serviceReference);
}
+ public void fireSessionIdChanged(String oldSessionId) {
+ for (ContextController contextController : controllerMap.values()) {
+ contextController.fireSessionIdChanged(oldSessionId);
+ }
+ }
+
private Map<String, Object> attributes;
private final String targetFilter;
private final ServiceRegistration<ServletContextHelper> defaultContextReg;
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
index bd10125..b706e46 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
@@ -1010,6 +1010,13 @@
classes.add(HttpSessionAttributeListener.class);
}
+ ServletContext servletContext = proxyContext.getServletContext();
+ if ((servletContext.getMajorVersion() >= 3) && (servletContext.getMinorVersion() > 0)) {
+ if (objectClassList.contains(javax.servlet.http.HttpSessionIdListener.class.getName())) {
+ classes.add(javax.servlet.http.HttpSessionIdListener.class);
+ }
+ }
+
return classes;
}
@@ -1056,6 +1063,30 @@
}
}
+ public void fireSessionIdChanged(String oldSessionId) {
+ ServletContext servletContext = proxyContext.getServletContext();
+ if ((servletContext.getMajorVersion() <= 3) && (servletContext.getMinorVersion() < 1)) {
+ return;
+ }
+
+ List<javax.servlet.http.HttpSessionIdListener> listeners = eventListeners.get(javax.servlet.http.HttpSessionIdListener.class);
+
+ if (listeners.isEmpty()) {
+ return;
+ }
+
+ Collection<HttpSessionAdaptor> currentActiveSessions;
+ synchronized (activeSessions) {
+ currentActiveSessions = new ArrayList<HttpSessionAdaptor>(activeSessions.values());
+ }
+ for (HttpSessionAdaptor httpSessionAdaptor : currentActiveSessions) {
+ HttpSessionEvent httpSessionEvent = new HttpSessionEvent(httpSessionAdaptor);
+ for (javax.servlet.http.HttpSessionIdListener listener : listeners) {
+ listener.sessionIdChanged(httpSessionEvent, oldSessionId);
+ }
+ }
+ }
+
public HttpSessionAdaptor getSessionAdaptor(
HttpSession session, ServletContext servletContext) {
boolean created = false;
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java
index cd68ca8..a21a040 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ProxyServlet.java
@@ -48,6 +48,10 @@
this.httpServiceRuntimeImpl = httpServiceRuntimeImpl;
}
+ public void sessionIdChanged(String oldSessionId) {
+ httpServiceRuntimeImpl.fireSessionIdChanged(oldSessionId);
+ }
+
/**
* @see HttpServlet#service(ServletRequest, ServletResponse)
*/