diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.common.tests/src/org/eclipse')
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); + } +} |