Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.common.tests/src/org/eclipse')
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/AllTests.java10
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdaptableTests.java28
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdapterManagerDynamicTest.java138
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerServiceTest.java195
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerTest.java294
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdaptable.java22
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapter.java20
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactory.java32
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactoryLoader.java65
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ContributorsTest.java178
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryDynamicTest.java157
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryStaticTest.java359
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/InputErrorTest.java147
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/MultiLanguageTest.java347
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/NamespaceTest.java116
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryListenerTest.java307
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryTests.java32
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/StaleObjects.java136
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/WaitingRegistryListener.java198
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/BaseExtensionRegistryRun.java117
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTest.java136
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTwoRegistriesTest.java103
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionRemoveTest.java204
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DuplicatePointsTest.java95
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/MergeContributionTest.java66
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/SimpleRegistryTests.java34
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/TokenAccessTest.java72
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExecutableExtensionTest.java80
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateEclipseTest.java59
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateTest.java106
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExeExtensionStrategy.java53
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExecutableRegistryObject.java39
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/HiddenLogRegistryStrategy.java79
-rw-r--r--bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/SimpleRegistryListener.java62
34 files changed, 4085 insertions, 1 deletions
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/AllTests.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/AllTests.java
index 3f9c9d143..9e7b920ef 100644
--- a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/AllTests.java
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/AllTests.java
@@ -13,12 +13,20 @@
*******************************************************************************/
package org.eclipse.equinox.common.tests;
+import org.eclipse.equinox.common.tests.adaptable.AdaptableTests;
+import org.eclipse.equinox.common.tests.registry.RegistryTests;
+import org.eclipse.equinox.common.tests.registry.simple.SimpleRegistryTests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-@SuiteClasses(RuntimeTests.class)
+@SuiteClasses({
+ RuntimeTests.class,
+ AdaptableTests.class,
+ RegistryTests.class,
+ SimpleRegistryTests.class
+})
public class AllTests {
// intentionally left blank
}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdaptableTests.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdaptableTests.java
new file mode 100644
index 000000000..92d59d933
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdaptableTests.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Julian Honnen
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Julian Honnen - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AdapterManagerDynamicTest.class,
+ IAdapterManagerServiceTest.class,
+ IAdapterManagerTest.class
+})
+public class AdaptableTests {
+ // intentionally left blank
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdapterManagerDynamicTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdapterManagerDynamicTest.java
new file mode 100644
index 000000000..2a24ba409
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/AdapterManagerDynamicTest.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+
+import org.eclipse.core.internal.runtime.AdapterManager;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.eclipse.equinox.common.tests.registry.WaitingRegistryListener;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Tests reaction of AdapterManager on addition and removal of adapters from
+ * the extension registry.
+ */
+public class AdapterManagerDynamicTest extends TestCase {
+
+ final private static int MAX_TIME_PER_BUNDLE = 10000; // maximum time to wait for bundle event in milliseconds
+
+ // Provided by bundle1; has an extension ID
+ private static final String BUNDLE1_TYPE_ID = "abc.SomethingElseA1";
+ // Provided by bundle1; has no extension ID
+ private static final String BUNDLE1_TYPE_NO_ID = "abc.SomethingElseA2";
+
+ // Provided by bundle2; has an extension ID
+ private static final String BUNDLE2_TYPE_ID = "abc.SomethingElseB1";
+ // Provided by bundle2; has no extension ID
+ private static final String BUNDLE2_TYPE_NO_ID = "abc.SomethingElseB2";
+
+ private IAdapterManager manager;
+
+ public AdapterManagerDynamicTest(String name) {
+ super(name);
+ }
+
+ public AdapterManagerDynamicTest() {
+ super("");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ manager = AdapterManager.getDefault();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ manager = null;
+ super.tearDown();
+ }
+
+ /**
+ * This test uses waiting listener for synchronization (events from bundle being
+ * installed or un-installed are not propagated right away).
+ */
+ public void testDynamicBundles() throws IOException, BundleException {
+
+ // check that adapters not available
+ TestAdaptable adaptable = new TestAdaptable();
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE1_TYPE_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE1_TYPE_NO_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE2_TYPE_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE2_TYPE_NO_ID));
+
+ Bundle bundle01 = null;
+ Bundle bundle02 = null;
+ WaitingRegistryListener listener = new WaitingRegistryListener();
+ listener.register("org.eclipse.core.runtime.adapters");
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle01 = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/adapters/dynamic/A");
+ bundle02 = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/adapters/dynamic/B");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01, bundle02});
+
+ // synchronization: listener should receive 2 groups of events
+ assertTrue(listener.waitFor(2, 2 * MAX_TIME_PER_BUNDLE) == 2);
+
+ // now has to have all 4 adapters
+ assertTrue(manager.hasAdapter(adaptable, BUNDLE1_TYPE_ID));
+ assertTrue(manager.hasAdapter(adaptable, BUNDLE1_TYPE_NO_ID));
+ assertTrue(manager.hasAdapter(adaptable, BUNDLE2_TYPE_ID));
+ assertTrue(manager.hasAdapter(adaptable, BUNDLE2_TYPE_NO_ID));
+
+ listener.reset();
+ bundle02.uninstall();
+ bundle02 = null;
+
+ // synchronization: listener should receive 1 group of events
+ assertTrue(listener.waitFor(1, MAX_TIME_PER_BUNDLE) == 1);
+
+ // now 2 installed; 2 not
+ assertTrue(manager.hasAdapter(adaptable, BUNDLE1_TYPE_ID));
+ assertTrue(manager.hasAdapter(adaptable, BUNDLE1_TYPE_NO_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE2_TYPE_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE2_TYPE_NO_ID));
+
+ listener.reset();
+ bundle01.uninstall();
+ bundle01 = null;
+
+ // synchronization: listener should receive 1 group of events
+ assertTrue(listener.waitFor(1, MAX_TIME_PER_BUNDLE) == 1);
+
+ // and all should be uninstalled again
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE1_TYPE_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE1_TYPE_NO_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE2_TYPE_ID));
+ assertFalse(manager.hasAdapter(adaptable, BUNDLE2_TYPE_NO_ID));
+
+ } finally {
+ listener.unregister();
+ // in case of exception in the process
+ if (bundle01 != null) {
+ bundle01.uninstall();
+ }
+ if (bundle02 != null) {
+ bundle02.uninstall();
+ }
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerServiceTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerServiceTest.java
new file mode 100644
index 000000000..950330a59
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerServiceTest.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Tests API on the IAdapterManager class accessed via an OSGi service.
+ *
+ * This class is a copy of IAdapterManagerTest modified to use an OSGi service
+ * instead of the Platform API.
+ */
+public class IAdapterManagerServiceTest extends TestCase {
+ private static final String NON_EXISTING = "com.does.not.Exist";
+ private static final String TEST_ADAPTER = "org.eclipse.equinox.common.tests.adaptable.TestAdapter";
+
+ private ServiceTracker<IAdapterManager, IAdapterManager> adapterManagerTracker;
+
+ public IAdapterManagerServiceTest(String name) {
+ super(name);
+ }
+
+ public IAdapterManagerServiceTest() {
+ super("");
+ }
+
+ /*
+ * Return the framework log service, if available.
+ */
+ public IAdapterManager getAdapterManager() {
+ if (adapterManagerTracker == null) {
+ BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ adapterManagerTracker = new ServiceTracker<>(context, IAdapterManager.class, null);
+ adapterManagerTracker.open();
+ }
+ return adapterManagerTracker.getService();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (adapterManagerTracker != null) {
+ adapterManagerTracker.close();
+ adapterManagerTracker = null;
+ }
+ super.tearDown();
+ }
+
+ /**
+ * Tests API method IAdapterManager.hasAdapter.
+ */
+ public void testHasAdapter() {
+ IAdapterManager manager = getAdapterManager();
+
+ TestAdaptable adaptable = new TestAdaptable();
+ //request non-existing adaptable
+ assertTrue("1.0", !manager.hasAdapter("", NON_EXISTING));
+
+ //request adapter that is in XML but has no registered factory
+ assertTrue("1.1", manager.hasAdapter(adaptable, TEST_ADAPTER));
+
+ //request adapter that is not in XML
+ assertTrue("1.2", !manager.hasAdapter(adaptable, "java.lang.String"));
+
+ //register an adapter factory that maps adaptables to strings
+ IAdapterFactory fac = new IAdapterFactory() {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == String.class) {
+ return adapterType.cast(adaptableObject.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {String.class};
+ }
+ };
+ manager.registerAdapters(fac, TestAdaptable.class);
+ try {
+ //request adapter for factory that we've just added
+ assertTrue("1.3", manager.hasAdapter(adaptable, "java.lang.String"));
+ } finally {
+ manager.unregisterAdapters(fac, TestAdaptable.class);
+ }
+
+ //request adapter that was unloaded
+ assertTrue("1.4", !manager.hasAdapter(adaptable, "java.lang.String"));
+ }
+
+ /**
+ * Tests API method IAdapterManager.getAdapter.
+ */
+ public void testGetAdapter() {
+ IAdapterManager manager = getAdapterManager();
+
+ TestAdaptable adaptable = new TestAdaptable();
+ //request non-existing adaptable
+ assertNull("1.0", manager.getAdapter("", NON_EXISTING));
+
+ //request adapter that is in XML but has no registered factory
+ Object result = manager.getAdapter(adaptable, TEST_ADAPTER);
+ assertTrue("1.1", result instanceof TestAdapter);
+
+ //request adapter that is not in XML
+ assertNull("1.2", manager.getAdapter(adaptable, "java.lang.String"));
+
+ //register an adapter factory that maps adaptables to strings
+ IAdapterFactory fac = new IAdapterFactory() {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == String.class) {
+ return adapterType.cast(adaptableObject.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {String.class};
+ }
+ };
+ manager.registerAdapters(fac, TestAdaptable.class);
+ try {
+ //request adapter for factory that we've just added
+ result = manager.getAdapter(adaptable, "java.lang.String");
+ assertTrue("1.3", result instanceof String);
+ } finally {
+ manager.unregisterAdapters(fac, TestAdaptable.class);
+ }
+ //request adapter that was unloaded
+ assertNull("1.4", manager.getAdapter(adaptable, "java.lang.String"));
+ }
+
+ /**
+ * Tests API method IAdapterManager.loadAdapter.
+ */
+ public void testLoadAdapter() {
+ IAdapterManager manager = getAdapterManager();
+
+ TestAdaptable adaptable = new TestAdaptable();
+ //request non-existing adaptable
+ assertNull("1.0", manager.loadAdapter("", NON_EXISTING));
+
+ //request adapter that is in XML but has no registered factory
+ Object result = manager.loadAdapter(adaptable, TEST_ADAPTER);
+ assertTrue("1.1", result instanceof TestAdapter);
+
+ //request adapter that is not in XML
+ assertNull("1.2", manager.loadAdapter(adaptable, "java.lang.String"));
+
+ //register an adapter factory that maps adaptables to strings
+ IAdapterFactory fac = new IAdapterFactory() {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == String.class) {
+ return adapterType.cast(adaptableObject.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {String.class};
+ }
+ };
+ manager.registerAdapters(fac, TestAdaptable.class);
+ try {
+ //request adapter for factory that we've just added
+ result = manager.loadAdapter(adaptable, "java.lang.String");
+ assertTrue("1.3", result instanceof String);
+ } finally {
+ manager.unregisterAdapters(fac, TestAdaptable.class);
+ }
+ //request adapter that was unloaded
+ assertNull("1.4", manager.loadAdapter(adaptable, "java.lang.String"));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerTest.java
new file mode 100644
index 000000000..07697e21f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/IAdapterManagerTest.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import junit.framework.TestCase;
+
+import org.eclipse.core.internal.runtime.AdapterManager;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Tests API on the IAdapterManager class.
+ */
+public class IAdapterManagerTest extends TestCase {
+ //following classes are for testComputeClassOrder
+ static interface C {
+ }
+
+ static interface D {
+ }
+
+ static interface M {
+ }
+
+ static interface N {
+ }
+
+ static interface O {
+ }
+
+ interface A extends M, N {
+ }
+
+ interface B extends O {
+ }
+
+ class Y implements C, D {
+ }
+
+ class X extends Y implements A, B {
+ }
+
+ private static final String NON_EXISTING = "com.does.not.Exist";
+ private static final String TEST_ADAPTER = "org.eclipse.equinox.common.tests.adaptable.TestAdapter";
+ private static final String TEST_ADAPTER_CL = "testAdapter.testUnknown";
+ private IAdapterManager manager;
+
+ public IAdapterManagerTest(String name) {
+ super(name);
+ }
+
+ public IAdapterManagerTest() {
+ super("");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ manager = AdapterManager.getDefault();
+ }
+
+ /**
+ * Tests API method IAdapterManager.hasAdapter.
+ */
+ public void testHasAdapter() {
+ TestAdaptable adaptable = new TestAdaptable();
+ //request non-existing adaptable
+ assertTrue("1.0", !manager.hasAdapter("", NON_EXISTING));
+
+ //request adapter that is in XML but has no registered factory
+ assertTrue("1.1", manager.hasAdapter(adaptable, TEST_ADAPTER));
+
+ //request adapter that is not in XML
+ assertTrue("1.2", !manager.hasAdapter(adaptable, "java.lang.String"));
+
+ //register an adapter factory that maps adaptables to strings
+ IAdapterFactory fac = new IAdapterFactory() {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == String.class) {
+ return adapterType.cast(adaptableObject.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {String.class};
+ }
+ };
+ manager.registerAdapters(fac, TestAdaptable.class);
+ try {
+ //request adapter for factory that we've just added
+ assertTrue("1.3", manager.hasAdapter(adaptable, "java.lang.String"));
+ } finally {
+ manager.unregisterAdapters(fac, TestAdaptable.class);
+ }
+
+ //request adapter that was unloaded
+ assertTrue("1.4", !manager.hasAdapter(adaptable, "java.lang.String"));
+ }
+
+ /**
+ * Tests API method IAdapterManager.getAdapter.
+ */
+ public void testGetAdapter() {
+ TestAdaptable adaptable = new TestAdaptable();
+ //request non-existing adaptable
+ assertNull("1.0", manager.getAdapter("", NON_EXISTING));
+
+ //request adapter that is in XML but has no registered factory
+ Object result = manager.getAdapter(adaptable, TEST_ADAPTER);
+ assertTrue("1.1", result instanceof TestAdapter);
+
+ //request adapter that is not in XML
+ assertNull("1.2", manager.getAdapter(adaptable, "java.lang.String"));
+
+ //register an adapter factory that maps adaptables to strings
+ IAdapterFactory fac = new IAdapterFactory() {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == String.class) {
+ return adapterType.cast(adaptableObject.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {String.class};
+ }
+ };
+ manager.registerAdapters(fac, TestAdaptable.class);
+ try {
+ //request adapter for factory that we've just added
+ result = manager.getAdapter(adaptable, "java.lang.String");
+ assertTrue("1.3", result instanceof String);
+ } finally {
+ manager.unregisterAdapters(fac, TestAdaptable.class);
+ }
+ //request adapter that was unloaded
+ assertNull("1.4", manager.getAdapter(adaptable, "java.lang.String"));
+ }
+
+ public void testGetAdapterNullArgs() {
+ TestAdaptable adaptable = new TestAdaptable();
+ try {
+ manager.getAdapter(adaptable, (Class<?>) null);
+ fail("1.0");
+ } catch (RuntimeException e) {
+ //expected
+ }
+ try {
+ manager.getAdapter(null, NON_EXISTING);
+ fail("1.0");
+ } catch (RuntimeException e) {
+ //expected
+ }
+
+ }
+
+ /**
+ * Tests API method IAdapterManager.loadAdapter.
+ */
+ public void testLoadAdapter() {
+ TestAdaptable adaptable = new TestAdaptable();
+ //request non-existing adaptable
+ assertNull("1.0", manager.loadAdapter("", NON_EXISTING));
+
+ //request adapter that is in XML but has no registered factory
+ Object result = manager.loadAdapter(adaptable, TEST_ADAPTER);
+ assertTrue("1.1", result instanceof TestAdapter);
+
+ //request adapter that is not in XML
+ assertNull("1.2", manager.loadAdapter(adaptable, "java.lang.String"));
+
+ //register an adapter factory that maps adaptables to strings
+ IAdapterFactory fac = new IAdapterFactory() {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == String.class) {
+ return adapterType.cast(adaptableObject.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {String.class};
+ }
+ };
+ manager.registerAdapters(fac, TestAdaptable.class);
+ try {
+ //request adapter for factory that we've just added
+ result = manager.loadAdapter(adaptable, "java.lang.String");
+ assertTrue("1.3", result instanceof String);
+ } finally {
+ manager.unregisterAdapters(fac, TestAdaptable.class);
+ }
+ //request adapter that was unloaded
+ assertNull("1.4", manager.loadAdapter(adaptable, "java.lang.String"));
+ }
+
+ /**
+ * Test adapting to classes not reachable by the default bundle class loader
+ * (bug 200068).
+ * NOTE: This test uses .class file compiled with 1.4 JRE. As a result,
+ * the test can not be run on pre-1.4 JRE.
+ */
+ public void testAdapterClassLoader() throws MalformedURLException, BundleException, IOException {
+ TestAdaptable adaptable = new TestAdaptable();
+ assertTrue(manager.hasAdapter(adaptable, TEST_ADAPTER_CL));
+ assertNull(manager.loadAdapter(adaptable, TEST_ADAPTER_CL));
+ Bundle bundle = null;
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/adapters/testAdapter_1.0.0");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle});
+
+ assertTrue(manager.hasAdapter(adaptable, TEST_ADAPTER_CL));
+ Object result = manager.loadAdapter(adaptable, TEST_ADAPTER_CL);
+ assertNotNull(result);
+ assertTrue(TEST_ADAPTER_CL.equals(result.getClass().getName()));
+ } finally {
+ if (bundle != null) {
+ bundle.uninstall();
+ }
+ }
+ }
+
+ /**
+ * Tests for {@link IAdapterManager#computeClassOrder(Class)}.
+ */
+ public void testComputeClassOrder() {
+ Class<?>[] expected = new Class[] { X.class, Y.class, Object.class, A.class, B.class, M.class, N.class, O.class,
+ C.class, D.class };
+ Class<?>[] actual = manager.computeClassOrder(X.class);
+ assertEquals("1.0", expected.length, actual.length);
+ for (int i = 0; i < actual.length; i++) {
+ assertEquals("1.1." + i, expected[i], actual[i]);
+ }
+ }
+
+ public void testFactoryViolatingContract() {
+ class Private {
+ }
+
+ IAdapterFactory fac = new IAdapterFactory() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == Private.class) {
+ // Cast below violates the contract of the factory
+ return (T) Boolean.FALSE;
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] { Private.class };
+ }
+ };
+ try {
+ manager.registerAdapters(fac, Private.class);
+ try {
+ manager.getAdapter(new Private(), Private.class);
+ fail("Should throw AssertionFailedException!");
+ } catch (AssertionFailedException e) {
+ assertTrue(e.getMessage().contains(fac.getClass().getName()));
+ assertTrue(e.getMessage().contains(Boolean.class.getName()));
+ assertTrue(e.getMessage().contains(Private.class.getName()));
+ }
+ } finally {
+ manager.unregisterAdapters(fac, Private.class);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdaptable.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdaptable.java
new file mode 100644
index 000000000..0ee28d631
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdaptable.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2012 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ * Used by IAdapterManagerTest
+ */
+public class TestAdaptable extends PlatformObject {
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapter.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapter.java
new file mode 100644
index 000000000..9fff0ebea
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapter.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2012 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+/**
+ * Used by IAdapterManagerTest
+ */
+public class TestAdapter {
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactory.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactory.java
new file mode 100644
index 000000000..8c32f97c5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.junit.Assert;
+
+/**
+ */
+public class TestAdapterFactory extends Assert implements IAdapterFactory {
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ assertTrue("Request for wrong adapter", adaptableObject instanceof TestAdaptable);
+ return adapterType.cast(new TestAdapter());
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class[] {TestAdapter.class};
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactoryLoader.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactoryLoader.java
new file mode 100644
index 000000000..ffe78ce6c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/adaptable/TestAdapterFactoryLoader.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.adaptable;
+
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.core.runtime.*;
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+
+/**
+ * The adaptor factory to test scenario described in the bug 200068: adapting to
+ * a class not reachable be the default class loader.
+ *
+ * This is a test code so almost all sanity checks are omitted (it is working on a known
+ * hard-coded set of extensions and extension points). Also, for simplicity no trackers
+ * or caching is done.
+ */
+public class TestAdapterFactoryLoader extends Assert implements IAdapterFactory {
+
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ try {
+ Class<?>[] targets = getAdapterList();
+ return adapterType.cast(targets[0].getDeclaredConstructor().newInstance());
+ } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e) {
+ e.printStackTrace();
+ fail("Unable to load target class");
+ return null;
+ }
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+ IExtensionPoint extPoint = registry.getExtensionPoint("org.eclipse.equinox.common.tests.factoryLoaderTest");
+ IExtension[] extensions = extPoint.getExtensions();
+ if (extensions.length == 0) {
+ return new Class[0];
+ }
+ IExtension extension = extensions[0];
+ IConfigurationElement[] confElements = extension.getConfigurationElements();
+ String className = confElements[0].getAttribute("name");
+ IContributor contributor = extension.getContributor();
+ Bundle extensionBundle = ContributorFactoryOSGi.resolve(contributor);
+ try {
+ return new Class[] {extensionBundle.loadClass(className)};
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ fail("Unable to load class " + className);
+ return null;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ContributorsTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ContributorsTest.java
new file mode 100644
index 000000000..8b80592db
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ContributorsTest.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.spi.IDynamicExtensionRegistry;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Tests contributor resolution for Bundle-based contributors.
+ *
+ * @since 3.3
+ */
+public class ContributorsTest extends TestCase {
+
+ public ContributorsTest() {
+ super();
+ }
+
+ public ContributorsTest(String name) {
+ super(name);
+ }
+
+ public void testResolution() throws IOException, BundleException {
+ Bundle bundle = null;
+ Bundle fragment = null;
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/registry/contributors/A");
+ fragment = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/registry/contributors/B");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle, fragment});
+
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+ IExtensionPoint bundleExtPoint = registry.getExtensionPoint("testContributors.xptContibutorsA");
+ IContributor bundleContributor = bundleExtPoint.getContributor();
+ Bundle contributingBundle = ContributorFactoryOSGi.resolve(bundleContributor);
+ assertNotNull(contributingBundle);
+ assertTrue(contributingBundle.equals(bundle));
+
+ IExtensionPoint fragmentExtPoint = registry.getExtensionPoint("testContributors.contrFragment");
+ IContributor fragmentContributor = fragmentExtPoint.getContributor();
+ Bundle contributingFragment = ContributorFactoryOSGi.resolve(fragmentContributor);
+ assertNotNull(contributingFragment);
+ assertTrue(contributingFragment.equals(fragment));
+ } finally {
+ if (bundle != null) {
+ bundle.uninstall();
+ }
+ if (fragment != null) {
+ fragment.uninstall();
+ }
+ }
+ }
+
+ /**
+ * bundleA, bundleB, and fragment on bundleA all use the same namespace. Verify that getting
+ * elements by contributor returns all elements from the contributor and only from that
+ * contributor.
+ *
+ * @throws IOException
+ * @throws BundleException
+ */
+ public void testByContributor() throws IOException, BundleException {
+ Bundle bundleA = null;
+ Bundle bundleB = null;
+ Bundle fragment = null;
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundleA = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/registry/elementsByContributor/A");
+ bundleB = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/registry/elementsByContributor/B");
+ fragment = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/registry/elementsByContributor/Afragment");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundleA, bundleB, fragment});
+
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+
+ // verify bundleA (bundle B is the same - will work if this works)
+ IContributor contributorA = ContributorFactoryOSGi.createContributor(bundleA);
+
+ IExtensionPoint[] extPointsA = registry.getExtensionPoints(contributorA);
+ assertNotNull(extPointsA);
+ assertTrue(extPointsA.length == 1);
+ assertTrue(extPointsA[0].getUniqueIdentifier().equals("org.eclipse.test.registryByContrib.PointA"));
+
+ IExtension[] extsA = registry.getExtensions(contributorA);
+ assertNotNull(extsA);
+ assertTrue(extsA.length == 1);
+ assertTrue(extsA[0].getUniqueIdentifier().equals("org.eclipse.test.registryByContrib.ExtensionA"));
+
+ // verify fragment
+ IContributor contributorAF = ContributorFactoryOSGi.createContributor(fragment);
+ IExtensionPoint[] extPointsFragmentA = registry.getExtensionPoints(contributorAF);
+ assertNotNull(extPointsFragmentA);
+ assertTrue(extPointsFragmentA.length == 1);
+ assertTrue(extPointsFragmentA[0].getUniqueIdentifier().equals("org.eclipse.test.registryByContrib.PointFA"));
+
+ IExtension[] extsFragmentA = registry.getExtensions(contributorAF);
+ assertNotNull(extsFragmentA);
+ assertTrue(extsFragmentA.length == 1);
+ assertTrue(extsFragmentA[0].getUniqueIdentifier().equals("org.eclipse.test.registryByContrib.ExtensionFA"));
+
+ } finally {
+ if (bundleA != null) {
+ bundleA.uninstall();
+ }
+ if (bundleB != null) {
+ bundleB.uninstall();
+ }
+ if (fragment != null) {
+ fragment.uninstall();
+ }
+ }
+ }
+
+ /**
+ * Checks {@link IDynamicExtensionRegistry#removeContributor(IContributor, Object)}. A separate
+ * registry is created as removal functionality is not allowed by the default Eclipse registry.
+ *
+ * @throws IOException
+ * @throws BundleException
+ */
+ public void testContributorRemoval() throws IOException {
+ Object masterKey = new Object();
+ IExtensionRegistry registry = RegistryFactory.createRegistry(null, masterKey, null);
+
+ assertTrue(addContribution(registry, "A"));
+ assertTrue(addContribution(registry, "B"));
+
+ assertNotNull(registry.getExtensionPoint("org.eclipse.test.registryByContrib.PointA"));
+ assertNotNull(registry.getExtensionPoint("org.eclipse.test.registryByContrib.PointB"));
+
+ IContributor[] contributors = ((IDynamicExtensionRegistry) registry).getAllContributors();
+ assertNotNull(contributors);
+ assertTrue(contributors.length == 2);
+ IContributor contributorB = null;
+ for (IContributor contributor : contributors) {
+ if ("B".equals(contributor.getName())) {
+ contributorB = contributor;
+ break;
+ }
+ }
+ assertNotNull(contributorB);
+
+ ((IDynamicExtensionRegistry) registry).removeContributor(contributorB, masterKey);
+
+ assertNotNull(registry.getExtensionPoint("org.eclipse.test.registryByContrib.PointA"));
+ assertNull(registry.getExtensionPoint("org.eclipse.test.registryByContrib.PointB"));
+ }
+
+ private boolean addContribution(IExtensionRegistry registry, String fileName) throws IOException {
+ String fullPath = "Plugin_Testing/registry/elementsByContributor/" + fileName + "/plugin.xml";
+ URL urlA = FrameworkUtil.getBundle(getClass()).getEntry(fullPath);
+ if (urlA == null) {
+ throw new IOException("No entry to '"+fullPath+"' could be found or caller does not have the appropriate permissions.");//$NON-NLS-1$ //$NON-NLS-2$
+ }
+ InputStream is = urlA.openStream();
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor(fileName);
+ return registry.addContribution(is, nonBundleContributor, false, urlA.getFile(), null, null);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryDynamicTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryDynamicTest.java
new file mode 100644
index 000000000..b500bbaf4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryDynamicTest.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.dynamichelpers.*;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.eclipse.core.tests.harness.TestRegistryChangeListener;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+public class ExtensionRegistryDynamicTest extends TestCase {
+
+ public ExtensionRegistryDynamicTest() {
+ super();
+ }
+
+ public ExtensionRegistryDynamicTest(String name) {
+ super(name);
+ }
+
+ public void testAddition() throws IOException, BundleException {
+ Bundle bundle01 = null;
+ Bundle bundle02 = null;
+ TestRegistryChangeListener listener = new TestRegistryChangeListener("bundle01", "xp1", "bundle02", "ext1");
+ listener.register();
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle01 = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/registryEvents/bundle01");
+ bundle02 = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/registryEvents/bundle02");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01, bundle02});
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+ IExtensionPoint extPoint = registry.getExtensionPoint("bundle01.xp1");
+ IExtension[] extensions = extPoint.getExtensions();
+ assertEquals("0.9", extensions.length, 1);
+
+ assertEquals("1.2", IExtensionDelta.ADDED, listener.eventTypeReceived(20000));
+ } finally {
+ listener.unregister();
+ if (bundle01 != null) {
+ bundle01.uninstall();
+ }
+ if (bundle02 != null) {
+ bundle02.uninstall();
+ }
+ }
+ }
+
+ /**
+ * @see bug 65783
+ */
+ public void testReresolving() throws IOException, BundleException {
+ Bundle bundle01 = null;
+ Bundle bundle02 = null;
+ TestRegistryChangeListener listener = new TestRegistryChangeListener("bundle01", "xp1", "bundle02", "ext1");
+ listener.register();
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle01 = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/registryEvents/bundle01");
+ bundle02 = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/registryEvents/bundle02");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01, bundle02});
+ assertEquals("0.5", IExtensionDelta.ADDED, listener.eventTypeReceived(20000));
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle02});
+ assertEquals("1.2", IExtensionDelta.REMOVED, listener.eventTypeReceived(10000));
+ assertEquals("2.2", IExtensionDelta.ADDED, listener.eventTypeReceived(10000));
+ } finally {
+ listener.unregister();
+ if (bundle01 != null) {
+ bundle01.uninstall();
+ }
+ if (bundle02 != null) {
+ bundle02.uninstall();
+ }
+ }
+ }
+
+ boolean additionCalled = false;
+ boolean removalCalled = false;
+
+ /**
+ * @see bug 178028
+ */
+ public void testEventTracker() throws IOException, BundleException {
+ Bundle bundle01 = null;
+ Bundle bundle02 = null;
+ TestRegistryChangeListener listener = new TestRegistryChangeListener("bundle01", "xp1", "bundle02", "ext1");
+ listener.register();
+ TestRegistryChangeListener lastListener = null;
+ try {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle01 = BundleTestingHelper.installBundle("0.1", bundleContext, "Plugin_Testing/registryEvents/bundle01");
+ bundle02 = BundleTestingHelper.installBundle("0.2", bundleContext, "Plugin_Testing/registryEvents/bundle02");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01, bundle02});
+ assertEquals("0.5", IExtensionDelta.ADDED, listener.eventTypeReceived(20000));
+
+ ExtensionTracker tracker = new ExtensionTracker();
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+ IExtensionPoint extPoint = registry.getExtensionPoint("bundle01.xp1");
+
+ // reset state variables
+ additionCalled = false;
+ removalCalled = false;
+
+ tracker.registerHandler(new IExtensionChangeHandler() {
+
+ @Override
+ public void addExtension(IExtensionTracker currentTracker, IExtension extension) {
+ additionCalled = true;
+ }
+
+ @Override
+ public void removeExtension(IExtension extension, Object[] objects) {
+ removalCalled = true;
+ }
+ }, ExtensionTracker.createExtensionPointFilter(extPoint));
+
+ lastListener = new TestRegistryChangeListener("bundle01", "xp1", "bundle02", "ext1");
+ // this relies on implementation details: listeners are called in the order they are registered
+ lastListener.register();
+
+ bundle02.uninstall();
+ bundle02 = null;
+
+ // make sure that all listener processed by synching on the last added listener
+ assertEquals("3.0", IExtensionDelta.REMOVED, lastListener.eventTypeReceived(20000));
+
+ assertFalse(additionCalled);
+ assertTrue(removalCalled);
+ } finally {
+ listener.unregister();
+ if (lastListener != null) {
+ lastListener.unregister();
+ }
+ if (bundle01 != null) {
+ bundle01.uninstall();
+ }
+ if (bundle02 != null) {
+ bundle02.uninstall();
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryStaticTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryStaticTest.java
new file mode 100644
index 000000000..f6964d8f2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/ExtensionRegistryStaticTest.java
@@ -0,0 +1,359 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import junit.framework.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+public class ExtensionRegistryStaticTest extends TestCase {
+
+ private BundleContext fBundleContext;
+
+ public ExtensionRegistryStaticTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ fBundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ }
+
+ public void testA() throws IOException, BundleException {
+ //test the addition of an extension point
+ String name = "A";
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/test" + name);
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ testExtensionPoint(name);
+ }
+
+ public void testAFromCache() {
+ //Check that it has been persisted
+ testExtensionPoint("A");
+ }
+
+ private void testExtensionPoint(String name) {
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("test" + name + ".xpt" + name));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("test" + name + ".xpt" + name).getLabel(), "Label xpt" + name);
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("test" + name + ".xpt" + name).getNamespace(), "test" + name);
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("test" + name + ".xpt" + name).getNamespaceIdentifier(), "test" + name);
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("test" + name + ".xpt" + name).getContributor().getName(), "test" + name);
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("test" + name + ".xpt" + name).getSchemaReference(), "schema/xpt" + name + ".exsd");
+ }
+
+ public void testB() throws IOException, BundleException {
+ //test the addition of an extension without extension point
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testB/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ assertNull(RegistryFactory.getRegistry().getExtension("testB2", "xptB2", "ext1"));
+ }
+
+ public void testBFromCache() throws IOException, BundleException {
+ // Test the addition of an extension point when orphans extension exists
+ assertNull(RegistryFactory.getRegistry().getExtension("testB2", "xptB2", "ext1"));
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testB/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+ testExtensionPoint("B2");
+
+ // Test the configuration elements
+ assertEquals(RegistryFactory.getRegistry().getExtension("testB2", "xptB2", "testB1.ext1").getConfigurationElements().length, 0);
+ assertEquals(RegistryFactory.getRegistry().getConfigurationElementsFor("testB2.xptB2").length, 0);
+
+ //Test the number of extension in the namespace
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testB1").length, 1);
+
+ //Test the extension
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testB1.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testB2", "xptB2", "testB1.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testB2.xptB2", "testB1.ext1"));
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testB2.xptB2").getExtension("testB1.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testB2.xptB2").getExtensions()[0].getUniqueIdentifier(), "testB1.ext1");
+
+ //uninstall the bundle contributing the extension point
+ bundle02.uninstall();
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+
+ assertNull(RegistryFactory.getRegistry().getExtension("testB1.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testB1").length, 0);
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoints("testB2").length, 0);
+ assertNull(RegistryFactory.getRegistry().getExtensionPoint("testB2.xptB2"));
+ }
+
+ public void testBRemoved() {
+ //Test if testB has been removed.
+ assertNull(RegistryFactory.getRegistry().getExtension("testB1.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testB1").length, 0);
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoints("testB2").length, 0);
+ assertNull(RegistryFactory.getRegistry().getExtensionPoint("testB2.xptB2"));
+ }
+
+ public void testC() throws IOException, BundleException {
+ //test the addition of an extension point then the addition of an extension
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testC/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ testExtensionPoint("C1");
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testC/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+
+ //Test the configurataion elements
+ assertEquals(RegistryFactory.getRegistry().getExtension("testC1", "xptC1", "testC2.ext1").getConfigurationElements().length, 0);
+ assertEquals(RegistryFactory.getRegistry().getConfigurationElementsFor("testC1.xptC1").length, 0);
+
+ //Test the number of extension in the namespace
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testC2").length, 1);
+
+ //Test the extension
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testC2.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testC1", "xptC1", "testC2.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testC1.xptC1", "testC2.ext1"));
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testC1.xptC1").getExtension("testC2.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testC1.xptC1").getExtensions()[0].getUniqueIdentifier(), "testC2.ext1");
+ }
+
+ public void testD() throws IOException, BundleException {
+ //test the addition of an extension then the addition of an extension point
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testD/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testD/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ testExtensionPoint("D1");
+
+ //Test the configurataion elements
+ assertEquals(RegistryFactory.getRegistry().getExtension("testD1", "xptD1", "testD2.ext1").getConfigurationElements().length, 0);
+ assertEquals(RegistryFactory.getRegistry().getConfigurationElementsFor("testD1.xptD1").length, 0);
+
+ //Test the number of extension in the namespace
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testD2").length, 1);
+
+ //Test the extension
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testD2.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testD1", "xptD1", "testD2.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testD1.xptD1", "testD2.ext1"));
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testD1.xptD1").getExtension("testD2.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testD1.xptD1").getExtensions()[0].getUniqueIdentifier(), "testD2.ext1");
+ }
+
+ public void testE() throws IOException, BundleException {
+ //test the addition of an extension point and then add the extension through a fragment
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testE/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testE/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+ testExtensionPoint("E1");
+
+ //Test the configurataion elements
+ assertEquals(RegistryFactory.getRegistry().getExtension("testE1", "xptE1", "testE1.ext1").getConfigurationElements().length, 0);
+ assertEquals(RegistryFactory.getRegistry().getConfigurationElementsFor("testE1.xptE1").length, 0);
+
+ //Test the number of extension in the namespace
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testE1").length, 1);
+
+ //Test the extension
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testE1", "xptE1", "testE1.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testE1.xptE1", "testE1.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testE1.ext1")); //This test exhibits a bug in the 3.0 implementation
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testE1.xptE1").getExtension("testE1.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testE1.xptE1").getExtensions()[0].getUniqueIdentifier(), "testE1.ext1");
+ }
+
+ public void testF() throws IOException, BundleException {
+ //test the addition of the extension through a fragment then the addition of an extension point
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testF/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testF/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ testExtensionPoint("F1");
+
+ //Test the configurataion elements
+ assertEquals(RegistryFactory.getRegistry().getExtension("testF1", "xptF1", "testF1.ext1").getConfigurationElements().length, 0);
+ assertEquals(RegistryFactory.getRegistry().getConfigurationElementsFor("testF1.xptE1").length, 0);
+
+ //Test the number of extension in the namespace
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testF1").length, 1);
+
+ //Test the extension
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testF1", "xptF1", "testF1.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testF1.xptF1", "testF1.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testF1.ext1")); //This test exhibits a bug in the 3.0 implementation
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testF1.xptF1").getExtension("testF1.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testF1.xptF1").getExtensions()[0].getUniqueIdentifier(), "testF1.ext1");
+
+ //Test the namespace
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testF1"), true);
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testF2"), false);
+ }
+
+ public void testG() throws IOException, BundleException {
+ //fragment contributing an extension point to a plugin that do not have extension or extension point
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testG/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testG/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testG1.xptG2"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testG1.xptG2").getLabel(), "Label xptG2");
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testG1.xptG2").getNamespace(), "testG1");
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testG1.xptG2").getNamespaceIdentifier(), "testG1");
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testG1.xptG2").getContributor().getName(), "testG1");
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testG1.xptG2").getSchemaReference(), "schema/xptG2.exsd");
+
+ //Test the namespace
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testG1"), true);
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testG2"), false);
+ }
+
+ public void testH() throws IOException, BundleException {
+ // fragment contributing an extension to a plugin that does not have extension or extension point
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testH/1");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testH/2");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+ Bundle bundle03 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testH/3");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle03});
+
+ testExtensionPoint("H1");
+
+ //Test the configurataion elements
+ assertEquals(RegistryFactory.getRegistry().getExtension("testH1", "xptH1", "testH3.ext1").getConfigurationElements().length, 0);
+ assertEquals(RegistryFactory.getRegistry().getConfigurationElementsFor("testH1.xptH1").length, 0);
+
+ //Test the number of extension in the namespace
+ assertEquals(RegistryFactory.getRegistry().getExtensions("testH3").length, 1);
+
+ //Test the extension
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testH1", "xptH1", "testH3.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testH1.xptH1", "testH3.ext1"));
+ assertNotNull(RegistryFactory.getRegistry().getExtension("testH3.ext1")); //This test exhibits a bug in the 3.0 implementation
+
+ assertNotNull(RegistryFactory.getRegistry().getExtensionPoint("testH1.xptH1").getExtension("testH3.ext1"));
+ assertEquals(RegistryFactory.getRegistry().getExtensionPoint("testH1.xptH1").getExtensions()[0].getUniqueIdentifier(), "testH3.ext1");
+
+ //Test the namespace
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testH1"), true);
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testH3"), true);
+ assertEquals(Arrays.asList(RegistryFactory.getRegistry().getNamespaces()).contains("testH2"), false); //fragments do not come with their namespace
+ }
+
+ public void test71826() throws MalformedURLException, BundleException, IOException {
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/71826/fragmentF");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+
+ Bundle bundle02 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/71826/pluginB");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle02});
+
+ Bundle bundle03 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/71826/pluginA");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle03});
+
+ IExtensionPoint xp = RegistryFactory.getRegistry().getExtensionPoint("71826A.xptE");
+ assertNotNull("1.0", xp);
+ IExtension[] exts = xp.getExtensions();
+ assertEquals("1.1", 2, exts.length);
+ assertNotNull("1.2", xp.getExtension("71826A.F1"));
+ assertNotNull("1.3", xp.getExtension("71826B.B1"));
+ }
+
+ public void testJ() throws MalformedURLException, BundleException, IOException {
+ //Test the third level configuration elements
+ Bundle bundle01 = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/testI");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {bundle01});
+
+ IExtension ext = RegistryFactory.getRegistry().getExtension("testI.ext1");
+ IConfigurationElement ce = ext.getConfigurationElements()[0];
+ assertEquals(ce.getName(), "ce");
+ assertNotNull(ce.getValue());
+ assertEquals(ce.getChildren()[0].getName(), "ce2");
+ assertNull(ce.getChildren()[0].getValue());
+ assertEquals(ce.getChildren()[0].getChildren()[0].getName(), "ce3");
+ assertNull(ce.getChildren()[0].getChildren()[0].getValue());
+ assertEquals(ce.getChildren()[0].getChildren()[1].getName(), "ce3");
+ assertNull(ce.getChildren()[0].getChildren()[1].getValue());
+ assertEquals(ce.getChildren()[0].getChildren()[0].getChildren()[0].getName(), "ce4");
+ assertNotNull(ce.getChildren()[0].getChildren()[0].getChildren()[0].getValue());
+ }
+
+ public void testJbis() {
+ //Test the third level configuration elements from cache
+ IExtension ext = RegistryFactory.getRegistry().getExtension("testI.ext1");
+ IConfigurationElement ce = ext.getConfigurationElements()[0];
+ assertEquals(ce.getName(), "ce");
+ assertNotNull(ce.getValue());
+ assertEquals(ce.getChildren()[0].getName(), "ce2");
+ assertNull(ce.getChildren()[0].getValue());
+ assertEquals(ce.getChildren()[0].getChildren()[0].getName(), "ce3");
+ assertNull(ce.getChildren()[0].getChildren()[0].getValue());
+ assertEquals(ce.getChildren()[0].getChildren()[1].getName(), "ce3");
+ assertNull(ce.getChildren()[0].getChildren()[1].getValue());
+ assertEquals(ce.getChildren()[0].getChildren()[0].getChildren()[0].getName(), "ce4");
+ assertNotNull(ce.getChildren()[0].getChildren()[0].getChildren()[0].getValue());
+ }
+
+ public void testNonSingletonBundle() throws MalformedURLException, BundleException, IOException {
+ //Non singleton bundles are not supposed to be added
+ Bundle nonSingletonBundle = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/nonSingleton");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {nonSingletonBundle});
+ assertNull(RegistryFactory.getRegistry().getExtensionPoint("NonSingleton.ExtensionPoint"));
+ }
+
+ public void testSingletonFragment() throws MalformedURLException, BundleException, IOException {
+ //Fragments to non singleton host can not contribute extension or extension points
+ Bundle fragmentToNonSingleton = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/fragmentToNonSingleton");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {fragmentToNonSingleton});
+ assertNull(RegistryFactory.getRegistry().getExtensionPoint("NonSingleton.Bar"));
+ }
+
+ public void testNonSingletonFragment() throws MalformedURLException, BundleException, IOException {
+ //Non singleton bundles are not supposed to be added
+ Bundle regular = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/nonSingletonFragment/plugin");
+ Bundle nonSingletonFragment = BundleTestingHelper.installBundle("", fBundleContext, "Plugin_Testing/registry/nonSingletonFragment/fragment");
+ BundleTestingHelper.refreshPackages(fBundleContext, new Bundle[] {regular, nonSingletonFragment});
+ assertNull(RegistryFactory.getRegistry().getExtensionPoint("Regular.Bar"));
+ }
+
+ public static Test suite() {
+ //Order is important
+ TestSuite sameSession = new TestSuite(ExtensionRegistryStaticTest.class.getName());
+ sameSession.addTest(new ExtensionRegistryStaticTest("testA"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testAFromCache"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testB"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testBFromCache"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testBRemoved"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testC"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testD"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testE"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testF"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testG"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testH"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("test71826"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testJ"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testJbis"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testNonSingletonBundle"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testSingletonFragment"));
+ sameSession.addTest(new ExtensionRegistryStaticTest("testNonSingletonFragment"));
+ return sameSession;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/InputErrorTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/InputErrorTest.java
new file mode 100644
index 000000000..aa604ec77
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/InputErrorTest.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.*;
+import java.net.URL;
+import junit.framework.TestCase;
+import org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI;
+import org.eclipse.core.runtime.*;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Test proper clean-up in case registry gets invalid XML contribution.
+ * @since 3.4
+ */
+public class InputErrorTest extends TestCase {
+
+ static private final String DATA_LOCATION = "Plugin_Testing/registry/errorHandling/";
+
+ /**
+ * Use customized registry strategy to both check error processing
+ * and to remove expected error messages from test log.
+ */
+ private class RegistryStrategyLog extends RegistryStrategyOSGI {
+
+ public String msg = null;
+
+ public RegistryStrategyLog(File[] theStorageDir, boolean[] cacheReadOnly, Object key) {
+ super(theStorageDir, cacheReadOnly, key);
+ }
+
+ @Override
+ public void log(IStatus status) {
+ msg = status.getMessage();
+ }
+ }
+
+ public InputErrorTest() {
+ super();
+ }
+
+ public InputErrorTest(String name) {
+ super(name);
+ }
+
+ private InputStream getStream(String location) {
+ URL xml = FrameworkUtil.getBundle(getClass()).getEntry(DATA_LOCATION + location);
+ assertNotNull(xml);
+ try {
+ return new BufferedInputStream(xml.openStream());
+ } catch (IOException ex) {
+ fail("Unable to open input stream to XML");
+ }
+ return null;
+ }
+
+ public void testErrorCleanupPoints() {
+ RegistryStrategyLog strategy = new RegistryStrategyLog(null, null, null); // RegistryFactory.createOSGiStrategy(null, null, null);
+ IExtensionRegistry localRegistry = RegistryFactory.createRegistry(strategy, null, null);
+ IContributor contributor = ContributorFactorySimple.createContributor("testErrorHandling");
+
+ // 1) attempt to add information from mis-formed XML
+ InputStream is = getStream("bad/point/plugin.xml");
+ assertNotNull(is);
+ boolean added = localRegistry.addContribution(is, contributor, false, "test", null, null);
+ assertFalse(added);
+ IExtensionPoint bundleExtPointA = localRegistry.getExtensionPoint("testErrorHandling.xptErrorTestA");
+ assertNull(bundleExtPointA);
+ IExtensionPoint bundleExtPointB = localRegistry.getExtensionPoint("testErrorHandling.xptErrorTestB");
+ assertNull(bundleExtPointB);
+
+ assertNotNull(strategy.msg);
+ strategy.msg = null;
+
+ // 2) add properly formed XML
+ is = getStream("good/point/plugin.xml");
+ assertNotNull(is);
+ added = localRegistry.addContribution(is, contributor, false, "test", null, null);
+ assertTrue(added);
+ bundleExtPointA = localRegistry.getExtensionPoint("testErrorHandling.xptErrorTestA");
+ assertNotNull(bundleExtPointA);
+ bundleExtPointB = localRegistry.getExtensionPoint("testErrorHandling.xptErrorTestB");
+ assertNotNull(bundleExtPointB);
+
+ assertNull(strategy.msg);
+ localRegistry.stop(null);
+ }
+
+ public void testErrorCleanupExtensions() {
+ RegistryStrategyLog strategy = new RegistryStrategyLog(null, null, null); // RegistryFactory.createOSGiStrategy(null, null, null);
+ IExtensionRegistry localRegistry = RegistryFactory.createRegistry(strategy, null, null);
+ IContributor contributor = ContributorFactorySimple.createContributor("testErrorHandling");
+
+ // 1) attempt to add information from mis-formed XML
+ InputStream is = getStream("bad/extension/plugin.xml");
+ assertNotNull(is);
+ boolean added = localRegistry.addContribution(is, contributor, false, "test", null, null);
+ assertFalse(added);
+ IExtensionPoint bundleExtPointA = localRegistry.getExtensionPoint("testErrorHandling.xptErrorTestA");
+ assertNull(bundleExtPointA);
+
+ IExtension extensionA = localRegistry.getExtension("testErrorHandling.testExtA");
+ assertNull(extensionA);
+ IExtension extensionB = localRegistry.getExtension("testErrorHandling.testExtB");
+ assertNull(extensionB);
+ IExtension extensionC = localRegistry.getExtension("testErrorHandling.testExtC");
+ assertNull(extensionC);
+
+ assertNotNull(strategy.msg);
+ strategy.msg = null;
+
+ // 2) add properly formed XML
+ is = getStream("good/extension/plugin.xml");
+ assertNotNull(is);
+ added = localRegistry.addContribution(is, contributor, false, "test", null, null);
+ assertTrue(added);
+ bundleExtPointA = localRegistry.getExtensionPoint("testErrorHandling.xptErrorTestA");
+ assertNotNull(bundleExtPointA);
+
+ checkExtension(localRegistry, "testErrorHandling.testExtA", "valueGoodA");
+ checkExtension(localRegistry, "testErrorHandling.testExtB", "valueGoodB");
+ checkExtension(localRegistry, "testErrorHandling.testExtC", "valueGoodC");
+
+ assertNull(strategy.msg);
+ localRegistry.stop(null);
+ }
+
+ private void checkExtension(IExtensionRegistry registry, String extID, String expectedValue) {
+ IExtension extensionA = registry.getExtension(extID);
+ assertNotNull(extensionA);
+ IConfigurationElement[] configElements = extensionA.getConfigurationElements();
+ assertTrue(configElements.length == 1);
+ String value = configElements[0].getAttribute("testAttr");
+ assertTrue(expectedValue.equals(value));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/MultiLanguageTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/MultiLanguageTest.java
new file mode 100644
index 000000000..a59e605bf
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/MultiLanguageTest.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.File;
+import java.util.Locale;
+import junit.framework.TestCase;
+import org.eclipse.core.internal.registry.IRegistryConstants;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.eclipse.core.tests.harness.FileSystemHelper;
+import org.eclipse.osgi.service.localization.LocaleProvider;
+import org.osgi.framework.*;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Run with no NL argument or with "-nl en".
+ */
+public class MultiLanguageTest extends TestCase {
+
+ class LocaleProviderTest implements LocaleProvider {
+ public Locale currentLocale;
+
+ @Override
+ public Locale getLocale() {
+ return currentLocale;
+ }
+ }
+
+ private ServiceTracker<?, PackageAdmin> bundleTracker;
+
+ private static String helloWorld = "Hello World";
+ private static String helloWorldGerman = "Hallo Welt";
+ private static String helloWorldItalian = "Ciao a tutti";
+ private static String helloWorldFinnish = "Hei maailma";
+
+ private static String catsAndDogs = "Cats and dogs";
+ private static String catsAndDogsGerman = "Hunde und Katzen";
+ private static String catsAndDogsItalian = "Cani e gatti";
+ private static String catsAndDogsFinnish = "Kissat ja koirat";
+
+ private static String eclipse = "eclipse";
+ private static String eclipseGerman = "Eklipse";
+ private static String eclipseItalian = "eclissi";
+ private static String eclipseFinnish = "pimennys";
+
+ private static String proverb = "Make haste slowly";
+ private static String proverbLatin = "Festina lente";
+
+ private Bundle bundle;
+ private Bundle bundleFragment;
+ private String oldMultiLangValue;
+ private IPath tmpPath;
+ private File registryLocation;
+
+ private BundleContext testBundleContext;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ testBundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ bundle = BundleTestingHelper.installBundle("0.1", testBundleContext, "Plugin_Testing/registry/multiLang/bundleA");
+ bundleFragment = BundleTestingHelper.installBundle("0.2", testBundleContext, "Plugin_Testing/registry/multiLang/fragmentA");
+ getBundleAdmin().resolveBundles(new Bundle[] {bundle});
+
+ // find a place for the extension registry cache
+ tmpPath = FileSystemHelper.getRandomLocation(FileSystemHelper.getTempDir());
+ registryLocation = tmpPath.append("testMulti").toFile();
+ registryLocation.mkdirs();
+
+ // switch environment to multi-language
+ oldMultiLangValue = System.getProperty(IRegistryConstants.PROP_MULTI_LANGUAGE);
+ System.setProperty(IRegistryConstants.PROP_MULTI_LANGUAGE, "true");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // delete registry cache
+ FileSystemHelper.clear(tmpPath.toFile());
+
+ // remove test bundles
+ bundleFragment.uninstall();
+ bundle.uninstall();
+ refreshPackages(new Bundle[] {bundle});
+
+ // restore system environment
+ if (oldMultiLangValue == null) {
+ System.clearProperty(IRegistryConstants.PROP_MULTI_LANGUAGE);
+ } else {
+ System.setProperty(IRegistryConstants.PROP_MULTI_LANGUAGE, oldMultiLangValue);
+ }
+
+ if (bundleTracker != null) {
+ bundleTracker.close();
+ bundleTracker = null;
+ }
+ super.tearDown();
+ }
+
+ private void refreshPackages(Bundle[] refresh) {
+ final boolean[] flag = new boolean[] {false};
+ FrameworkListener listener = event -> {
+ if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
+ synchronized (flag) {
+ flag[0] = true;
+ flag.notifyAll();
+ }
+ }
+ };
+ testBundleContext.addFrameworkListener(listener);
+
+ try {
+ getBundleAdmin().refreshPackages(refresh);
+ synchronized (flag) {
+ while (!flag[0]) {
+ try {
+ flag.wait(5000);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+ } finally {
+ testBundleContext.removeFrameworkListener(listener);
+ }
+ }
+
+ /**
+ * Tests APIs that take Locale as an argument.
+ */
+ public void testMultiLocale() {
+ Object masterToken = new Object();
+ // Create a multi-language extension registry
+ File[] registryLocations = new File[] {registryLocation};
+ boolean[] readOnly = new boolean[] {false};
+ RegistryStrategy strategy = RegistryFactory.createOSGiStrategy(registryLocations, readOnly, masterToken);
+ IExtensionRegistry localRegistry = RegistryFactory.createRegistry(strategy, masterToken, null);
+ assertTrue(localRegistry.isMultiLanguage());
+
+ // this is a direct test
+ checkTranslations(localRegistry, false);
+
+ // test cache
+ localRegistry.stop(masterToken);
+ IExtensionRegistry registryCached = RegistryFactory.createRegistry(strategy, masterToken, null);
+ assertTrue(registryCached.isMultiLanguage());
+ checkTranslations(registryCached, true);
+
+ registryCached.stop(masterToken);
+ }
+
+ /**
+ * Tests APIs that use implicit default Locale.
+ */
+ public void testMultiLocaleService() {
+ Object masterToken = new Object();
+ // Create a multi-language extension registry
+ File[] registryLocations = new File[] {registryLocation};
+ boolean[] readOnly = new boolean[] {false};
+ RegistryStrategy strategy = RegistryFactory.createOSGiStrategy(registryLocations, readOnly, masterToken);
+ IExtensionRegistry localRegistry = RegistryFactory.createRegistry(strategy, masterToken, null);
+ assertTrue(localRegistry.isMultiLanguage());
+
+ // this is a direct test
+ checkTranslationsService(localRegistry, false);
+
+ // test cache
+ localRegistry.stop(masterToken);
+ IExtensionRegistry registryCached = RegistryFactory.createRegistry(strategy, masterToken, null);
+ assertTrue(registryCached.isMultiLanguage());
+ checkTranslationsService(registryCached, true);
+ registryCached.stop(masterToken);
+ }
+
+ private void checkTranslationsService(IExtensionRegistry registry, boolean extended) {
+ ServiceRegistration<LocaleProvider> registration = null;
+ try {
+ IExtensionPoint extPoint = registry.getExtensionPoint("org.eclipse.test.registryMulti.PointA");
+ assertNotNull(extPoint);
+ IExtension extension = registry.getExtension("org.eclipse.test.registryMulti.ExtA");
+ assertNotNull(extension);
+ IConfigurationElement[] elements = registry.getConfigurationElementsFor("org.eclipse.test.registryMulti", "PointA", "org.eclipse.test.registryMulti.ExtA");
+ assertNotNull(elements);
+ assertEquals(1, elements.length);
+ IConfigurationElement element = elements[0];
+ assertNotNull(element);
+ IConfigurationElement[] sectionElements = element.getChildren("section");
+ assertNotNull(sectionElements);
+ assertEquals(1, sectionElements.length);
+ IConfigurationElement[] subdivisionElements = sectionElements[0].getChildren("subdivision");
+ assertNotNull(subdivisionElements);
+ assertEquals(1, subdivisionElements.length);
+ IConfigurationElement[] elementsValue = registry.getConfigurationElementsFor("org.eclipse.test.registryMulti", "PointValue", "org.eclipse.test.registryMulti.ExtValue");
+ assertNotNull(elementsValue);
+ assertEquals(1, elementsValue.length);
+ IConfigurationElement elementValue = elementsValue[0];
+ assertNotNull(elementValue);
+
+ // default: no service registered
+ assertEquals(helloWorld, extPoint.getLabel());
+ assertEquals(catsAndDogs, extension.getLabel());
+ assertEquals(helloWorld, element.getAttribute("name"));
+ assertEquals(eclipse, subdivisionElements[0].getAttribute("division"));
+ assertEquals(catsAndDogs, elementValue.getValue());
+
+ // locale set to German
+ LocaleProviderTest localeProvider = new LocaleProviderTest();
+ registration = testBundleContext.registerService(LocaleProvider.class, localeProvider, null);
+ localeProvider.currentLocale = new Locale("de_DE");
+ assertEquals(helloWorldGerman, extPoint.getLabel());
+ assertEquals(catsAndDogsGerman, extension.getLabel());
+ assertEquals(helloWorldGerman, element.getAttribute("name"));
+ assertEquals(eclipseGerman, subdivisionElements[0].getAttribute("division"));
+ assertEquals(catsAndDogsGerman, elementValue.getValue());
+
+ // locale changed to Italian
+ localeProvider.currentLocale = new Locale("it_IT");
+ assertEquals(catsAndDogsItalian, extension.getLabel());
+ assertEquals(helloWorldItalian, extPoint.getLabel());
+ assertEquals(helloWorldItalian, element.getAttribute("name"));
+ assertEquals(eclipseItalian, subdivisionElements[0].getAttribute("division"));
+ assertEquals(catsAndDogsItalian, elementValue.getValue());
+
+ if (extended) { // check Finnish
+ localeProvider.currentLocale = new Locale("fi_FI");
+ assertEquals(catsAndDogsFinnish, extension.getLabel());
+ assertEquals(helloWorldFinnish, extPoint.getLabel());
+ assertEquals(helloWorldFinnish, element.getAttribute("name"));
+ assertEquals(eclipseFinnish, subdivisionElements[0].getAttribute("division"));
+ assertEquals(catsAndDogsFinnish, elementValue.getValue());
+ }
+
+ // unregister service - locale back to default
+ registration.unregister();
+ registration = null;
+ assertEquals(helloWorld, extPoint.getLabel());
+ assertEquals(catsAndDogs, extension.getLabel());
+ assertEquals(helloWorld, element.getAttribute("name"));
+ assertEquals(eclipse, subdivisionElements[0].getAttribute("division"));
+ assertEquals(catsAndDogs, elementValue.getValue());
+ } finally {
+ if (registration != null) {
+ registration.unregister();
+ }
+ }
+ }
+
+ private void checkTranslations(IExtensionRegistry registry, boolean extended) {
+ IExtensionPoint extPoint = registry.getExtensionPoint("org.eclipse.test.registryMulti.PointA");
+ assertNotNull(extPoint);
+ IExtension extension = registry.getExtension("org.eclipse.test.registryMulti.ExtA");
+ assertNotNull(extension);
+ IConfigurationElement[] elements = registry.getConfigurationElementsFor("org.eclipse.test.registryMulti", "PointA", "org.eclipse.test.registryMulti.ExtA");
+ assertNotNull(elements);
+ assertEquals(1, elements.length);
+ IConfigurationElement element = elements[0];
+ assertNotNull(element);
+ IConfigurationElement[] sectionElements = element.getChildren("section");
+ assertNotNull(sectionElements);
+ assertEquals(1, sectionElements.length);
+ IConfigurationElement[] subdivisionElements = sectionElements[0].getChildren("subdivision");
+ assertNotNull(subdivisionElements);
+ assertEquals(1, subdivisionElements.length);
+ IConfigurationElement[] elementsValue = registry.getConfigurationElementsFor("org.eclipse.test.registryMulti", "PointValue", "org.eclipse.test.registryMulti.ExtValue");
+ assertNotNull(elementsValue);
+ assertEquals(1, elementsValue.length);
+ IConfigurationElement elementValue = elementsValue[0];
+ assertNotNull(elementValue);
+ IConfigurationElement[] elementsFrag = registry.getConfigurationElementsFor("org.eclipse.test.registryMulti", "FragmentPointA", "org.eclipse.test.registryMulti.FragmentExtA");
+ assertNotNull(elementsFrag);
+ assertEquals(1, elementsFrag.length);
+ IConfigurationElement elementFrag = elementsFrag[0];
+ assertNotNull(elementFrag);
+
+ assertEquals(helloWorldGerman, extPoint.getLabel("de_DE"));
+ assertEquals(helloWorldItalian, extPoint.getLabel("it"));
+ assertEquals(helloWorld, extPoint.getLabel());
+
+ assertEquals(catsAndDogsGerman, extension.getLabel("de_DE"));
+ assertEquals(catsAndDogsItalian, extension.getLabel("it"));
+ assertEquals(catsAndDogs, extension.getLabel());
+
+ assertEquals(helloWorldGerman, element.getAttribute("name", "de_DE"));
+ assertEquals(helloWorldGerman, element.getAttribute("name", "de_DE")); // check internal cache
+
+ assertEquals(helloWorldItalian, element.getAttribute("name", "it"));
+ assertEquals(helloWorldItalian, element.getAttribute("name", "it")); // check internal cache
+
+ assertEquals(helloWorld, element.getAttribute("name", "some_OtherABC"));
+ assertEquals(helloWorld, element.getAttribute("name")); // "default" locale
+
+ assertEquals(eclipseGerman, subdivisionElements[0].getAttribute("division", "de_DE"));
+ assertEquals(eclipseItalian, subdivisionElements[0].getAttribute("division", "it"));
+ assertEquals(eclipse, subdivisionElements[0].getAttribute("division", "some_OtherABC"));
+
+ assertEquals(catsAndDogsGerman, elementValue.getValue("de_DE"));
+ assertEquals(catsAndDogsGerman, elementValue.getValue("de_DE")); // check internal cache
+
+ assertEquals(catsAndDogsItalian, elementValue.getValue("it"));
+ assertEquals(catsAndDogsItalian, elementValue.getValue("it")); // check internal cache
+
+ assertEquals(catsAndDogs, elementValue.getValue("some_OtherABC"));
+ assertEquals(catsAndDogs, elementValue.getValue());
+
+ assertEquals(proverbLatin, elementFrag.getAttribute("name", "la_LA"));
+ assertEquals(proverbLatin, elementFrag.getAttribute("name", "la_LA")); // check internal cache
+ assertEquals(proverb, elementFrag.getAttribute("name", "some_OtherABC"));
+
+ if (!extended) {
+ return;
+ }
+
+ assertEquals(helloWorldFinnish, extPoint.getLabel("fi_FI"));
+ assertEquals(catsAndDogsFinnish, extension.getLabel("fi_FI"));
+ assertEquals(helloWorldFinnish, element.getAttribute("name", "fi_FI"));
+ assertEquals(helloWorldFinnish, element.getAttribute("name", "fi_FI")); // check internal cache
+ assertEquals(eclipseFinnish, subdivisionElements[0].getAttribute("division", "fi_FI"));
+ assertEquals(catsAndDogsFinnish, elementValue.getValue("fi_FI"));
+ assertEquals(catsAndDogsFinnish, elementValue.getValue("fi_FI")); // check internal cache
+ }
+
+ /*
+ * Return the package admin service, if available.
+ */
+ private PackageAdmin getBundleAdmin() {
+ if (bundleTracker == null) {
+ bundleTracker = new ServiceTracker<>(testBundleContext, PackageAdmin.class, null);
+ bundleTracker.open();
+ }
+ return bundleTracker.getService();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/NamespaceTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/NamespaceTest.java
new file mode 100644
index 000000000..c787fa229
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/NamespaceTest.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2012 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.IOException;
+import junit.framework.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+public class NamespaceTest extends TestCase {
+
+ public NamespaceTest(String name) {
+ super(name);
+ }
+
+ public void testNamespaceBasic() throws IOException, BundleException {
+ //test the addition of an extension point
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ Bundle bundle01 = BundleTestingHelper.installBundle("Plugin", bundleContext, "Plugin_Testing/registry/testNamespace/1");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01});
+
+ // Extension point and extension should be present
+ IExtensionPoint extpt = RegistryFactory.getRegistry().getExtensionPoint("org.abc.xptNS1");
+ assertNotNull(extpt);
+ assertTrue(extpt.getNamespaceIdentifier().equals("org.abc"));
+ assertTrue(extpt.getContributor().getName().equals("testNamespace1"));
+ assertTrue(extpt.getSimpleIdentifier().equals("xptNS1"));
+ assertTrue(extpt.getUniqueIdentifier().equals("org.abc.xptNS1"));
+
+ IExtension ext = RegistryFactory.getRegistry().getExtension("org.abc.extNS1");
+ assertNotNull(ext);
+ assertTrue(ext.getNamespaceIdentifier().equals("org.abc"));
+ assertTrue(ext.getContributor().getName().equals("testNamespace1"));
+ assertTrue(ext.getSimpleIdentifier().equals("extNS1"));
+ assertTrue(ext.getUniqueIdentifier().equals("org.abc.extNS1"));
+
+ // Check linkage extension <-> extension point
+ assertTrue(ext.getExtensionPointUniqueIdentifier().equals(extpt.getUniqueIdentifier()));
+ IExtension[] extensions = extpt.getExtensions();
+ assertTrue(extensions.length == 1);
+ assertTrue(extensions[0].equals(ext));
+
+ // Exactly one extension and one extension point in the "org.abc" namespace
+ IExtensionPoint[] namespaceExtensionPoints = RegistryFactory.getRegistry().getExtensionPoints("org.abc");
+ assertTrue(namespaceExtensionPoints.length == 1);
+ assertTrue(namespaceExtensionPoints[0].equals(extpt));
+ IExtension[] namespaceExtensions = RegistryFactory.getRegistry().getExtensions("org.abc");
+ assertTrue(namespaceExtensions.length == 1);
+ assertTrue(namespaceExtensions[0].equals(ext));
+
+ // There should not be extension points or extensions in the default namespace
+ IExtensionPoint[] defaultExtensionPoints = RegistryFactory.getRegistry().getExtensionPoints("testNamespace1");
+ assertTrue(defaultExtensionPoints.length == 0);
+ IExtension[] defaultExtensions = RegistryFactory.getRegistry().getExtensions("testNamespace1");
+ assertTrue(defaultExtensions.length == 0);
+
+ // remove the first bundle
+ bundle01.uninstall();
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01});
+ }
+
+ public void testNamespaceDynamic() throws BundleException, IOException {
+
+ // add another bundle
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ Bundle anotherNamespaceBundle = BundleTestingHelper.installBundle("Plugin", bundleContext, "Plugin_Testing/registry/testNamespace/2");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {anotherNamespaceBundle});
+
+ // all elements from the first bundle should be gone
+ IExtensionPoint extpt_removed = RegistryFactory.getRegistry().getExtensionPoint("org.abc.xptNS1");
+ assertNull(extpt_removed);
+ IExtension ext_removed = RegistryFactory.getRegistry().getExtension("org.abc.extNS1");
+ assertNull(ext_removed);
+
+ // all elements from the second bundle should still be present
+ IExtensionPoint extpt2 = RegistryFactory.getRegistry().getExtensionPoint("org.abc.xptNS2");
+ assertNotNull(extpt2);
+ IExtension ext2 = RegistryFactory.getRegistry().getExtension("org.abc.extNS2");
+ assertNotNull(ext2);
+
+ // Exactly one extension and one extension point in the "org.abc" namespace
+ IExtensionPoint[] namespaceExtensionPoints2 = RegistryFactory.getRegistry().getExtensionPoints("org.abc");
+ assertTrue(namespaceExtensionPoints2.length == 1);
+ assertTrue(namespaceExtensionPoints2[0].equals(extpt2));
+ IExtension[] namespaceExtensions2 = RegistryFactory.getRegistry().getExtensions("org.abc");
+ assertTrue(namespaceExtensions2.length == 1);
+ assertTrue(namespaceExtensions2[0].equals(ext2));
+
+ // remove the second bundle
+ anotherNamespaceBundle.uninstall();
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {anotherNamespaceBundle});
+ }
+
+ public static Test suite() {
+ //Order is important
+ TestSuite sameSession = new TestSuite(NamespaceTest.class.getName());
+ sameSession.addTest(new NamespaceTest("testNamespaceBasic"));
+ sameSession.addTest(new NamespaceTest("testNamespaceDynamic"));
+ return sameSession;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryListenerTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryListenerTest.java
new file mode 100644
index 000000000..95dd5782c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryListenerTest.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.RegistryFactory;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Tests "new" registry event listener.
+ * @since 3.4
+ */
+public class RegistryListenerTest extends TestCase {
+
+ final private static int MAX_TIME_PER_BUNDLE = 10000; // maximum time to wait for bundle event in milliseconds
+
+ private BundleContext fBundleContext;
+
+ public RegistryListenerTest() {
+ super();
+ }
+
+ public RegistryListenerTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ fBundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ }
+
+ /**
+ * Producer and consumer bundles are installed and removed in a "normal" order
+ */
+ public void testRegularOrder() throws IOException, BundleException {
+ Bundle bundle01 = null;
+ Bundle bundle02 = null;
+ WaitingRegistryListener listener = new WaitingRegistryListener();
+ listener.register("bundle01.xp1");
+ try {
+ bundle01 = BundleTestingHelper.installBundle("0.1", fBundleContext, "Plugin_Testing/registryListener/bundle01");
+ bundle02 = BundleTestingHelper.installBundle("0.2", fBundleContext, "Plugin_Testing/registryListener/bundle02");
+
+ Bundle[] testBundles = new Bundle[] {bundle01, bundle02};
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ String[] extPointIDs = listener.extPointsReceived(2 * MAX_TIME_PER_BUNDLE);
+ String[] extensionsReceived = listener.extensionsReceived(2 * MAX_TIME_PER_BUNDLE);
+ assertTrue(listener.isAdded());
+
+ assertNotNull(extPointIDs);
+ assertTrue(extPointIDs.length == 1);
+ assertTrue("bundle01.xp1".equals(extPointIDs[0]));
+
+ assertNotNull(extensionsReceived);
+ assertTrue(extensionsReceived.length == 1);
+ assertTrue("bundle02.ext1".equals(extensionsReceived[0]));
+
+ listener.reset();
+
+ bundle02.uninstall();
+ bundle02 = null; // reset as early as possible in case of exception
+ bundle01.uninstall();
+ bundle01 = null; // reset as early as possible in case of exception
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ extPointIDs = listener.extPointsReceived(2 * MAX_TIME_PER_BUNDLE);
+ extensionsReceived = listener.extensionsReceived(2 * MAX_TIME_PER_BUNDLE);
+ assertTrue(listener.isRemoved());
+
+ assertNotNull(extPointIDs);
+ assertTrue(extPointIDs.length == 1);
+ assertTrue("bundle01.xp1".equals(extPointIDs[0]));
+
+ assertNotNull(extensionsReceived);
+ assertTrue(extensionsReceived.length == 1);
+ assertTrue("bundle02.ext1".equals(extensionsReceived[0]));
+
+ } finally {
+ listener.unregister();
+ if (bundle01 != null) {
+ bundle01.uninstall();
+ }
+ if (bundle02 != null) {
+ bundle02.uninstall();
+ }
+ }
+ }
+
+ /**
+ * Producer and consumer bundles are installed and removed in an inverse order
+ */
+ public void testInverseOrder() throws IOException, BundleException {
+ Bundle bundle01 = null;
+ Bundle bundle02 = null;
+ WaitingRegistryListener listener = new WaitingRegistryListener();
+ listener.register("bundle01.xp1");
+ try {
+ bundle02 = BundleTestingHelper.installBundle("0.2", fBundleContext, "Plugin_Testing/registryEvents/bundle02");
+ bundle01 = BundleTestingHelper.installBundle("0.1", fBundleContext, "Plugin_Testing/registryEvents/bundle01");
+
+ Bundle[] testBundles = new Bundle[] {bundle01, bundle02};
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ String[] extPointIDs = listener.extPointsReceived(2 * MAX_TIME_PER_BUNDLE);
+ String[] extensionsReceived = listener.extensionsReceived(2 * MAX_TIME_PER_BUNDLE);
+ assertTrue(listener.isAdded());
+
+ assertNotNull(extPointIDs);
+ assertTrue(extPointIDs.length == 1);
+ assertTrue("bundle01.xp1".equals(extPointIDs[0]));
+
+ assertNotNull(extensionsReceived);
+ assertTrue(extensionsReceived.length == 1);
+ assertTrue("bundle02.ext1".equals(extensionsReceived[0]));
+
+ listener.reset();
+
+ bundle01.uninstall();
+ bundle01 = null; // reset as early as possible in case of exception
+ bundle02.uninstall();
+ bundle02 = null; // reset as early as possible in case of exception
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ extPointIDs = listener.extPointsReceived(2 * MAX_TIME_PER_BUNDLE);
+ extensionsReceived = listener.extensionsReceived(2 * MAX_TIME_PER_BUNDLE);
+ assertTrue(listener.isRemoved());
+
+ assertNotNull(extPointIDs);
+ assertTrue(extPointIDs.length == 1);
+ assertTrue("bundle01.xp1".equals(extPointIDs[0]));
+
+ assertNotNull(extensionsReceived);
+ assertTrue(extensionsReceived.length == 1);
+ assertTrue("bundle02.ext1".equals(extensionsReceived[0]));
+
+ } finally {
+ listener.unregister();
+ if (bundle02 != null) {
+ bundle02.uninstall();
+ }
+ if (bundle01 != null) {
+ bundle01.uninstall();
+ }
+ }
+ }
+
+ /**
+ * Tests modifications to multiple extensions and extension points
+ * Three listeners are tested: global; on xp1 (two extensions); on xp2 (no extensions)
+ */
+ public void testMultiplePoints() throws IOException, BundleException {
+ Bundle bundle = null;
+ WaitingRegistryListener listenerGlobal = new WaitingRegistryListener();
+ listenerGlobal.register(null);
+ WaitingRegistryListener listener1 = new WaitingRegistryListener();
+ listener1.register("bundleMultiple.xp1");
+ WaitingRegistryListener listener2 = new WaitingRegistryListener();
+ listener2.register("bundleMultiple.xp2");
+ try {
+ bundle = BundleTestingHelper.installBundle("0.1", fBundleContext, "Plugin_Testing/registryListener/bundleMultiple");
+
+ Bundle[] testBundles = new Bundle[] {bundle};
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ // test additions on global listener
+ String[] extPointIDs = listenerGlobal.extPointsReceived(MAX_TIME_PER_BUNDLE);
+ String[] extensionsReceived = listenerGlobal.extensionsReceived(MAX_TIME_PER_BUNDLE);
+ assertTrue(listenerGlobal.isAdded());
+ checkIDs(extPointIDs, new String[] {"bundleMultiple.xp1", "bundleMultiple.xp2"});
+ checkIDs(extensionsReceived, new String[] {"bundleMultiple.ext11", "bundleMultiple.ext12"});
+
+ // test additions on listener on extension point with extensions
+ String[] extPointIDs1 = listener1.extPointsReceived(20000);
+ String[] extensionsReceived1 = listener1.extensionsReceived(20000);
+ assertTrue(listener1.isAdded());
+ checkIDs(extPointIDs1, new String[] {"bundleMultiple.xp1"});
+ checkIDs(extensionsReceived1, new String[] {"bundleMultiple.ext11", "bundleMultiple.ext12"});
+
+ // test additions on listener on extension point with no extensions
+ String[] extPointIDs2 = listener2.extPointsReceived(MAX_TIME_PER_BUNDLE);
+ String[] extensionsReceived2 = listener2.extensionsReceived(50);
+ assertTrue(listener2.isAdded());
+ checkIDs(extPointIDs2, new String[] {"bundleMultiple.xp2"});
+ assertNull(extensionsReceived2);
+
+ // removal
+ listenerGlobal.reset();
+ listener1.reset();
+ listener2.reset();
+ bundle.uninstall();
+ bundle = null; // reset as early as possible in case of exception
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ // test removals on global listener
+ extPointIDs = listenerGlobal.extPointsReceived(MAX_TIME_PER_BUNDLE);
+ extensionsReceived = listenerGlobal.extensionsReceived(MAX_TIME_PER_BUNDLE);
+ assertTrue(listenerGlobal.isRemoved());
+ checkIDs(extPointIDs, new String[] {"bundleMultiple.xp1", "bundleMultiple.xp2"});
+ checkIDs(extensionsReceived, new String[] {"bundleMultiple.ext11", "bundleMultiple.ext12"});
+
+ // test removals on listener on extension point with extensions
+ extPointIDs1 = listener1.extPointsReceived(MAX_TIME_PER_BUNDLE);
+ extensionsReceived1 = listener1.extensionsReceived(MAX_TIME_PER_BUNDLE);
+ assertTrue(listener1.isRemoved());
+ checkIDs(extPointIDs1, new String[] {"bundleMultiple.xp1"});
+ checkIDs(extensionsReceived1, new String[] {"bundleMultiple.ext11", "bundleMultiple.ext12"});
+
+ // test removals on listener on extension point with no extensions
+ extPointIDs2 = listener2.extPointsReceived(MAX_TIME_PER_BUNDLE);
+ extensionsReceived2 = listener2.extensionsReceived(50);
+ assertTrue(listener2.isRemoved());
+ checkIDs(extPointIDs2, new String[] {"bundleMultiple.xp2"});
+ assertNull(extensionsReceived2);
+
+ } finally {
+ listenerGlobal.unregister();
+ listener1.unregister();
+ listener2.unregister();
+ if (bundle != null) {
+ bundle.uninstall();
+ }
+ }
+ }
+
+ /**
+ * Tests listener registered multiple times: once on xp1, once on xp2
+ */
+ public void testMultipleRegistrations() throws IOException, BundleException {
+ Bundle bundle = null;
+ WaitingRegistryListener listener = new WaitingRegistryListener();
+ RegistryFactory.getRegistry().addListener(listener, "bundleMultiple.xp1");
+ RegistryFactory.getRegistry().addListener(listener, "bundleMultiple.xp1");
+ try {
+ bundle = BundleTestingHelper.installBundle("0.1", fBundleContext, "Plugin_Testing/registryListener/bundleMultiple");
+
+ Bundle[] testBundles = new Bundle[] {bundle};
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ // 1st registration: extension point; extension => 2 callbacks
+ // 2nd registration should be ignored: extension => 0 callbacks
+ // total: 2 callbacks
+ assertTrue(listener.waitFor(2, MAX_TIME_PER_BUNDLE) == 2);
+
+ // test additions on listener on extension point with extensions
+ String[] extPointIDs = listener.extPointsReceived(50);
+ String[] extensionsReceived = listener.extensionsReceived(50);
+ assertTrue(listener.isAdded());
+ checkIDs(extPointIDs, new String[] {"bundleMultiple.xp1"});
+ checkIDs(extensionsReceived, new String[] {"bundleMultiple.ext11", "bundleMultiple.ext12"});
+
+ // removal: unregistering listener once should remove both registrations
+ listener.reset();
+ listener.unregister();
+ bundle.uninstall();
+ bundle = null; // reset as early as possible in case of exception
+ BundleTestingHelper.refreshPackages(fBundleContext, testBundles);
+
+ // test removals on listener on extension point with extensions
+ assertTrue(listener.waitFor(3, 200) == 0);
+ extPointIDs = listener.extPointsReceived(50);
+ extensionsReceived = listener.extensionsReceived(50);
+ assertNull(extPointIDs);
+ assertNull(extensionsReceived);
+ } finally {
+ // second unregistration should have no effect
+ listener.unregister();
+ if (bundle != null) {
+ bundle.uninstall();
+ }
+ }
+ }
+
+ // For simplicity, this method does not expect duplicate IDs in either array
+ private void checkIDs(String[] receivedIDs, String[] expectedIDs) {
+ assertNotNull(receivedIDs);
+ assertNotNull(expectedIDs);
+ assertTrue(receivedIDs.length == expectedIDs.length);
+ for (String expected : expectedIDs) {
+ boolean found = false;
+ for (String receivedID : receivedIDs) {
+ if (expected.equals(receivedID)) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryTests.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryTests.java
new file mode 100644
index 000000000..8a4b162f0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/RegistryTests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Julian Honnen
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Julian Honnen - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ ContributorsTest.class,
+ ExtensionRegistryDynamicTest.class,
+ ExtensionRegistryStaticTest.class,
+ InputErrorTest.class,
+ MultiLanguageTest.class,
+ NamespaceTest.class,
+ RegistryListenerTest.class
+})
+public class RegistryTests {
+ // intentionally left blank
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/StaleObjects.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/StaleObjects.java
new file mode 100644
index 000000000..99510e8ac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/StaleObjects.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.tests.harness.BundleTestingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+public class StaleObjects extends TestCase {
+ private class HandleCatcher implements IRegistryChangeListener {
+ private IExtension extensionFromTheListener;
+
+ public HandleCatcher() {
+ RegistryFactory.getRegistry().addRegistryChangeListener(this);
+ }
+
+ @Override
+ public void registryChanged(IRegistryChangeEvent event) {
+ boolean gotException = false;
+ try {
+ extensionFromTheListener = event.getExtensionDeltas()[0].getExtension();
+ extensionFromTheListener.getSimpleIdentifier();
+ } catch (InvalidRegistryObjectException e) {
+ gotException = true;
+ }
+ assertEquals(false, gotException);
+ }
+
+ public IExtension getAcquiredHandle() {
+ return extensionFromTheListener;
+ }
+ }
+
+ public synchronized void testA() throws IOException, BundleException {
+ HandleCatcher listener = new HandleCatcher();
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ Bundle bundle01 = BundleTestingHelper.installBundle("", bundleContext, "Plugin_Testing/registry/testStale1");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01});
+
+ IExtension willBeStale = RegistryFactory.getRegistry().getExtension("testStale.ext1");
+
+ //Test that handles obtained from deltas are working.
+
+ //Test that handles obtained from an addition deltas are working even after the delta is done being broadcasted.
+ boolean gotException = false;
+ try {
+ IExtension result = null;
+ while ((result = listener.getAcquiredHandle()) == null) {
+ try {
+ wait(200);
+ } catch (InterruptedException e) {
+ //ignore.
+ }
+ }
+ result.getSimpleIdentifier();
+ } catch (InvalidRegistryObjectException e) {
+ gotException = true;
+ }
+ assertEquals(false, gotException);
+
+ //Add a listener capturing a handle removal. Inside the handle catcher the handle is valid
+ HandleCatcher listener2 = new HandleCatcher();
+ try {
+ wait(500); //Wait for the listeners to be done
+ } catch (InterruptedException e) {
+ //ignore.
+ }
+
+ bundle01.uninstall();
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01});
+
+ //Outside of the event notification the handle from a removed object should be invalid
+ gotException = false;
+ try {
+ while (listener2.getAcquiredHandle() == null) {
+ try {
+ wait(200);
+ } catch (InterruptedException e) {
+ //ignore.
+ }
+ }
+ listener2.getAcquiredHandle().getSimpleIdentifier();
+ } catch (InvalidRegistryObjectException e) {
+ gotException = true;
+ }
+ assertEquals(true, gotException);
+
+ //Check that the initial handles are stale as well
+ gotException = false;
+ try {
+ willBeStale.getSimpleIdentifier();
+ } catch (InvalidRegistryObjectException e) {
+ gotException = true;
+ }
+ assertEquals(true, gotException);
+ RegistryFactory.getRegistry().removeRegistryChangeListener(listener2);
+ RegistryFactory.getRegistry().removeRegistryChangeListener(listener);
+ }
+
+ public void testStaleConfigurationElement() throws IOException, BundleException {
+ BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ Bundle bundle01 = BundleTestingHelper.installBundle("", bundleContext, "Plugin_Testing/registry/testStale2");
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01});
+
+ IConfigurationElement ce = RegistryFactory.getRegistry().getExtension("testStale2.ext1").getConfigurationElements()[0];
+ assertNotNull(ce);
+
+ bundle01.uninstall();
+ BundleTestingHelper.refreshPackages(bundleContext, new Bundle[] {bundle01});
+
+ boolean gotException = false;
+ try {
+ ce.createExecutableExtension("name");
+ } catch (CoreException c) {
+ gotException = true;
+ }
+ assertEquals(true, gotException);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/WaitingRegistryListener.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/WaitingRegistryListener.java
new file mode 100644
index 000000000..d5c95a619
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/WaitingRegistryListener.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.runtime.*;
+import org.junit.Assert;
+
+/**
+ * Allows test cases to wait for the extension registry notifications.
+ * This listener checks navigability to related elements from extensions.
+ * @since 3.4
+ */
+public class WaitingRegistryListener extends Assert implements IRegistryEventListener {
+
+ final static long MIN_WAIT_TIME = 100; // minimum wait time in milliseconds
+
+ private List<String> extensionIDs; // String[]
+ private List<String> extPointIDs; // String[]
+
+ private volatile boolean added;
+ private volatile boolean removed;
+ private volatile int callbacks;
+
+ private String extPointId;
+
+ public WaitingRegistryListener() {
+ reset();
+ }
+
+ public void register(String id) {
+ extPointId = id; // used for verification in callbacks
+ if (extPointId != null) {
+ RegistryFactory.getRegistry().addListener(this, extPointId);
+ } else {
+ RegistryFactory.getRegistry().addListener(this);
+ }
+ }
+
+ public void unregister() {
+ RegistryFactory.getRegistry().removeListener(this);
+ }
+
+ public void reset() {
+ extensionIDs = null;
+ extPointIDs = null;
+ added = false;
+ removed = false;
+ callbacks = 0;
+ }
+
+ public boolean isAdded() {
+ return added;
+ }
+
+ public boolean isRemoved() {
+ return removed;
+ }
+
+ public synchronized String[] extensionsReceived(long timeout) {
+ if (extensionIDs != null) {
+ return extensionIDs.toArray(new String[extensionIDs.size()]);
+ }
+ try {
+ wait(timeout);
+ } catch (InterruptedException e) {
+ // who cares?
+ }
+ if (extensionIDs == null) {
+ return null;
+ }
+ return extensionIDs.toArray(new String[extensionIDs.size()]);
+ }
+
+ public synchronized String[] extPointsReceived(long timeout) {
+ if (extPointIDs != null) {
+ return extPointIDs.toArray(new String[extPointIDs.size()]);
+ }
+ try {
+ wait(timeout);
+ } catch (InterruptedException e) {
+ // who cares?
+ }
+ if (extPointIDs == null) {
+ return null;
+ }
+ return extPointIDs.toArray(new String[extPointIDs.size()]);
+ }
+
+ public synchronized int waitFor(int events, long maxTimeout) {
+ long startTime = System.currentTimeMillis();
+ try {
+ while (callbacks < events) {
+ long currentTime = System.currentTimeMillis();
+ long alreadyWaited = currentTime - startTime;
+ if (alreadyWaited < 0)
+ {
+ alreadyWaited = 0; // just in case if system timer is not very precise
+ }
+ long timeToWait = maxTimeout - alreadyWaited;
+ if (timeToWait <= 0) {
+ wait(MIN_WAIT_TIME); // give it a last chance
+ break; // timed out
+ }
+ wait(timeToWait);
+ }
+ } catch (InterruptedException e) {
+ // breaks the cycle
+ }
+ return callbacks;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtension[])
+ */
+ @Override
+ synchronized public void added(IExtension[] extensions) {
+ extensionsToString(extensions);
+ added = true;
+ callbacks++;
+ notify();
+ }
+
+ @Override
+ synchronized public void removed(IExtension[] extensions) {
+ extensionsToString(extensions);
+ removed = true;
+ callbacks++;
+ notify();
+ }
+
+ @Override
+ synchronized public void added(IExtensionPoint[] extensionPoints) {
+ extPointsToString(extensionPoints);
+ added = true;
+ callbacks++;
+ notify();
+ }
+
+ @Override
+ synchronized public void removed(IExtensionPoint[] extensionPoints) {
+ extPointsToString(extensionPoints);
+ removed = true;
+ callbacks++;
+ notify();
+ }
+
+ private void extensionsToString(IExtension[] extensions) {
+ extensionIDs = new ArrayList<>(extensions.length);
+ for (IExtension extension : extensions) {
+ extensionIDs.add(extension.getUniqueIdentifier());
+
+ // test navigation: to extension point
+ String ownerId = extension.getExtensionPointUniqueIdentifier();
+ if (extPointId != null) {
+ assertTrue(extPointId.equals(ownerId));
+ }
+ // test navigation: all children
+ assertTrue(validContents(extension.getConfigurationElements()));
+ }
+ }
+
+ private boolean validContents(IConfigurationElement[] children) {
+ if (children == null) {
+ return true;
+ }
+ for (int i = 0; i < children.length; i++) {
+ if (!children[i].isValid()) {
+ return false;
+ }
+ if (!validContents(children[i].getChildren())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void extPointsToString(IExtensionPoint[] extensionPoints) {
+ extPointIDs = new ArrayList<>(extensionPoints.length);
+ for (IExtensionPoint extensionPoint : extensionPoints) {
+ extPointIDs.add(extensionPoint.getUniqueIdentifier());
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/BaseExtensionRegistryRun.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/BaseExtensionRegistryRun.java
new file mode 100644
index 000000000..da7c864b5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/BaseExtensionRegistryRun.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import java.io.*;
+import java.net.URL;
+import junit.framework.TestCase;
+
+import org.eclipse.core.internal.runtime.MetaDataKeeper;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+import org.osgi.framework.FrameworkUtil;
+
+public class BaseExtensionRegistryRun extends TestCase {
+
+ // The imaging device registry
+ protected IExtensionRegistry simpleRegistry;
+ protected Object masterToken = new Object();
+ protected Object userToken = new Object();
+
+ // Path to the XML files
+ private final static String xmlPath = "Plugin_Testing/registry/testSimple/"; //$NON-NLS-1$
+
+ public BaseExtensionRegistryRun() {
+ super();
+ }
+
+ public BaseExtensionRegistryRun(String name) {
+ super(name);
+ }
+
+ protected URL getXML(String fileName) {
+ return FrameworkUtil.getBundle(getClass()).getEntry(xmlPath + fileName);
+ }
+
+ /**
+ * Create the "imaging device" registry
+ */
+ @Override
+ protected void setUp() throws Exception {
+ // create the imaging device registry
+ simpleRegistry = startRegistry();
+ }
+
+ /**
+ * Properly dispose of the extension registry
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ stopRegistry();
+ }
+
+ /**
+ * @return - open extension registry
+ */
+ protected IExtensionRegistry startRegistry() {
+ return startRegistry(this.getClass().getName());
+ }
+
+ /**
+ * @return - open extension registry
+ */
+ protected IExtensionRegistry startRegistry(String subDir) {
+ // use plugin's metadata directory to save cache data
+ IPath userDataPath = getStateLocation();
+ userDataPath = userDataPath.append(subDir);
+
+ File[] registryLocations = new File[] {new File(userDataPath.toOSString())};
+ boolean[] readOnly = new boolean[] {false};
+ RegistryStrategy registryStrategy = new RegistryStrategy(registryLocations, readOnly);
+ return RegistryFactory.createRegistry(registryStrategy, masterToken, userToken);
+ }
+
+ /**
+ * Stops the extension registry.
+ */
+ protected void stopRegistry() {
+ assertNotNull(simpleRegistry);
+ simpleRegistry.stop(masterToken);
+ }
+
+ protected void processXMLContribution(IContributor nonBundleContributor, URL url) {
+ processXMLContribution(nonBundleContributor, url, false);
+ }
+
+ protected void processXMLContribution(IContributor nonBundleContributor, URL url, boolean persist) {
+ try {
+ InputStream is = url.openStream();
+ simpleRegistry.addContribution(is, nonBundleContributor, persist, url.getFile(), null, persist ? masterToken : userToken);
+ } catch (IOException eFile) {
+ fail(eFile.getMessage());
+ return;
+ }
+ }
+
+ protected String qualifiedName(String namespace, String simpleName) {
+ return namespace + "." + simpleName; //$NON-NLS-1$
+ }
+
+ protected IPath getStateLocation() {
+ IPath stateLocation = MetaDataKeeper.getMetaArea().getStateLocation(FrameworkUtil.getBundle(getClass()));
+ stateLocation.toFile().mkdirs();
+ return stateLocation;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTest.java
new file mode 100644
index 000000000..2c317b874
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTest.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import org.eclipse.core.internal.registry.ExtensionRegistry;
+import org.eclipse.core.internal.registry.spi.ConfigurationElementAttribute;
+import org.eclipse.core.internal.registry.spi.ConfigurationElementDescription;
+import org.eclipse.core.runtime.*;
+
+/**
+ * Tests programmatic creation of extension and extension point by using direct
+ * methods on the ExtensionRegistry.
+ *
+ * Note that in present those methods are internal, but might be exposed as
+ * APIs in the future.
+ *
+ * @since 3.2
+ */
+public class DirectExtensionCreateTest extends BaseExtensionRegistryRun {
+
+ public DirectExtensionCreateTest() {
+ super();
+ }
+
+ public DirectExtensionCreateTest(String name) {
+ super(name);
+ }
+
+ public void testExtensionPointAddition() {
+ IContributor contributor = ContributorFactorySimple.createContributor("1"); //$NON-NLS-1$
+ String extensionPointId = "DirectExtPoint"; //$NON-NLS-1$
+ String extensionPointLabel = "Direct Extension Point"; //$NON-NLS-1$
+ String extensionPointSchemaRef = "schema/ExtensionPointTest.exsd"; //$NON-NLS-1$
+
+ /**********************************************************************************************
+ * Add extension point:
+ *
+ * <extension-point id="DirectExtPoint"
+ * name="Direct Extension Point"
+ * schema="schema/ExtensionPointTest.exsd"/>
+ *
+ *********************************************************************************************/
+
+ ((ExtensionRegistry) simpleRegistry).addExtensionPoint(extensionPointId, contributor, false, extensionPointLabel, extensionPointSchemaRef, userToken);
+
+ String namespace = contributor.getName();
+ IExtensionPoint extensionPoint = simpleRegistry.getExtensionPoint(qualifiedName(namespace, extensionPointId));
+ assertNotNull(extensionPoint);
+ assertTrue(extensionPointSchemaRef.equals(extensionPoint.getSchemaReference()));
+ assertTrue(extensionPointLabel.equals(extensionPoint.getLabel()));
+
+ // add second contribution in the same namespace
+ String extensionPointAltId = "DirectExtPointAlt"; //$NON-NLS-1$
+ String extensionPointAltLabel = "Second direct extension point"; //$NON-NLS-1$
+ assertTrue(((ExtensionRegistry) simpleRegistry).addExtensionPoint(extensionPointAltId, contributor, false, extensionPointAltLabel, extensionPointSchemaRef, userToken));
+
+ IExtensionPoint extensionPointAlt = simpleRegistry.getExtensionPoint(qualifiedName(namespace, extensionPointAltId));
+ assertNotNull(extensionPointAlt);
+ assertTrue(extensionPointSchemaRef.equals(extensionPointAlt.getSchemaReference()));
+ assertTrue(extensionPointAltLabel.equals(extensionPointAlt.getLabel()));
+
+ /**********************************************************************************************
+ * Add extension:
+ * <extension id="DirectExtensionID" name="Direct Extension" point="DirectExtPoint">
+ * <StorageDevice deviceURL="theShienneMountain">
+ * <BackupDevice backupURL="SkyLab"/>
+ * <BackupDevice backupURL="OceanFloor"/>
+ * </StorageDevice>
+ * </extension>
+ *********************************************************************************************/
+ String extensionId = "DirectExtensionID"; //$NON-NLS-1$
+ String extensionLabel = "Direct Extension"; //$NON-NLS-1$
+
+ String nameChildDesc = "BackupDevice"; //$NON-NLS-1$
+ String propNameChildDesc = "backupURL"; //$NON-NLS-1$
+ String propValueChildDesc1 = "SkyLab"; //$NON-NLS-1$
+ String propValueChildDesc2 = "OceanFloor"; //$NON-NLS-1$
+
+ ConfigurationElementAttribute propChildDesc1 = new ConfigurationElementAttribute(propNameChildDesc, propValueChildDesc1);
+ ConfigurationElementDescription childDesc1 = new ConfigurationElementDescription(nameChildDesc, propChildDesc1, null, null);
+
+ ConfigurationElementAttribute propChildDesc2 = new ConfigurationElementAttribute(propNameChildDesc, propValueChildDesc2);
+ ConfigurationElementDescription childDesc2 = new ConfigurationElementDescription(nameChildDesc, propChildDesc2, null, null);
+
+ String extensionName = "StorageDevice"; //$NON-NLS-1$
+ String extensionProrName1 = "deviceURL"; //$NON-NLS-1$
+ String extensionPropValue1 = "theShienneMountain"; //$NON-NLS-1$
+ String extensionProrName2 = "primary"; //$NON-NLS-1$
+ String extensionPropValue2 = "true"; //$NON-NLS-1$
+ ConfigurationElementAttribute prop1 = new ConfigurationElementAttribute(extensionProrName1, extensionPropValue1);
+ ConfigurationElementAttribute prop2 = new ConfigurationElementAttribute(extensionProrName2, extensionPropValue2);
+ String extensionValue = "SomeValue"; //$NON-NLS-1$
+
+ ConfigurationElementDescription description = new ConfigurationElementDescription(extensionName, new ConfigurationElementAttribute[] {prop1, prop2}, extensionValue, new ConfigurationElementDescription[] {childDesc1, childDesc2});
+
+ assertTrue(((ExtensionRegistry) simpleRegistry).addExtension(extensionId, contributor, false, extensionLabel, extensionPointId, description, userToken));
+
+ IExtension[] namespaceExtensions = simpleRegistry.getExtensions(namespace);
+ assertNotNull(namespaceExtensions);
+ assertTrue(namespaceExtensions.length == 1);
+ IExtension[] extensions = extensionPoint.getExtensions();
+ assertNotNull(extensions);
+ assertTrue(extensions.length == 1);
+ for (IExtension extension : extensions) {
+ String storedExtensionId = extension.getUniqueIdentifier();
+ assertTrue(storedExtensionId.equals(qualifiedName(namespace, extensionId)));
+ String extensionNamespace = extension.getNamespaceIdentifier();
+ assertTrue(extensionNamespace.equals(namespace));
+ String extensionContributor = extension.getContributor().getName();
+ assertTrue(extensionContributor.equals(namespace));
+ IConfigurationElement[] configElements = extension.getConfigurationElements();
+ assertNotNull(configElements);
+ for (IConfigurationElement configElement : configElements) {
+ String configElementName = configElement.getName();
+ assertTrue(configElementName.equals(extensionName));
+ String configElementValue = configElement.getValue();
+ assertTrue(configElementValue.equals(extensionValue));
+ String[] attributeNames = configElement.getAttributeNames();
+ assertTrue(attributeNames.length == 2);
+ IConfigurationElement[] configElementChildren = configElement.getChildren();
+ assertTrue(configElementChildren.length == 2);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTwoRegistriesTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTwoRegistriesTest.java
new file mode 100644
index 000000000..0287fa5c6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionCreateTwoRegistriesTest.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import org.eclipse.core.internal.registry.ExtensionRegistry;
+import org.eclipse.core.runtime.*;
+
+/**
+ * Test simultaneous work of two extension registries.
+ * @since 3.2
+ */
+public class DirectExtensionCreateTwoRegistriesTest extends BaseExtensionRegistryRun {
+
+ private String extensionPointId = "AAAid"; //$NON-NLS-1$
+ private String extensionPointAltId = "BBBid"; //$NON-NLS-1$
+ private String extensionPointSchemaRef = "schema/schema.exsd"; //$NON-NLS-1$
+
+ private IExtensionRegistry theDeviceRegistryA;
+ private IExtensionRegistry theDeviceRegistryB;
+
+ public DirectExtensionCreateTwoRegistriesTest() {
+ super();
+ }
+
+ public DirectExtensionCreateTwoRegistriesTest(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ startRegistries();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ stopRegistries();
+ }
+
+ private void startRegistries() {
+ theDeviceRegistryA = startRegistry("A"); //$NON-NLS-1$
+ theDeviceRegistryB = startRegistry("B"); //$NON-NLS-1$
+ }
+
+ private void stopRegistries() {
+ assertNotNull(theDeviceRegistryA);
+ theDeviceRegistryA.stop(masterToken);
+
+ assertNotNull(theDeviceRegistryB);
+ theDeviceRegistryB.stop(masterToken);
+ }
+
+ public void testExtensionPointAddition() {
+ // Test with non-bundle contributor
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor("ABC"); //$NON-NLS-1$
+ String namespace = nonBundleContributor.getName();
+ checkEmptyRegistries(namespace); // make sure we don't have any leftovers
+
+ fillRegistries(nonBundleContributor); // add one extension point in each registry
+ checkRegistries(namespace); // check that they got into right places
+
+ stopRegistries(); // check caches
+ startRegistries();
+ checkEmptyRegistries(namespace); // confirm that both registries got re-populated from caches
+ }
+
+ private void checkEmptyRegistries(String namespace) {
+ // see what's in the registry A:
+ IExtensionPoint extensionPoint = theDeviceRegistryA.getExtensionPoint(qualifiedName(namespace, extensionPointId));
+ IExtensionPoint extensionPointAlt = theDeviceRegistryA.getExtensionPoint(qualifiedName(namespace, extensionPointAltId));
+ assertNull(extensionPoint);
+ assertNull(extensionPointAlt);
+ }
+
+ private void fillRegistries(IContributor contributor) {
+ assertTrue(((ExtensionRegistry) theDeviceRegistryA).addExtensionPoint(extensionPointId, contributor, false, "LabelA", extensionPointSchemaRef, userToken)); //$NON-NLS-1$
+ assertTrue(((ExtensionRegistry) theDeviceRegistryB).addExtensionPoint(extensionPointAltId, contributor, false, "LabelB", extensionPointSchemaRef, userToken)); //$NON-NLS-1$
+ }
+
+ private void checkRegistries(String namespace) {
+ // see what's in the registry A:
+ IExtensionPoint extensionPoint = theDeviceRegistryA.getExtensionPoint(qualifiedName(namespace, extensionPointId));
+ IExtensionPoint extensionPointAlt = theDeviceRegistryA.getExtensionPoint(qualifiedName(namespace, extensionPointAltId));
+ assertNotNull(extensionPoint);
+ assertNull(extensionPointAlt);
+
+ // see what's in the registry B:
+ extensionPoint = theDeviceRegistryB.getExtensionPoint(qualifiedName(namespace, extensionPointId));
+ extensionPointAlt = theDeviceRegistryB.getExtensionPoint(qualifiedName(namespace, extensionPointAltId));
+ assertNull(extensionPoint);
+ assertNotNull(extensionPointAlt);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionRemoveTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionRemoveTest.java
new file mode 100644
index 000000000..b05d8370d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DirectExtensionRemoveTest.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.common.tests.registry.simple.utils.SimpleRegistryListener;
+
+/**
+ * Tests removal APIs using a simple registry.
+ * @since 3.2
+ */
+public class DirectExtensionRemoveTest extends BaseExtensionRegistryRun {
+
+ private final static String pointA = "PointA"; //$NON-NLS-1$
+ private final static String pointB = "PointB"; //$NON-NLS-1$
+
+ private final static String extensionA1 = "TestExtensionA1"; //$NON-NLS-1$
+ private final static String extensionA2 = "TestExtensionA2"; //$NON-NLS-1$
+
+ public DirectExtensionRemoveTest() {
+ super();
+ }
+
+ public DirectExtensionRemoveTest(String name) {
+ super(name);
+ }
+
+ // Fill the registry; remove half; check listener; check what's left
+ public void testExtensionPointAddition() {
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor("DirectRemoveProvider"); //$NON-NLS-1$
+ String namespace = nonBundleContributor.getName();
+ fillRegistry(nonBundleContributor);
+ checkRegistryFull(namespace);
+
+ SimpleRegistryListener listener = new SimpleRegistryListener();
+ listener.register(simpleRegistry);
+ remove(namespace);
+
+ checkListener(listener);
+ checkRegistryRemoved(namespace);
+ listener.unregister(simpleRegistry);
+ }
+
+ /**
+ * Tests that configuration elements associated with the removed extension
+ * are removed.
+ */
+ public void testAssociatedConfigElements() {
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor("CETest"); //$NON-NLS-1$
+ String namespace = nonBundleContributor.getName();
+ processXMLContribution(nonBundleContributor, getXML("CERemovalTest.xml")); //$NON-NLS-1$
+
+ IExtensionPoint extensionPointA = simpleRegistry.getExtensionPoint(qualifiedName(namespace, "PointA")); //$NON-NLS-1$
+ assertNotNull(extensionPointA);
+ IExtension[] extensionsA = extensionPointA.getExtensions();
+ assertTrue(extensionsA.length == 2);
+
+ // check first extension
+ IExtension ext1 = extensionPointA.getExtension(qualifiedName(namespace, "TestExtensionA1")); //$NON-NLS-1$
+ assertNotNull(ext1);
+ IConfigurationElement[] ces11 = ext1.getConfigurationElements(); // this will be used later
+ assertNotNull(ces11);
+ assertEquals(1, ces11.length);
+ String[] attrs1 = ces11[0].getAttributeNames();
+ assertNotNull(attrs1);
+ assertEquals(1, attrs1.length);
+ assertEquals("class", attrs1[0]); //$NON-NLS-1$
+ IConfigurationElement[] ces12 = ces11[0].getChildren(); // this will be used later
+ assertNotNull(ces12);
+ assertEquals(1, ces12.length);
+ String[] attrs2 = ces12[0].getAttributeNames();
+ assertNotNull(attrs2);
+ assertEquals(1, attrs2.length);
+ assertEquals("value", attrs2[0]); //$NON-NLS-1$
+
+ // check second extension
+ IExtension ext2 = extensionPointA.getExtension(qualifiedName(namespace, "TestExtensionA2")); //$NON-NLS-1$
+ assertNotNull(ext2);
+ IConfigurationElement[] ces21 = ext2.getConfigurationElements(); // this will be used later
+ IConfigurationElement[] ces22 = ces21[0].getChildren(); // this will be used later
+ String[] attrs22 = ces22[0].getAttributeNames();
+ assertNotNull(attrs22);
+ assertEquals(1, attrs22.length);
+ assertEquals("value", attrs22[0]); //$NON-NLS-1$
+
+ // remove extension1
+ // listener to verify that valid CEs are included in the notification
+ IRegistryChangeListener listener = event -> {
+ IExtensionDelta[] deltas = event.getExtensionDeltas();
+ assertTrue(deltas.length == 1);
+ for (IExtensionDelta delta : deltas) {
+ assertTrue(delta.getKind() == IExtensionDelta.REMOVED);
+ IExtension extension = delta.getExtension();
+ assertNotNull(extension);
+
+ IConfigurationElement[] l_ces11 = extension.getConfigurationElements();
+ assertNotNull(l_ces11);
+ assertEquals(1, l_ces11.length);
+ String[] l_attrs1 = l_ces11[0].getAttributeNames();
+ assertNotNull(l_attrs1);
+ assertEquals(1, l_attrs1.length);
+ assertEquals("class", l_attrs1[0]); //$NON-NLS-1$
+ IConfigurationElement[] l_ces12 = l_ces11[0].getChildren();
+ assertNotNull(l_ces12);
+ assertEquals(1, l_ces12.length);
+ String[] l_attrs2 = l_ces12[0].getAttributeNames();
+ assertNotNull(l_attrs2);
+ assertEquals(1, l_attrs2.length);
+ assertEquals("value", l_attrs2[0]); //$NON-NLS-1$
+ }
+ };
+
+ //SimpleRegistryListener listener = new SimpleRegistryListener() {};
+ simpleRegistry.addRegistryChangeListener(listener);
+ try {
+ simpleRegistry.removeExtension(ext1, userToken);
+ } finally {
+ simpleRegistry.removeRegistryChangeListener(listener);
+ }
+
+ // basic checks
+ IExtension[] extensionsRemoved = extensionPointA.getExtensions();
+ assertTrue(extensionsRemoved.length == 1);
+
+ // re-check configuration elements
+ boolean exceptionFound = false;
+ try {
+ ces11[0].getAttributeNames(); // should produce an exception
+ } catch (InvalidRegistryObjectException e) {
+ exceptionFound = true;
+ }
+ assertTrue(exceptionFound);
+
+ exceptionFound = false;
+ try {
+ ces12[0].getAttributeNames(); // should produce an exception
+ } catch (InvalidRegistryObjectException e) {
+ exceptionFound = true;
+ }
+
+ assertTrue(exceptionFound);
+ // the non-removed extension CEs should still be valid
+ String[] attrs22removed = ces22[0].getAttributeNames();
+ assertNotNull(attrs22removed);
+ assertEquals(1, attrs22removed.length);
+ assertEquals("value", attrs22removed[0]); //$NON-NLS-1$
+ }
+
+ private void fillRegistry(IContributor contributor) {
+ processXMLContribution(contributor, getXML("RemovalTest.xml")); //$NON-NLS-1$
+ }
+
+ private void checkRegistryFull(String namespace) {
+ IExtensionPoint extensionPointA = simpleRegistry.getExtensionPoint(qualifiedName(namespace, pointA));
+ assertNotNull(extensionPointA);
+ IExtensionPoint extensionPointB = simpleRegistry.getExtensionPoint(qualifiedName(namespace, pointB));
+ assertNotNull(extensionPointB);
+ IExtension[] extensionsA = extensionPointA.getExtensions();
+ assertTrue(extensionsA.length == 2);
+ IExtension[] extensionsB = extensionPointB.getExtensions();
+ assertTrue(extensionsB.length == 2);
+ }
+
+ private void remove(String namespace) {
+ IExtensionPoint extensionPointB = simpleRegistry.getExtensionPoint(qualifiedName(namespace, pointB));
+ assertTrue(simpleRegistry.removeExtensionPoint(extensionPointB, userToken));
+
+ IExtension extension = simpleRegistry.getExtension(qualifiedName(namespace, extensionA1));
+ assertTrue(simpleRegistry.removeExtension(extension, userToken));
+ }
+
+ private void checkRegistryRemoved(String namespace) {
+ IExtensionPoint extensionPointA = simpleRegistry.getExtensionPoint(qualifiedName(namespace, pointA));
+ assertNotNull(extensionPointA);
+ IExtensionPoint extensionPointB = simpleRegistry.getExtensionPoint(qualifiedName(namespace, pointB));
+ assertNull(extensionPointB);
+ IExtension[] extensionsA = extensionPointA.getExtensions();
+ assertTrue(extensionsA.length == 1);
+ String Id = extensionsA[0].getUniqueIdentifier();
+ assertTrue(qualifiedName(namespace, extensionA2).equals(Id));
+ }
+
+ private void checkListener(SimpleRegistryListener listener) {
+ IRegistryChangeEvent event = listener.getEvent(5000);
+ IExtensionDelta[] deltas = event.getExtensionDeltas();
+ assertTrue(deltas.length == 2);
+ for (IExtensionDelta delta : deltas) {
+ assertTrue(delta.getKind() == IExtensionDelta.REMOVED);
+ assertNotNull(delta.getExtension());
+ assertNotNull(delta.getExtensionPoint());
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DuplicatePointsTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DuplicatePointsTest.java
new file mode 100644
index 000000000..7e420647b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/DuplicatePointsTest.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import java.io.File;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+import org.eclipse.equinox.common.tests.registry.simple.utils.HiddenLogRegistryStrategy;
+
+/**
+ * Tests addition of extensions and extension points with duplicate IDs.
+ * The duplicate extension points should be ignored.
+ * The duplicate extensions should be added.
+ * The rest of the XML contribution should not be affected.
+ *
+ * @since 3.2
+ */
+public class DuplicatePointsTest extends BaseExtensionRegistryRun {
+
+ private final static String errMsg1 = "Error: Ignored duplicate extension point \"testDuplicates.duplicateExtensionPoint\" supplied by \"2\"." + "Warning: Extensions supplied by \"2\" and \"1\" have the same Id: \"testDuplicates.duplicateExtension\".";
+ private final static String errMsg2 = "Error: Ignored duplicate extension point \"testSame.duplicateExtensionPointSame\" supplied by \"3\"." + "Warning: Extensions supplied by \"3\" and \"3\" have the same Id: \"testSame.duplicateExtensionSame\".";
+
+ public DuplicatePointsTest() {
+ super();
+ }
+
+ public DuplicatePointsTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Use registry strategy with modified logging
+ * @return - open extension registry
+ */
+ @Override
+ protected IExtensionRegistry startRegistry() {
+ // use plugin's metadata directory to save cache data
+ IPath userDataPath = getStateLocation();
+ File[] registryLocations = new File[] {new File(userDataPath.toOSString())};
+ boolean[] readOnly = new boolean[] {false};
+ RegistryStrategy registryStrategy = new HiddenLogRegistryStrategy(registryLocations, readOnly);
+ return RegistryFactory.createRegistry(registryStrategy, masterToken, userToken);
+ }
+
+ public void testDuplicates() {
+ HiddenLogRegistryStrategy.output = ""; //$NON-NLS-1$
+ IContributor contributor1 = ContributorFactorySimple.createContributor("1"); //$NON-NLS-1$
+ processXMLContribution(contributor1, getXML("DuplicatePoints1.xml")); //$NON-NLS-1$
+
+ IContributor contributor2 = ContributorFactorySimple.createContributor("2"); //$NON-NLS-1$
+ processXMLContribution(contributor2, getXML("DuplicatePoints2.xml")); //$NON-NLS-1$
+
+ checkRegistryDifferent("testDuplicates"); //$NON-NLS-1$
+
+ HiddenLogRegistryStrategy.output = ""; //$NON-NLS-1$
+ IContributor contributor3 = ContributorFactorySimple.createContributor("3"); //$NON-NLS-1$
+ processXMLContribution(contributor3, getXML("DuplicatePointsSame.xml")); //$NON-NLS-1$
+
+ checkRegistrySame("testSame"); //$NON-NLS-1$
+ }
+
+ private void checkRegistryDifferent(String namespace) {
+ assertTrue(errMsg1.equals(HiddenLogRegistryStrategy.output));
+
+ IExtensionPoint[] extensionPoints = simpleRegistry.getExtensionPoints(namespace);
+ assertTrue(extensionPoints.length == 2);
+
+ IExtension[] extensions = simpleRegistry.getExtensions(namespace);
+ assertTrue(extensions.length == 3);
+
+ IExtension extension = simpleRegistry.getExtension(qualifiedName(namespace, "nonDuplicateExtension")); //$NON-NLS-1$
+ assertNotNull(extension);
+ }
+
+ private void checkRegistrySame(String namespace) {
+ assertTrue(errMsg2.equals(HiddenLogRegistryStrategy.output));
+
+ IExtensionPoint[] extensionPoints = simpleRegistry.getExtensionPoints(namespace);
+ assertTrue(extensionPoints.length == 1);
+
+ IExtension[] extensions = simpleRegistry.getExtensions(namespace);
+ assertTrue(extensions.length == 2);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/MergeContributionTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/MergeContributionTest.java
new file mode 100644
index 000000000..eb8662469
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/MergeContributionTest.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import org.eclipse.core.runtime.*;
+
+/**
+ * Tests merging static and dynamic contributions.
+ *
+ * @since 3.2
+ */
+public class MergeContributionTest extends BaseExtensionRegistryRun {
+
+ public MergeContributionTest() {
+ super();
+ }
+
+ public MergeContributionTest(String name) {
+ super(name);
+ }
+
+ public void testMergeStaticDynamic() {
+ // Test with non-bundle contributor
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor("ABC"); //$NON-NLS-1$
+ String namespace = nonBundleContributor.getName();
+
+ fillRegistryStatic(nonBundleContributor);
+ checkRegistry(namespace, 3);
+ fillRegistryDynamic(nonBundleContributor);
+ checkRegistry(namespace, 6);
+
+ stopRegistry();
+ simpleRegistry = startRegistry();
+
+ checkRegistry(namespace, 3);
+ fillRegistryDynamic(nonBundleContributor);
+ checkRegistry(namespace, 6);
+ }
+
+ private void fillRegistryStatic(IContributor contributor) {
+ processXMLContribution(contributor, getXML("MergeStatic.xml"), true); //$NON-NLS-1$
+ }
+
+ private void fillRegistryDynamic(IContributor contributor) {
+ processXMLContribution(contributor, getXML("MergeDynamic.xml"), false); //$NON-NLS-1$
+ }
+
+ private void checkRegistry(String namespace, int expectedExtensions) {
+ IExtensionPoint extensionPoint = simpleRegistry.getExtensionPoint(qualifiedName(namespace, "MergeStatic")); //$NON-NLS-1$
+ assertNotNull(extensionPoint);
+ IExtension[] extensions = simpleRegistry.getExtensions(namespace);
+ assertNotNull(extensions);
+ assertEquals(expectedExtensions, extensions.length);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/SimpleRegistryTests.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/SimpleRegistryTests.java
new file mode 100644
index 000000000..9d9219340
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/SimpleRegistryTests.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Julian Honnen
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Julian Honnen - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ XMLExtensionCreateTest.class,
+ DirectExtensionCreateTest.class,
+ XMLExecutableExtensionTest.class,
+ DirectExtensionCreateTwoRegistriesTest.class,
+ TokenAccessTest.class,
+ XMLExtensionCreateEclipseTest.class,
+ DirectExtensionRemoveTest.class,
+ MergeContributionTest.class,
+ DuplicatePointsTest.class
+})
+public class SimpleRegistryTests {
+ // intentionally left blank
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/TokenAccessTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/TokenAccessTest.java
new file mode 100644
index 000000000..14bbd702a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/TokenAccessTest.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.RegistryFactory;
+
+/**
+ * Tests registry token-based access rules.
+ * @since 3.2
+ */
+public class TokenAccessTest extends TestCase {
+
+ public TokenAccessTest() {
+ super();
+ }
+
+ public TokenAccessTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Tests token access to sensetive registry methods
+ */
+ public void testControlledAccess() {
+ Object tokenGood = new Object();
+ Object tokenBad = new Object();
+
+ // registry created with no token
+ IExtensionRegistry registry = RegistryFactory.createRegistry(null, null, null);
+ assertNotNull(registry);
+ // and stopped with no token - should be no exception
+ registry.stop(null);
+
+ // registry created with no token
+ registry = RegistryFactory.createRegistry(null, null, null);
+ assertNotNull(registry);
+ // and stopped with a bad - should be no exception
+ registry.stop(tokenBad);
+
+ // registry created with a good token
+ registry = RegistryFactory.createRegistry(null, tokenGood, null);
+ assertNotNull(registry);
+ // and stopped with a good token - should be no exception
+ registry.stop(tokenGood);
+
+ // registry created with a good token
+ registry = RegistryFactory.createRegistry(null, tokenGood, null);
+ assertNotNull(registry);
+ // and stopped with a bad token - should be an exception
+ boolean bException = false;
+ try {
+ registry.stop(tokenBad);
+ } catch (IllegalArgumentException e) {
+ // this is good; this is expected
+ bException = true;
+ }
+ assertTrue(bException);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExecutableExtensionTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExecutableExtensionTest.java
new file mode 100644
index 000000000..990f58c1c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExecutableExtensionTest.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import java.io.File;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+import org.eclipse.equinox.common.tests.registry.simple.utils.ExeExtensionStrategy;
+import org.eclipse.equinox.common.tests.registry.simple.utils.ExecutableRegistryObject;
+
+/**
+ * Tests that executable extensions present in the simple registry actually
+ * gets processed.
+ * @since 3.2
+ */
+public class XMLExecutableExtensionTest extends BaseExtensionRegistryRun {
+
+ public XMLExecutableExtensionTest() {
+ super();
+ }
+
+ public XMLExecutableExtensionTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Provide own class loader to the registry executable element strategry
+ * @return - open extension registry
+ */
+ @Override
+ protected IExtensionRegistry startRegistry() {
+ // use plugin's metadata directory to save cache data
+ IPath userDataPath = getStateLocation();
+ File[] registryLocations = new File[] {new File(userDataPath.toOSString())};
+ boolean[] readOnly = new boolean[] {false};
+ RegistryStrategy registryStrategy = new ExeExtensionStrategy(registryLocations, readOnly);
+ return RegistryFactory.createRegistry(registryStrategy, masterToken, userToken);
+ }
+
+ public void testExecutableExtensionCreation() {
+ // Test with non-bundle contributor
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor("ABC"); //$NON-NLS-1$
+ assertFalse(ExecutableRegistryObject.createCalled);
+
+ fillRegistry(nonBundleContributor);
+ assertFalse(ExecutableRegistryObject.createCalled);
+
+ checkRegistry(nonBundleContributor.getName());
+ assertTrue(ExecutableRegistryObject.createCalled);
+ }
+
+ private void fillRegistry(IContributor contributor) {
+ processXMLContribution(contributor, getXML("ExecutableExtension.xml")); //$NON-NLS-1$
+ }
+
+ private void checkRegistry(String namespace) {
+ IConfigurationElement[] elements = simpleRegistry.getConfigurationElementsFor(qualifiedName(namespace, "XMLExecutableExtPoint")); //$NON-NLS-1$
+ assertTrue(elements.length == 1);
+ for (IConfigurationElement element : elements) {
+ try {
+ Object object = element.createExecutableExtension("class"); //$NON-NLS-1$
+ assertNotNull(object);
+ } catch (CoreException e) {
+ assertTrue(false);
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateEclipseTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateEclipseTest.java
new file mode 100644
index 000000000..38f28450d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateEclipseTest.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import java.io.IOException;
+import java.net.URL;
+import org.eclipse.core.internal.registry.ExtensionRegistry;
+import org.eclipse.core.runtime.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * Check dynamic contribution into the Eclipse registry itself.
+ * @since 3.2
+ */
+public class XMLExtensionCreateEclipseTest extends BaseExtensionRegistryRun {
+
+ public void testDynamicContribution() {
+ // specify this bundle as a contributor
+ Bundle thisBundle = FrameworkUtil.getBundle(getClass());
+ IContributor thisContributor = ContributorFactoryOSGi.createContributor(thisBundle);
+ fillRegistry(thisContributor);
+ checkRegistry(thisContributor.getName());
+ }
+
+ private void fillRegistry(IContributor contributor) {
+ try {
+ Object userKey = ((ExtensionRegistry) RegistryFactory.getRegistry()).getTemporaryUserToken();
+ URL xmlURL = getXML("DynamicExtension.xml"); //$NON-NLS-1$
+ RegistryFactory.getRegistry().addContribution(xmlURL.openStream(), contributor, false, xmlURL.getFile(), null, userKey);
+ } catch (IOException eFile) {
+ fail(eFile.getMessage());
+ return;
+ }
+ }
+
+ private void checkRegistry(String namespace) {
+ IExtensionRegistry eclipseRegistry = RegistryFactory.getRegistry();
+ String uniqueId = qualifiedName(namespace, "XMLDirectExtPoint"); //$NON-NLS-1$
+ IExtensionPoint dynamicExtensionPoint = eclipseRegistry.getExtensionPoint(uniqueId);
+ assertNotNull(dynamicExtensionPoint);
+ IConfigurationElement[] elements = eclipseRegistry.getConfigurationElementsFor(uniqueId);
+ assertTrue(elements.length == 1);
+ for (IConfigurationElement element : elements) {
+ assertTrue("org.eclipse.equinox.common.tests.registry.simple.utils.ExecutableRegistryObject".equals(element.getAttribute("class")));
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateTest.java
new file mode 100644
index 000000000..94d1e7635
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/XMLExtensionCreateTest.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.common.tests.registry.simple.utils.SimpleRegistryListener;
+
+/**
+ * Tests addition of extension point and the extension to the registry via
+ * XML contribution. Makes sure that items are actually added; checks
+ * listener notification; reloads registry from cache and re-checks the data.
+ *
+ * @since 3.2
+ */
+public class XMLExtensionCreateTest extends BaseExtensionRegistryRun {
+
+ public XMLExtensionCreateTest() {
+ super();
+ }
+
+ public XMLExtensionCreateTest(String name) {
+ super(name);
+ }
+
+ public void testExtensionPointAddition() {
+ SimpleRegistryListener listener = new SimpleRegistryListener();
+ listener.register(simpleRegistry);
+
+ // Test with non-bundle contributor
+ IContributor nonBundleContributor = ContributorFactorySimple.createContributor("ABC"); //$NON-NLS-1$
+ fillRegistry(nonBundleContributor);
+
+ String namespace = nonBundleContributor.getName();
+ checkListener(namespace, listener);
+ checkRegistry(nonBundleContributor.getName());
+
+ listener.unregister(simpleRegistry);
+
+ // check the cache: stop -> re-start
+ stopRegistry();
+ startRegistry();
+ checkRegistry(nonBundleContributor.getName());
+ }
+
+ private void fillRegistry(IContributor contributor) {
+ // Add extension point
+ processXMLContribution(contributor, getXML("ExtensionPoint.xml")); //$NON-NLS-1$
+ // Add extension
+ processXMLContribution(contributor, getXML("Extension.xml")); //$NON-NLS-1$
+ }
+
+ private void checkRegistry(String namespace) {
+ IExtensionPoint extensionPoint = simpleRegistry.getExtensionPoint(qualifiedName(namespace, "XMLDirectExtPoint")); //$NON-NLS-1$
+ assertNotNull(extensionPoint);
+ IExtension[] namespaceExtensions = simpleRegistry.getExtensions(namespace);
+ assertNotNull(namespaceExtensions);
+ assertTrue(namespaceExtensions.length == 1);
+ IExtension[] extensions = extensionPoint.getExtensions();
+ assertNotNull(extensions);
+ assertTrue(extensions.length == 1);
+ for (IExtension extension : extensions) {
+ String extensionId = extension.getUniqueIdentifier();
+ assertTrue(extensionId.equals(qualifiedName(namespace, "XMLDirectExtensionID"))); //$NON-NLS-1$
+ String extensionNamespace = extension.getNamespaceIdentifier();
+ assertTrue(extensionNamespace.equals(namespace));
+ String extensionContributor = extension.getContributor().getName();
+ assertTrue(extensionContributor.equals(namespace));
+ IConfigurationElement[] configElements = extension.getConfigurationElements();
+ assertNotNull(configElements);
+ for (IConfigurationElement configElement : configElements) {
+ String configElementName = configElement.getName();
+ assertTrue(configElementName.equals("StorageDevice")); //$NON-NLS-1$
+ String[] attributeNames = configElement.getAttributeNames();
+ assertTrue(attributeNames.length == 1);
+ IConfigurationElement[] configElementChildren = configElement.getChildren();
+ assertTrue(configElementChildren.length == 2);
+ }
+ }
+ }
+
+ private void checkListener(String namespace, SimpleRegistryListener listener) {
+ IRegistryChangeEvent event = listener.getEvent(5000);
+ IExtensionDelta[] deltas = event.getExtensionDeltas();
+ assertTrue(deltas.length == 1); // only one notification
+ for (IExtensionDelta delta : deltas) {
+ assertTrue(delta.getKind() == IExtensionDelta.ADDED);
+ IExtensionPoint theExtensionPoint = delta.getExtensionPoint();
+ IExtension theExtension = delta.getExtension();
+ String Id1 = theExtension.getExtensionPointUniqueIdentifier();
+ String Id2 = theExtensionPoint.getUniqueIdentifier();
+ assertTrue(Id1.equals(Id2)); // check connectivity
+ assertTrue(Id1.equals(qualifiedName(namespace, "XMLDirectExtPoint"))); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExeExtensionStrategy.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExeExtensionStrategy.java
new file mode 100644
index 000000000..5884237fd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExeExtensionStrategy.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple.utils;
+
+import java.io.File;
+import org.eclipse.core.runtime.spi.RegistryContributor;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+
+/**
+ * Registry strategy that uses class loader from this bundle to process executable
+ * extensions.
+ * @since 3.2
+ */
+public class ExeExtensionStrategy extends RegistryStrategy {
+
+ public ExeExtensionStrategy(File[] theStorageDir, boolean[] cacheReadOnly) {
+ super(theStorageDir, cacheReadOnly);
+ }
+
+ @Override
+ public Object createExecutableExtension(RegistryContributor defaultContributor, String className, String requestedContributorName) {
+ Class<?> classInstance = null;
+ try {
+ classInstance = Class.forName(className);
+ } catch (ClassNotFoundException e1) {
+ e1.printStackTrace();
+ return null;
+ }
+
+ // create a new instance
+ Object result = null;
+ try {
+ result = classInstance.getDeclaredConstructor().newInstance();
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ return null;
+ }
+
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExecutableRegistryObject.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExecutableRegistryObject.java
new file mode 100644
index 000000000..a93939278
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/ExecutableRegistryObject.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple.utils;
+
+import org.eclipse.core.runtime.*;
+
+/**
+ * Test class for the executable extensions.
+ * @since 3.2
+ */
+public class ExecutableRegistryObject implements IExecutableExtensionFactory {
+
+ public static boolean createCalled = false;
+
+ public ExecutableRegistryObject() {
+ // intentionally left empty
+ }
+
+ @Override
+ public Object create() throws CoreException {
+ if (createCalled) {
+ Status status = new Status(IStatus.ERROR, "org.eclipse.core.tests.runtime", 0, "Duplicate executable extension call.", null); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new CoreException(status);
+ }
+ createCalled = true;
+ return new ExecutableRegistryObject();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/HiddenLogRegistryStrategy.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/HiddenLogRegistryStrategy.java
new file mode 100644
index 000000000..513e7792b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/HiddenLogRegistryStrategy.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple.utils;
+
+import java.io.File;
+import org.eclipse.core.internal.registry.RegistryMessages;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+
+/**
+ * Registry strategy that keeps log output in an accessible string.
+ * @since 3.2
+ */
+public class HiddenLogRegistryStrategy extends RegistryStrategy {
+
+ public static String output;
+
+ public HiddenLogRegistryStrategy(File[] theStorageDir, boolean[] cacheReadOnly) {
+ super(theStorageDir, cacheReadOnly);
+ }
+
+ @Override
+ public boolean debug() {
+ return true;
+ }
+
+ @Override
+ public void log(IStatus status) {
+ log(status, null);
+ }
+
+ // Same as RegistryStrategy, but logs into String
+ public void log(IStatus status, String prefix) {
+ String message = status.getMessage();
+ int severity = status.getSeverity();
+
+ String statusMsg;
+ switch (severity) {
+ case IStatus.ERROR :
+ statusMsg = RegistryMessages.log_error;
+ break;
+ case IStatus.WARNING :
+ statusMsg = RegistryMessages.log_warning;
+ break;
+ default :
+ statusMsg = RegistryMessages.log_log;
+ break;
+ }
+ statusMsg += message;
+
+ if (prefix != null)
+ statusMsg = prefix + statusMsg;
+ output += statusMsg;
+
+ // print out children as well
+ IStatus[] children = status.getChildren();
+ if (children.length != 0) {
+ String newPrefix;
+ if (prefix == null)
+ newPrefix = "\t"; //$NON-NLS-1$
+ else
+ newPrefix = prefix + "\t"; //$NON-NLS-1$
+ for (IStatus child : children) {
+ log(child, newPrefix);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/SimpleRegistryListener.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/SimpleRegistryListener.java
new file mode 100644
index 000000000..f801dc466
--- /dev/null
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/registry/simple/utils/SimpleRegistryListener.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2015 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Alexander Kurtakov <akurtako@redhat.com> - bug 458490
+ *******************************************************************************/
+package org.eclipse.equinox.common.tests.registry.simple.utils;
+
+import java.util.LinkedList;
+import java.util.List;
+import org.eclipse.core.runtime.*;
+
+/**
+ * Allows test cases to wait for event notification so they can make assertions on the event.
+ * Similar to org.eclipse.core.tests.harness.TestRegistryChangeListener.
+ * @since 3.2
+ */
+public class SimpleRegistryListener implements IRegistryChangeListener {
+
+ private List<IRegistryChangeEvent> events = new LinkedList<>();
+
+ @Override
+ public synchronized void registryChanged(IRegistryChangeEvent newEvent) {
+ events.add(newEvent);
+ notify();
+ }
+
+ /**
+ * Returns the first event that is received, blocking for at most <code>timeout</code> milliseconds.
+ * Returns <code>null</code> if a event was not received for the time allowed.
+ *
+ * @param timeout the maximum time to wait in milliseconds. If zero, this method will
+ * block until an event is received
+ * @return the first event received, or <code>null</code> if none was received
+ */
+ public synchronized IRegistryChangeEvent getEvent(long timeout) {
+ if (!events.isEmpty())
+ return events.remove(0);
+ try {
+ wait(timeout);
+ } catch (InterruptedException e) {
+ // nothing to do
+ }
+ return events.isEmpty() ? null : events.remove(0);
+ }
+
+ public void register(IExtensionRegistry registry) {
+ registry.addRegistryChangeListener(this);
+ }
+
+ public void unregister(IExtensionRegistry registry) {
+ registry.removeRegistryChangeListener(this);
+ }
+}

Back to the top