Bug 325064 - Handlers registered w/ topic a/b/c/* should not receive events on topic a/b/c
diff --git a/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/compendium/tests/AllTests.java b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/compendium/tests/AllTests.java
index c7962a5..b2aeee9 100644
--- a/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/compendium/tests/AllTests.java
+++ b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/compendium/tests/AllTests.java
@@ -19,6 +19,7 @@
TestSuite suite = new TestSuite("Tests for Equinox Compendium"); //$NON-NLS-1$
suite.addTest(org.eclipse.equinox.metatype.tests.AllTests.suite());
suite.addTest(org.eclipse.equinox.useradmin.tests.AllTests.suite());
+ suite.addTest(org.eclipse.equinox.event.tests.AllTests.suite());
return suite;
}
diff --git a/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/AllTests.java b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/AllTests.java
new file mode 100644
index 0000000..274e981
--- /dev/null
+++ b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/AllTests.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.event.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Tests for Equinox EventAdmin"); //$NON-NLS-1$
+ suite.addTestSuite(EventAdminTest.class);
+ return suite;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/EventAdminTest.java b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/EventAdminTest.java
new file mode 100644
index 0000000..2da46fb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/EventAdminTest.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.event.tests;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import junit.framework.TestCase;
+import org.eclipse.equinox.compendium.tests.Activator;
+import org.osgi.framework.*;
+import org.osgi.service.event.*;
+
+public class EventAdminTest extends TestCase {
+ private EventAdmin eventAdmin;
+ private ServiceReference eventAdminReference;
+
+ protected void setUp() throws Exception {
+ Activator.getBundle(Activator.BUNDLE_EVENT).start();
+ eventAdminReference = Activator.getBundleContext().getServiceReference(EventAdmin.class.getName());
+ eventAdmin = (EventAdmin) Activator.getBundleContext().getService(eventAdminReference);
+ }
+
+ protected void tearDown() throws Exception {
+ Activator.getBundleContext().ungetService(eventAdminReference);
+ Activator.getBundle(Activator.BUNDLE_EVENT).stop();
+ }
+
+ /*
+ * Ensures EventAdmin does not deliver an event published on topic "a/b/c"
+ * to an EventHandler listening to topic a/b/c/*.
+ *
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=325064.
+ */
+ public void testEventDeliveryForWildcardTopic1() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, "a/b/c/*"); //$NON-NLS-1$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a/b/c", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNull("Received event published to topic 'a/b/c' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+
+ /*
+ * Ensures EventAdmin does not deliver an event published on topic "a/b" to
+ * an EventHandler listening to topic a/b/c/*.
+ */
+ public void testEventDeliveryForWildcardTopic2() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, "a/b/c/*"); //$NON-NLS-1$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a/b", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNull("Received event published to topic 'a/b' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+
+ /*
+ * Ensures EventAdmin does not deliver an event published on topic "a" to
+ * an EventHandler listening to topic a/b/c/*.
+ */
+ public void testEventDeliveryForWildcardTopic3() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, "a/b/c/*"); //$NON-NLS-1$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNull("Received event published to topic 'a' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+
+ /*
+ * Ensures EventAdmin delivers an event published on topic "a/b/c/d" to an
+ * EventHandler listening to topic "a/b/c/*".
+ */
+ public void testEventDeliveryForWildcardTopic4() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, "a/b/c/*"); //$NON-NLS-1$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a/b/c/d", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNotNull("Did not receive event published to topic 'a/b/c/d' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+
+ /*
+ * Ensures EventAdmin delivers an event published on topic "a/b/c/d/e" to
+ * an EventHandler listening to topic "a/b/c/*".
+ */
+ public void testEventDeliveryForWildcardTopic5() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, "a/b/c/*"); //$NON-NLS-1$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a/b/c/d/e", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNotNull("Did not receive event published to topic 'a/b/c/d/e' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+
+ /*
+ * Ensures EventAdmin delivers an event published on topic "a/b/c/d/e/f" to
+ * an EventHandler listening to topic "a/b/c/*".
+ */
+ public void testEventDeliveryForWildcardTopic6() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, "a/b/c/*"); //$NON-NLS-1$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a/b/c/d/e/f", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNotNull("Did not receive event published to topic 'a/b/c/d/e/f' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+
+ /*
+ * Ensures EventAdmin delivers an event published to topics "a/b/c" and
+ * "a/b/c/d" to an EventHandler listening to topics "a/b/c" and "a/b/c/*".
+ *
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=325064.
+ */
+ public void testEventDeliveryForWildcardTopic7() {
+ Dictionary properties = new Hashtable();
+ properties.put(EventConstants.EVENT_TOPIC, new String[] {"a/b/c", "a/b/c/*"}); //$NON-NLS-1$ //$NON-NLS-2$
+ BundleContext bundleContext = Activator.getBundleContext();
+ EventHandlerHelper handler = new EventHandlerHelper();
+ ServiceRegistration handlerRegistration = bundleContext.registerService(EventHandler.class, handler, properties);
+ Event event = new Event("a/b/c", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNotNull("Did not receive event published to topic 'a/b/c' while listening to 'a/b/c'", handler.clearLastEvent()); //$NON-NLS-1$
+ event = new Event("a/b/c/d", (Dictionary) null); //$NON-NLS-1$
+ eventAdmin.sendEvent(event);
+ assertNotNull("Did not receive event published to topic 'a/b/c/d' while listening to 'a/b/c/*'", handler.lastEvent()); //$NON-NLS-1$
+ handlerRegistration.unregister();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/EventHandlerHelper.java b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/EventHandlerHelper.java
new file mode 100644
index 0000000..e9b4e08
--- /dev/null
+++ b/bundles/org.eclipse.equinox.compendium.tests/src/org/eclipse/equinox/event/tests/EventHandlerHelper.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.event.tests;
+
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+public class EventHandlerHelper implements EventHandler {
+ private volatile Event lastEvent;
+
+ public Event clearLastEvent() {
+ Event result = lastEvent;
+ lastEvent = null;
+ return result;
+ }
+
+ public void handleEvent(Event event) {
+ lastEvent = event;
+ }
+
+ public Event lastEvent() {
+ return lastEvent;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.event/.settings/org.eclipse.pde.api.tools.prefs b/bundles/org.eclipse.equinox.event/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..ceb4af0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.event/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,94 @@
+#Fri Oct 22 19:46:45 EDT 2010
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+invalid_since_tag_version=Error
+LEAK_METHOD_RETURN_TYPE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+ILLEGAL_INSTANTIATE=Warning
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ILLEGAL_IMPLEMENT=Warning
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+LEAK_EXTEND=Warning
+INVALID_JAVADOC_TAG=Ignore
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+ILLEGAL_REFERENCE=Warning
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+LEAK_METHOD_PARAM=Warning
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+incompatible_api_component_version=Error
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ILLEGAL_OVERRIDE=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+malformed_since_tag=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+automatically_removed_unused_problem_filters=false
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+report_api_breakage_when_major_version_incremented=Disabled
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+eclipse.preferences.version=1
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+missing_since_tag=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+UNUSED_PROBLEM_FILTERS=Warning
+ILLEGAL_EXTEND=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+LEAK_FIELD_DECL=Warning
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+LEAK_IMPLEMENT=Warning
+report_resolution_errors_api_component=Warning
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
diff --git a/bundles/org.eclipse.equinox.event/src/org/eclipse/equinox/internal/event/EventHandlerTracker.java b/bundles/org.eclipse.equinox.event/src/org/eclipse/equinox/internal/event/EventHandlerTracker.java
index 91d6bb3..23bb0ba 100644
--- a/bundles/org.eclipse.equinox.event/src/org/eclipse/equinox/internal/event/EventHandlerTracker.java
+++ b/bundles/org.eclipse.equinox.event/src/org/eclipse/equinox/internal/event/EventHandlerTracker.java
@@ -161,9 +161,9 @@
// Add the handlers with partial matches
if (partialWildcard.size() > 0) {
- int index = topic.length();
+ int index = topic.lastIndexOf('/');
while (index >= 0) {
- String subTopic = topic.substring(0, index); // First subtopic is the complete topic.
+ String subTopic = topic.substring(0, index);
List<EventHandlerWrapper> wrappers = partialWildcard.get(subTopic);
if (wrappers != null) {
handlers.addAll(wrappers);