diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java index fb9b5be8379..5af3487e58d 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java @@ -26,6 +26,7 @@ public class AllLanguageSettingsProvidersTests { suite.addTest(LanguageSettingsManagerTests.suite()); suite.addTest(LanguageSettingsSerializableTests.suite()); suite.addTest(LanguageSettingsPersistenceProjectTests.suite()); + suite.addTest(LanguageSettingsListenersTests.suite()); suite.addTest(LanguageSettingsScannerInfoProviderTests.suite()); return suite; } diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java index 3a95102a247..d7eb6af64de 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java @@ -37,11 +37,11 @@ import org.eclipse.core.runtime.Path; public class LanguageSettingsExtensionsTests extends TestCase { // These should match corresponding entries defined in plugin.xml private static final String EXTENSION_BASE_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider"; - private static final String EXTENSION_BASE_PROVIDER_NAME = "Test Plugin Language Settings Base Provider"; + private static final String EXTENSION_BASE_PROVIDER_NAME = "Test Plugin Mock Language Settings Base Provider"; private static final String EXTENSION_BASE_PROVIDER_LANG_ID = "org.eclipse.cdt.core.tests.language.id"; private static final String EXTENSION_BASE_PROVIDER_PARAMETER = "custom parameter"; private static final String EXTENSION_CUSTOM_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.language.settings.provider"; - private static final String EXTENSION_CUSTOM_PROVIDER_NAME = "Test Plugin Language Settings Provider"; + private static final String EXTENSION_CUSTOM_PROVIDER_NAME = "Test Plugin Mock Language Settings Provider"; private static final String EXTENSION_BASE_SUBCLASS_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider.subclass"; private static final String EXTENSION_BASE_SUBCLASS_PROVIDER_PARAMETER = "custom parameter subclass"; private static final String EXTENSION_SERIALIZABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.serializable.language.settings.provider"; diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsListenersTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsListenersTests.java new file mode 100644 index 00000000000..7a527624432 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsListenersTests.java @@ -0,0 +1,494 @@ +/******************************************************************************* + * Copyright (c) 2011, 2011 Andrew Gvozdev and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.language.settings.providers; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.testplugin.ResourceHelper; +import org.eclipse.core.resources.IProject; + +/** + * Test cases testing LanguageSettingsProvider functionality + */ +public class LanguageSettingsListenersTests extends TestCase { + // Must match provider id defined as extension point + private static final String EXTENSION_REGISTERER_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.listener.registerer.provider"; + + private static final String PROVIDER_1 = "test.provider.1.id"; + private static final String PROVIDER_NAME_1 = "test.provider.1.name"; + private static final String PROVIDER_CUSTOM_GLOBAL = "test.provider.custom.global.id"; + private static final String PROVIDER_CUSTOM_GLOBAL_NAME = "test.provider.custom.global.name"; + + /** + * Constructor. + * @param name - name of the test. + */ + public LanguageSettingsListenersTests(String name) { + super(name); + + } + + @Override + protected void setUp() throws Exception { + } + + @Override + protected void tearDown() throws Exception { + LanguageSettingsManager.setWorkspaceProviders(null); + ResourceHelper.cleanUp(); + } + + /** + * @return - new TestSuite. + */ + public static TestSuite suite() { + return new TestSuite(LanguageSettingsListenersTests.class); + } + + /** + * main function of the class. + * + * @param args - arguments + */ + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + /** + */ + public void testListenerRegisterer_CheckExtensionProvider() throws Exception { + // check if extension provider exists + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(workspaceProvider); + assertNotNull(rawProvider); + // global listeners providers get registered only lazily + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + + /** + */ + public void testListenerRegisterer_OneOwnedByCfg() throws Exception { + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + + { + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + // create a provider + ILanguageSettingsProvider mockProvider = new MockListenerRegisterer(PROVIDER_1, PROVIDER_NAME_1); + List providers = new ArrayList(); + providers.add(mockProvider); + cfgDescription.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(PROVIDER_1)); + } + { + // close the project + project.close(null); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_1)); + } + { + // reopen the project + project.open(null); + CoreModel.getDefault().getProjectDescription(project); + assertEquals(1, MockListenerRegisterer.getCount(PROVIDER_1)); + // and delete + project.delete(true, null); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_1)); + } + + } + + /** + */ + public void testListenerRegisterer_TwoOwnedByCfgs() throws Exception { + IProject project = ResourceHelper.createCDTProject(this.getName(), null, new String[] { + "org.eclipse.cdt.core.tests.configuration.id.1", + "org.eclipse.cdt.core.tests.configuration.id.2", + }); + + { + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(2, cfgDescriptions.length); + ICConfigurationDescription cfgDescription1 = cfgDescriptions[0]; + ICConfigurationDescription cfgDescription2 = cfgDescriptions[1]; + + { + // create a provider 1 + ILanguageSettingsProvider mockProvider = new MockListenerRegisterer(PROVIDER_1, PROVIDER_NAME_1); + List providers = new ArrayList(); + providers.add(mockProvider); + cfgDescription1.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription1.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + } + { + // create a provider 2 + ILanguageSettingsProvider mockProvider = new MockListenerRegisterer(PROVIDER_1, PROVIDER_NAME_1); + List providers = new ArrayList(); + providers.add(mockProvider); + cfgDescription2.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription2.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + } + + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + assertEquals(2, MockListenerRegisterer.getCount(PROVIDER_1)); + } + { + // close the project + project.close(null); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_1)); + } + { + // reopen the project + project.open(null); + CoreModel.getDefault().getProjectDescription(project); + assertEquals(2, MockListenerRegisterer.getCount(PROVIDER_1)); + // and delete + project.delete(true, null); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_1)); + } + + } + + /** + */ + public void testListenerRegisterer_OneGlobal() throws Exception { + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + { + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + // add global provider + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // close the project + project.close(null); + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // reopen the project + project.open(null); + CoreModel.getDefault().getProjectDescription(project); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + // and delete + project.delete(true, null); + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + + } + + /** + */ + public void testListenerRegisterer_TwoGlobal() throws Exception { + IProject project = ResourceHelper.createCDTProject(this.getName(), null, new String[] { + "org.eclipse.cdt.core.tests.configuration.id.1", + "org.eclipse.cdt.core.tests.configuration.id.2", + }); + + { + // retrieve global provider + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(2, cfgDescriptions.length); + ICConfigurationDescription cfgDescription1 = cfgDescriptions[0]; + ICConfigurationDescription cfgDescription2 = cfgDescriptions[1]; + + { + // add global provider to configuration 1 + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription1.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription1.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + } + { + // add global provider to configuration 2 + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription2.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription2.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + } + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // close the project + project.close(null); + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // reopen the project + project.open(null); + CoreModel.getDefault().getProjectDescription(project); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + // and delete + project.delete(true, null); + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + } + + /** + */ + public void testListenerRegisterer_TwoGlobalMinusOne() throws Exception { + IProject project = ResourceHelper.createCDTProject(this.getName(), null, new String[] { + "org.eclipse.cdt.core.tests.configuration.id.1", + "org.eclipse.cdt.core.tests.configuration.id.2", + }); + + { + // retrieve workspace provider + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(2, cfgDescriptions.length); + ICConfigurationDescription cfgDescription1 = cfgDescriptions[0]; + ICConfigurationDescription cfgDescription2 = cfgDescriptions[1]; + + { + // add global provider to configuration 1 + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription1.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription1.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + } + { + // add global provider to configuration 2 + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription2.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription2.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + } + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // retrieve workspace provider + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(2, cfgDescriptions.length); + ICConfigurationDescription cfgDescription1 = cfgDescriptions[0]; + ICConfigurationDescription cfgDescription2 = cfgDescriptions[1]; + + { + // remove global provider from configuration 1 + List providers = new ArrayList(); + cfgDescription1.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription1.getLanguageSettingProviders(); + assertEquals(0, storedProviders.size()); + } + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // close the project + project.close(null); + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + } + + /** + */ + public void testListenerRegisterer_GlobalProviderTwoProjects() throws Exception { + // create project 1 + IProject project_1 = ResourceHelper.createCDTProjectWithConfig(this.getName() + ".1"); + { + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project_1); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + // add global provider + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project_1, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + + // create project 2 + IProject project_2 = ResourceHelper.createCDTProjectWithConfig(this.getName() + ".2"); + { + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project_2); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + // add global provider + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_REGISTERER_PROVIDER_ID); + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project_2, writableProjDescription); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + + { + // close project 1 + project_1.close(null); + assertEquals(1, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + { + // close project 2 + project_2.close(null); + assertEquals(0, MockListenerRegisterer.getCount(EXTENSION_REGISTERER_PROVIDER_ID)); + } + + } + + /** + */ + public void testListenerRegisterer_GlobalProviderNotInUse() throws Exception { + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(PROVIDER_CUSTOM_GLOBAL); + + // the global custom provider has not been added yet + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(workspaceProvider); + assertNull(rawProvider); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + + List workspaceProvidersOriginal = LanguageSettingsManager.getWorkspaceProviders(); + { + // add global provider which is not engaged + ILanguageSettingsProvider provider = new MockListenerRegisterer(PROVIDER_CUSTOM_GLOBAL, PROVIDER_CUSTOM_GLOBAL_NAME); + List providers = new ArrayList(workspaceProvidersOriginal); + providers.add(provider); + LanguageSettingsManager.setWorkspaceProviders(providers); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + { + // remove global provider and restore original list + List providers = new ArrayList(workspaceProvidersOriginal); + LanguageSettingsManager.setWorkspaceProviders(providers); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + } + + /** + */ + public void testListenerRegisterer_GlobalProviderAddRemoveOutsideTheProject() throws Exception { + ILanguageSettingsProvider workspaceProvider = LanguageSettingsManager.getWorkspaceProvider(PROVIDER_CUSTOM_GLOBAL); + + // the global custom provider has not been added yet + ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(workspaceProvider); + assertNull(rawProvider); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + + // prepare project + List workspaceProvidersOriginal = LanguageSettingsManager.getWorkspaceProviders(); + IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName()); + { + // get project descriptions + ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project); + assertNotNull(writableProjDescription); + ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations(); + assertEquals(1, cfgDescriptions.length); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + // add global provider + List providers = new ArrayList(); + providers.add(workspaceProvider); + cfgDescription.setLanguageSettingProviders(providers); + List storedProviders = cfgDescription.getLanguageSettingProviders(); + assertEquals(1, storedProviders.size()); + + // write to project description + CoreModel.getDefault().setProjectDescription(project, writableProjDescription); + // the global custom provider has not been added yet + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + + { + // add global provider + ILanguageSettingsProvider provider = new MockListenerRegisterer(PROVIDER_CUSTOM_GLOBAL, PROVIDER_CUSTOM_GLOBAL_NAME); + List providers = new ArrayList(); + providers.add(provider); + LanguageSettingsManager.setWorkspaceProviders(providers); + assertEquals(1, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + { + // remove global provider + List providers = new ArrayList(workspaceProvidersOriginal); + LanguageSettingsManager.setWorkspaceProviders(providers); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + + { + // close project + project.close(null); + assertEquals(0, MockListenerRegisterer.getCount(PROVIDER_CUSTOM_GLOBAL)); + } + } + +} + + diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java index ebff84f3c76..d6732472b4b 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java @@ -44,7 +44,7 @@ public class LanguageSettingsManagerTests extends TestCase { // Should match id of extension point defined in plugin.xml private static final String EXTENSION_BASE_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider"; private static final String EXTENSION_EDITABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.editable.language.settings.provider"; - private static final String EXTENSION_EDITABLE_PROVIDER_NAME = "Test Plugin Editable Language Settings Provider"; + private static final String EXTENSION_EDITABLE_PROVIDER_NAME = "Test Plugin Mock Editable Language Settings Provider"; private static final IFile FILE_0 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/project/path0")); private static final String CFG_ID = "test.configuration.id"; diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java index dbb5f954000..f08b723b4e6 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsPersistenceProjectTests.java @@ -43,9 +43,9 @@ import org.w3c.dom.Element; public class LanguageSettingsPersistenceProjectTests extends TestCase { private static final String LANGUAGE_SETTINGS_PROJECT_XML = ".settings/language.settings.xml"; private static final String LANGUAGE_SETTINGS_WORKSPACE_XML = "language.settings.xml"; - // Should match id of extension point defined in plugin.xml + // Should match extension points defined in plugin.xml private static final String EXTENSION_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider.subclass"; - private static final String EXTENSION_PROVIDER_NAME = "Test Plugin Base Provider Subclass"; + private static final String EXTENSION_PROVIDER_NAME = "Test Plugin Mock Base Provider Subclass"; private static final String EXTENSION_SERIALIZABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.serializable.language.settings.provider"; private static final String CFG_ID = "test.configuration.id.0"; diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/MockListenerRegisterer.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/MockListenerRegisterer.java new file mode 100644 index 00000000000..2d4a05c4b21 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/MockListenerRegisterer.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2011, 2011 Andrew Gvozdev and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.language.settings.providers; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider; +import org.eclipse.core.runtime.Assert; + +/** + * Language Settings Provider that keeps count how many times it has been registered. + */ +public class MockListenerRegisterer extends LanguageSettingsSerializable implements ILanguageSettingsEditableProvider, ICListenerRegisterer { + private static MockListenerManager mockListenerManager = new MockListenerManager(); + + private static class MockListenerManager { + private class ListenerCount { + private MockListenerRegisterer listener; + private int count; + public ListenerCount(MockListenerRegisterer l, int cnt) { + listener = l; + count = cnt; + } + } + private List register = new ArrayList(); + + public void registerListener(MockListenerRegisterer listener) { + for (ListenerCount lc : register) { + if (lc.listener == listener) { + lc.count++; + return; + } + } + + register.add(new ListenerCount(listener, 1)); + } + + public void unregisterListener(MockListenerRegisterer listener) { + for (ListenerCount lc : register) { + if (lc.listener == listener) { + lc.count--; + Assert.isTrue(lc.count>=0); + return; + } + } + + // attempt to unregister non-registered listener + Assert.isTrue(false); + } + + /** + * Note that that count includes all listeners with that id. + */ + public int getCount(String id) { + int count = 0; + + for (ListenerCount lc : register) { + if (lc.listener.getId().equals(id)) { + count = count + lc.count; + } + } + + return count; + } + } + + public MockListenerRegisterer() { + super(); + } + public MockListenerRegisterer(String id, String name) { + super(id, name); + } + public void registerListener(ICConfigurationDescription cfgDescription) { + mockListenerManager.registerListener(this); + } + + public void unregisterListener() { + mockListenerManager.unregisterListener(this); + } + @Override + public MockListenerRegisterer cloneShallow() throws CloneNotSupportedException { + return (MockListenerRegisterer) super.cloneShallow(); + } + @Override + public MockListenerRegisterer clone() throws CloneNotSupportedException { + return (MockListenerRegisterer) super.clone(); + } + + public static int getCount(String id) { + return mockListenerManager.getCount(id); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/plugin.xml b/core/org.eclipse.cdt.core.tests/plugin.xml index 4c4418fc9fe..c8588c34993 100644 --- a/core/org.eclipse.cdt.core.tests/plugin.xml +++ b/core/org.eclipse.cdt.core.tests/plugin.xml @@ -201,7 +201,7 @@ --> @@ -250,12 +250,12 @@ + name="Test Plugin Mock Language Settings Provider"> + name="Test Plugin Mock Serializable Language Settings Provider"> + name="Test Plugin Mock Editable Language Settings Provider"> + + + + diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ICListenerRegisterer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ICListenerRegisterer.java new file mode 100644 index 00000000000..df953e20808 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ICListenerRegisterer.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2011, 2011 Andrew Gvozdev and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andrew Gvozdev - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.language.settings.providers; + +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; + + +/** + * Helper class to allow listeners self-register/dispose. Called by cdt core. + * TODO - expand in more detail. + */ +public interface ICListenerRegisterer { + public void registerListener(ICConfigurationDescription cfgDescription); + public void unregisterListener(); +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java index e81dd9ca1ca..0ef6a684080 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.language.settings.providers.ICListenerRegisterer; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable; @@ -33,10 +34,6 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -66,13 +63,22 @@ public class LanguageSettingsProvidersSerializer { private static Map rawGlobalWorkspaceProviders = new HashMap(); private static Map globalWorkspaceProviders = new HashMap(); - private static class LanguageSettingsWorkspaceProvider implements ILanguageSettingsProvider, IResourceChangeListener { - private String providerId; - private int registrationCount = 0; + private static class ListenerAssociation { + private ICListenerRegisterer listener; + private ICConfigurationDescription cfgDescription; + + public ListenerAssociation(ICListenerRegisterer li, ICConfigurationDescription cfgd) { + listener = li; + cfgDescription = cfgd; + } + } - public LanguageSettingsWorkspaceProvider(String id) { + private static class LanguageSettingsWorkspaceProvider implements ILanguageSettingsProvider, ICListenerRegisterer { + private String providerId; + private int projectCount = 0; + + private LanguageSettingsWorkspaceProvider(String id) { Assert.isNotNull(id); - Assert.isTrue(id.length()>0); providerId = id; } @@ -117,22 +123,38 @@ public class LanguageSettingsProvidersSerializer { } /** - * {@inheritDoc} - * - * LanguageSettingsWorkspaceProvider delegates event handling to raw provider. - * + * We count number of times workspace provider (not the raw one!) associated + * with a project. If a project includes it multiple times via different configurations + * it still counts as 1. */ - public void resourceChanged(IResourceChangeEvent event) { - // keep in mind that type of rawProvider can change - ILanguageSettingsProvider rawProvider = getRawProvider(); - if (rawProvider instanceof IResourceChangeListener) { - ((IResourceChangeListener) rawProvider).resourceChanged(event); - } + private int getProjectCount() { + return projectCount; } - synchronized int incrementListenerCount(int inc) { - registrationCount += inc; - return registrationCount; + private synchronized int incrementProjectCount() { + projectCount++; + return projectCount; + } + + private synchronized int decrementProjectCount() { + projectCount--; + return projectCount; + } + + public void registerListener(ICConfigurationDescription cfgDescription) { + // keep in mind that rawProvider can change + ILanguageSettingsProvider rawProvider = getRawProvider(); + if (rawProvider instanceof ICListenerRegisterer) { + ((ICListenerRegisterer) rawProvider).registerListener(null); + } + } + + public void unregisterListener() { + // keep in mind that rawProvider can change + ILanguageSettingsProvider rawProvider = getRawProvider(); + if (rawProvider instanceof ICListenerRegisterer) { + ((ICListenerRegisterer) rawProvider).unregisterListener(); + } } } @@ -142,9 +164,8 @@ public class LanguageSettingsProvidersSerializer { try { loadLanguageSettingsWorkspace(); } catch (Throwable e) { + // log and swallow any exception CCorePlugin.log("Error loading workspace language settings providers", e); //$NON-NLS-1$ - } finally { - // swallow any exception } } @@ -195,8 +216,8 @@ public class LanguageSettingsProvidersSerializer { } } + List rawProviders = new ArrayList(); if (providers!=null) { - List rawProviders = new ArrayList(); for (ILanguageSettingsProvider provider : providers) { if (isWorkspaceProvider(provider)) { provider = rawGlobalWorkspaceProviders.get(provider.getId()); @@ -210,6 +231,27 @@ public class LanguageSettingsProvidersSerializer { } } + List oldListeners = selectListeners(rawGlobalWorkspaceProviders.values()); + List newListeners = selectListeners(rawProviders); + + for (ICListenerRegisterer oldListener : oldListeners) { + if (!isObjectInTheList(newListeners, oldListener)) { + LanguageSettingsWorkspaceProvider wspProvider = (LanguageSettingsWorkspaceProvider) globalWorkspaceProviders.get(((ILanguageSettingsProvider)oldListener).getId()); + if (wspProvider != null && wspProvider.getProjectCount() > 0) { + oldListener.unregisterListener(); + } + } + } + + for (ICListenerRegisterer newListener : newListeners) { + if (!isObjectInTheList(oldListeners, newListener)) { + LanguageSettingsWorkspaceProvider wspProvider = (LanguageSettingsWorkspaceProvider) globalWorkspaceProviders.get(((ILanguageSettingsProvider)newListener).getId()); + if (wspProvider != null && wspProvider.getProjectCount() > 0) { + newListener.registerListener(null); + } + } + } + rawGlobalWorkspaceProviders = rawWorkspaceProviders; } @@ -654,36 +696,39 @@ public class LanguageSettingsProvidersSerializer { } } - /** - * TODO - remove me - * Temporary method to report inconsistency in log. - */ - @Deprecated - public static void assertConsistency(ICConfigurationDescription cfgDescription) { - List listeners = new ArrayList(); - List providers = cfgDescription.getLanguageSettingProviders(); - for (ILanguageSettingsProvider provider : providers) { - if (isObjectInTheList(listeners, provider)) { - IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Inconsistent state, duplicate LSP in project description " + provider); - CoreException e = new CoreException(status); - CCorePlugin.log(e); - } - listeners.add(provider); + private static boolean isObjectInTheList(Collection list, T element) { + // list.contains(element) won't do it as we are interested in exact object, not in equal object + for (T elem : list) { + if (elem == element) + return true; } + return false; } - + + private static boolean isListenerInTheListOfAssociations(Collection list, ICListenerRegisterer element) { + // list.contains(element) won't do it as we are interested in exact object, not in equal object + for (ListenerAssociation la : list) { + if (la.listener == element) + return true; + } + return false; + } + /** - * Get a providers list including only providers of type IResourceChangeListener + * Get a providers list including only providers of type ICListenerRegisterer * for a given project description - collecting from all configurations. */ - private static List getResourceChangeListeners(ICProjectDescription prjDescription) { - List listeners = new ArrayList(); + private static List getListeners(ICProjectDescription prjDescription) { + List listeners = new ArrayList(); if (prjDescription != null) { for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) { List providers = cfgDescription.getLanguageSettingProviders(); for (ILanguageSettingsProvider provider : providers) { - if (provider instanceof IResourceChangeListener) { - listeners.add((IResourceChangeListener) provider); + if (provider instanceof ICListenerRegisterer) { + ICListenerRegisterer listener = (ICListenerRegisterer) provider; + if (!isObjectInTheList(listeners, listener)) { + listeners.add(listener); + } } } } @@ -691,6 +736,35 @@ public class LanguageSettingsProvidersSerializer { return listeners; } + private static List selectListeners(Collection values) { + List listeners = new ArrayList(); + for (ILanguageSettingsProvider provider : values) { + if (provider instanceof ICListenerRegisterer) + listeners.add((ICListenerRegisterer) provider); + } + return listeners; + } + + /** + * Get a providers list including only providers of type IResourceChangeListener + * for a given project description - collecting from all configurations. + */ + private static List getListenersAssociations(ICProjectDescription prjDescription) { + List associations = new ArrayList(); + if (prjDescription != null) { + for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) { + List providers = cfgDescription.getLanguageSettingProviders(); + List listeners = selectListeners(providers); + for (ICListenerRegisterer listener : listeners) { + if (!isListenerInTheListOfAssociations(associations, listener)) { + associations.add(new ListenerAssociation(listener, cfgDescription)); + } + } + } + } + return associations; + } + /** * Unregister listeners which are not used anymore and register new listeners. * The method is used when project description is applied to workspace. @@ -706,54 +780,46 @@ public class LanguageSettingsProvidersSerializer { assertConsistency(oldPrjDescription); // TODO - remove me assertConsistency(newPrjDescription); // TODO - remove me - IWorkspace workspace = ResourcesPlugin.getWorkspace(); + List oldListeners = getListeners(oldPrjDescription); + List newAssociations = getListenersAssociations(newPrjDescription); - List oldListeners = getResourceChangeListeners(oldPrjDescription); - List newListeners = getResourceChangeListeners(newPrjDescription); - - for (IResourceChangeListener listener : oldListeners) { - if (!isObjectInTheList(newListeners, listener)) { + for (ICListenerRegisterer oldListener : oldListeners) { + if (!isListenerInTheListOfAssociations(newAssociations, oldListener)) { int count = 0; - if (listener instanceof LanguageSettingsWorkspaceProvider) { - count = ((LanguageSettingsWorkspaceProvider) listener).incrementListenerCount(-1); + if (oldListener instanceof LanguageSettingsWorkspaceProvider) { + count = ((LanguageSettingsWorkspaceProvider) oldListener).decrementProjectCount(); } if (count == 0) { - workspace.removeResourceChangeListener(listener); - // TODO - remove me - CCorePlugin.log(new Status(IStatus.WARNING,CCorePlugin.PLUGIN_ID, oldPrjDescription.getProject() + ": Removed IResourceChangeListener " - + "[" + System.identityHashCode(listener) + "] " - + listener)); + try { + oldListener.unregisterListener(); + } catch (Throwable e) { + // protect from any exceptions from implementers + CCorePlugin.log(e); + } } } } - for (IResourceChangeListener listener : newListeners) { - if (!isObjectInTheList(oldListeners, listener)) { + for (ListenerAssociation newListenerAssociation : newAssociations) { + ICListenerRegisterer newListener = newListenerAssociation.listener; + if (!isObjectInTheList(oldListeners, newListener)) { int count = 1; - if (listener instanceof LanguageSettingsWorkspaceProvider) { - count = ((LanguageSettingsWorkspaceProvider) listener).incrementListenerCount(1); + if (newListener instanceof LanguageSettingsWorkspaceProvider) { + count = ((LanguageSettingsWorkspaceProvider) newListener).incrementProjectCount(); } if (count == 1) { - workspace.addResourceChangeListener(listener); - // TODO - remove me - CCorePlugin.log(new Status(IStatus.WARNING,CCorePlugin.PLUGIN_ID, newPrjDescription.getProject() + ": Added IResourceChangeListener " - + "[" + System.identityHashCode(listener) + "] " - + listener)); + try { + newListener.registerListener(newListenerAssociation.cfgDescription); + } catch (Throwable e) { + // protect from any exceptions from implementers + CCorePlugin.log(e); + } } } } } - private static boolean isObjectInTheList(Collection list, T element) { - // list.contains(element) won't do it as we are interested in exact object, not in equal object - for (T elem : list) { - if (elem == element) - return true; - } - return false; - } - /** * Deep clone of a list of language settings providers. *