Bug 486412 - [http whiteboard] Implement better equality (merged from squashed master impl)
Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java
index 2513922..9624f30 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/ServletTest.java
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Raymond Augé <raymond.auge@liferay.com> - Bug 436698
+ * Juan Gonzalez <juan.gonzalez@liferay.com> - Bug 486412
*******************************************************************************/
package org.eclipse.equinox.http.servlet.tests;
@@ -2794,7 +2795,56 @@
}
}
}
-
+
+ public void test_Listener10() throws Exception {
+ BaseServletContextListener scl1 = new BaseServletContextListener();
+ BaseServletContextListener scl2 = new BaseServletContextListener();
+ BaseServletContextListener scl3 = new BaseServletContextListener();
+
+ Dictionary<String, String> listenerProps = new Hashtable<String, String>();
+ listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
+ registrations.add(getBundleContext().registerService(ServletContextListener.class, scl1, listenerProps));
+
+ listenerProps = new Hashtable<String, String>();
+ listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
+ registrations.add(getBundleContext().registerService(ServletContextListener.class, scl2, listenerProps));
+
+ Dictionary<String, String> contextProps = new Hashtable<String, String>();
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
+ registrations.add(getBundleContext().registerService(ServletContextHelper.class, new ServletContextHelper(){}, contextProps));
+
+ listenerProps = new Hashtable<String, String>();
+ listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
+ listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
+ registrations.add(getBundleContext().registerService(ServletContextListener.class, scl3, listenerProps));
+
+ ServletContext servletContext1 = scl1.servletContext;
+ ServletContext servletContext2 = scl2.servletContext;
+ ServletContext servletContext3 = scl3.servletContext;
+
+ Assert.assertNotNull(servletContext1);
+ Assert.assertNotNull(servletContext2);
+ Assert.assertNotNull(servletContext3);
+
+ Assert.assertTrue(servletContext1.equals(servletContext1));
+ Assert.assertTrue(servletContext2.equals(servletContext2));
+ Assert.assertTrue(servletContext3.equals(servletContext3));
+
+ Assert.assertTrue(servletContext1.equals(servletContext2));
+ Assert.assertFalse(servletContext1.equals(servletContext3));
+ Assert.assertFalse(servletContext2.equals(servletContext3));
+
+ // Asserts two invocations return the same value
+ Assert.assertEquals(servletContext1.hashCode(), servletContext1.hashCode());
+ Assert.assertEquals(servletContext2.hashCode(), servletContext2.hashCode());
+ Assert.assertEquals(servletContext3.hashCode(), servletContext3.hashCode());
+
+ Assert.assertEquals(servletContext1.hashCode(), servletContext2.hashCode());
+ Assert.assertNotEquals(servletContext1.hashCode(), servletContext3.hashCode());
+ Assert.assertNotEquals(servletContext2.hashCode(), servletContext3.hashCode());
+ }
+
public void test_Async1() throws Exception {
Servlet s1 = new BaseAsyncServlet("test_Listener8");
diff --git a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/BaseServletContextListener.java b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/BaseServletContextListener.java
index f5bdfa8..d022513 100644
--- a/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/BaseServletContextListener.java
+++ b/bundles/org.eclipse.equinox.http.servlet.tests/src/org/eclipse/equinox/http/servlet/tests/util/BaseServletContextListener.java
@@ -1,28 +1,31 @@
/*******************************************************************************
- * Copyright (c) 2014 Raymond Augé and others.
+ * Copyright (c) 2016 Raymond Augé and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Raymond Augé <raymond.auge@liferay.com> - Bug 436698
+ * Raymond Augé <raymond.auge@liferay.com> - Bug 436698
+ * Juan Gonzalez <juan.gonzalez@liferay.com> - Bug 486412
******************************************************************************/
package org.eclipse.equinox.http.servlet.tests.util;
import java.util.concurrent.atomic.AtomicBoolean;
+import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
- * @author Raymond Augé
+ * @author Raymond Augé
*/
public class BaseServletContextListener implements ServletContextListener {
public AtomicBoolean initialized = new AtomicBoolean(false);
public AtomicBoolean destroyed = new AtomicBoolean(false);
+ public ServletContext servletContext;
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
@@ -32,6 +35,7 @@
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
initialized.set(true);
+ servletContext = servletContextEvent.getServletContext();
}
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java
index 2dc9697..66d2a49 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/servlet/ServletContextAdaptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 Cognos Incorporated, IBM Corporation and others.
+ * Copyright (c) 2005, 2016 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -9,6 +9,7 @@
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Raymond Augé <raymond.auge@liferay.com> - Bug 436698
+ * Juan Gonzalez <juan.gonzalez@liferay.com> - Bug 486412
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal.servlet;
@@ -54,6 +55,19 @@
}
}
+ try {
+ Method equalsMethod = Object.class.getMethod("equals", Object.class); //$NON-NLS-1$
+ Method equalsHandlerMethod = ServletContextAdaptor.class.getMethod("equals", Object.class); //$NON-NLS-1$
+ methods.put(equalsMethod, equalsHandlerMethod);
+
+ Method hashCodeMethod = Object.class.getMethod("hashCode", (Class<?>[])null); //$NON-NLS-1$
+ Method hashCodeHandlerMethod = ServletContextAdaptor.class.getMethod("hashCode", (Class<?>[])null); //$NON-NLS-1$
+ methods.put(hashCodeMethod, hashCodeHandlerMethod);
+ }
+ catch (NoSuchMethodException e) {
+ // do nothing
+ }
+
return methods;
}
@@ -80,10 +94,29 @@
Class<?> clazz = getClass();
ClassLoader curClassLoader = clazz.getClassLoader();
Class<?>[] interfaces = new Class[] {ServletContext.class};
- InvocationHandler invocationHandler = createInvocationHandler();
return (ServletContext)Proxy.newProxyInstance(
- curClassLoader, interfaces, invocationHandler);
+ curClassLoader, interfaces, new AdaptorInvocationHandler());
+ }
+
+ public boolean equals (Object obj) {
+ if (!(obj instanceof ServletContext)) {
+ return false;
+ }
+
+ if (!(Proxy.isProxyClass(obj.getClass()))) {
+ return false;
+ }
+
+ InvocationHandler invocationHandler = Proxy.getInvocationHandler(obj);
+
+ if (!(invocationHandler instanceof AdaptorInvocationHandler)) {
+ return false;
+ }
+
+ AdaptorInvocationHandler adaptorInvocationHandler = (AdaptorInvocationHandler)invocationHandler;
+
+ return contextController.equals(adaptorInvocationHandler.getContextController());
}
public ClassLoader getClassLoader() {
@@ -243,6 +276,10 @@
return contextName;
}
+ public int hashCode() {
+ return contextController.hashCode();
+ }
+
public void removeAttribute(String attributeName) {
Dictionary<String, Object> attributes = getContextAttributes();
Object attributeValue = attributes.remove(attributeName);
@@ -361,24 +398,28 @@
}
}
- private InvocationHandler createInvocationHandler() {
- return new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
-
- return ServletContextAdaptor.this.invoke(proxy, method, args);
- }
- };
- }
-
private Dictionary<String, Object> getContextAttributes() {
return proxyContext.getContextAttributes(contextController);
}
+ private class AdaptorInvocationHandler implements InvocationHandler {
+ public AdaptorInvocationHandler() {}
+
+ public ContextController getContextController() {
+ return contextController;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ return ServletContextAdaptor.this.invoke(proxy, method, args);
+ }
+ }
+
private final AccessControlContext acc;
private final Bundle bundle;
private final ClassLoader classLoader;
- private final ContextController contextController;
+ final ContextController contextController;
private final String contextName;
private final EventListeners eventListeners;
private final ProxyContext proxyContext;