diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CConfigurationDescriptionExportSettings.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CConfigurationDescriptionExportSettings.java index e53ffec853f..c9a3e3ffd34 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CConfigurationDescriptionExportSettings.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CConfigurationDescriptionExportSettings.java @@ -24,28 +24,43 @@ import junit.framework.TestSuite; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; /** - * Class for testing exported settings and project references + * Class for testing exported settings and project references. + * This functionality is provided by the CfgExportSettingContainerFactory which plugins + * into the CExternalSettingsManager */ public class CConfigurationDescriptionExportSettings extends BaseTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - ResourceHelper.cleanUp(); - } + CoreModel coreModel = CoreModel.getDefault(); public static TestSuite suite() { return suite(CConfigurationDescriptionExportSettings.class, "_"); } + // Setting entries 1 + final ICLanguageSettingEntry entries[] = new ICLanguageSettingEntry[]{ + new CMacroEntry("a", "b", 0), + new CMacroEntry("c", "d", 0), + new CIncludePathEntry("a/b/c", 0), + new CIncludePathEntry("d/e/f", 0), + }; + + // Setting entries 2 + final ICLanguageSettingEntry entries2[] = new ICLanguageSettingEntry[]{ + new CMacroEntry("a2", "b2", 0), + new CMacroEntry("c2", "d2", 0), + new CIncludePathEntry("a/b/c/2", 0), + new CIncludePathEntry("d/e/f/2", 0), + }; + /** * This tests for simple reference propagation. * It used to live in the Managedbuild testsuite in ProjectModelTests.java @@ -54,7 +69,6 @@ public class CConfigurationDescriptionExportSettings extends BaseTestCase { public void testReferences() throws Exception { final String projectName4 = "test4"; final String projectName5 = "test5"; - CoreModel coreModel = CoreModel.getDefault(); IProject project4 = ResourceHelper.createCDTProjectWithConfig(projectName4); IProject project5 = ResourceHelper.createCDTProjectWithConfig(projectName5); @@ -63,12 +77,6 @@ public class CConfigurationDescriptionExportSettings extends BaseTestCase { ICProjectDescription des5 = coreModel.getProjectDescription(project5); ICConfigurationDescription dess[] = des5.getConfigurations(); - ICLanguageSettingEntry entries[] = new ICLanguageSettingEntry[]{ - new CMacroEntry("a", "b", 0), - new CMacroEntry("c", "d", 0), - new CIncludePathEntry("a/b/c", 0), - new CIncludePathEntry("d/e/f", 0), - }; dess[0].createExternalSetting(null, null, null, entries); dess[0].setActive(); @@ -124,18 +132,9 @@ public class CConfigurationDescriptionExportSettings extends BaseTestCase { * @throws Exception */ public void testProjectImport() throws Exception { - CoreModel coreModel = CoreModel.getDefault(); final IProject libProj = ResourceHelper.createCDTProjectWithConfig("libProj"); final IProject mainProj = ResourceHelper.createCDTProjectWithConfig("mainProj"); - // Settings to set on the lib project - final ICLanguageSettingEntry entries[] = new ICLanguageSettingEntry[]{ - new CMacroEntry("a", "b", 0), - new CMacroEntry("c", "d", 0), - new CIncludePathEntry("a/b/c", 0), - new CIncludePathEntry("d/e/f", 0), - }; - // set the settings on the lib config; reference it from the main config { ICProjectDescription desLib = coreModel.getProjectDescription(libProj); @@ -176,8 +175,8 @@ public class CConfigurationDescriptionExportSettings extends BaseTestCase { libProj.open(null); // Referenced settings should still exist - ICConfigurationDescription cfgMain = coreModel.getProjectDescription(mainProj).getActiveConfiguration(); - ICConfigurationDescription cfgLib = coreModel.getProjectDescription(libProj).getActiveConfiguration(); + ICConfigurationDescription cfgMain = coreModel.getProjectDescription(mainProj, false).getActiveConfiguration(); + ICConfigurationDescription cfgLib = coreModel.getProjectDescription(libProj, false).getActiveConfiguration(); checkEquivContents(cfgLib.getExternalSettings()[0].getEntries(), entries); for (ICLanguageSettingEntry e : entries) { @@ -186,17 +185,293 @@ public class CConfigurationDescriptionExportSettings extends BaseTestCase { } } - private void checkEquivContents(Object[] a1, Object[] a2) { - if(a1 == null){ - assertTrue(a2 == null); + /** + * Tests that updating the exported settings on the active configuration, without updating the set + * of references, is correctly picked up in referencing projects. + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=312575 + */ + public void testUpdateExportedSettingsActiveCfg() throws Exception { + final IProject libProj = ResourceHelper.createCDTProjectWithConfig("libUpdateExtSettings"); + final IProject mainProj = ResourceHelper.createCDTProjectWithConfig("mainProjUpdateExtSettings"); + + { + // set the settings on the lib config; reference it from the main config + ICProjectDescription desLib = coreModel.getProjectDescription(libProj); + ICProjectDescription desMain = coreModel.getProjectDescription(mainProj); + ICConfigurationDescription cfgLib = desLib.getActiveConfiguration(); + ICConfigurationDescription cfgMain = desMain.getActiveConfiguration(); + + cfgLib.createExternalSetting(null, null, null, entries); + coreModel.setProjectDescription(libProj, desLib); + + // Main Project references lib project + cfgMain.setReferenceInfo(new HashMap() {{ put(libProj.getName(), ""); }}); + coreModel.setProjectDescription(mainProj, desMain); + + // Referenced settings have been picked up + for (ICLanguageSettingEntry e : entries) { + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + { + // Now apply different language setting entries + ICProjectDescription desLib = coreModel.getProjectDescription(libProj); + ICConfigurationDescription cfgLib = desLib.getActiveConfiguration(); + cfgLib.removeExternalSetting(cfgLib.getExternalSettings()[0]); + cfgLib.createExternalSetting(null, null, null, entries2); + coreModel.setProjectDescription(libProj, desLib); + + // Check the exported settings is correct + checkEquivContents(entries2, cfgLib.getExternalSettings()[0].getEntries()); + // Fetch the configuration a-fresh to pick up the settings + ICConfigurationDescription cfgMain = coreModel.getProjectDescription(mainProj, false).getActiveConfiguration(); + assertTrue(cfgMain.getReferenceInfo().containsKey(libProj.getName())); + + // Referenced settings have changed from entries -> entries2 + for (ICLanguageSettingEntry e : entries) + assertTrue(!cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + for (ICLanguageSettingEntry e : entries2) + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + /** + * This is the same as testeUpdateExprtedSettingsActiveCfg except we explicitly name the + * referenced configuration. + * Tests that updating the exported settings on a name configuration, without updating the set + * of references, is correctly picked up in referencing projects + */ + public void testUpdateExportedSettingsNamedConfig() throws Exception { + final IProject libProj = ResourceHelper.createCDTProjectWithConfig("libUpdateExpSettingsNamed"); + final IProject mainProj = ResourceHelper.createCDTProjectWithConfig("mainProjUpdateExpSettingsNamed"); + + { + // set the settings on the lib config; reference it from the main config + ICProjectDescription desLib = coreModel.getProjectDescription(libProj); + ICProjectDescription desMain = coreModel.getProjectDescription(mainProj); + final ICConfigurationDescription cfgLib = desLib.getActiveConfiguration(); + ICConfigurationDescription cfgMain = desMain.getActiveConfiguration(); + + cfgLib.createExternalSetting(null, null, null, entries); + coreModel.setProjectDescription(libProj, desLib); + + // Main Project references lib project + cfgMain.setReferenceInfo(new HashMap() {{ put(libProj.getName(), cfgLib.getId()); }}); + coreModel.setProjectDescription(mainProj, desMain); + + // Referenced settings have been picked up + for (ICLanguageSettingEntry e : entries) { + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + { + // Now apply different language setting entries + ICProjectDescription desLib = coreModel.getProjectDescription(libProj); + ICConfigurationDescription cfgLib = desLib.getActiveConfiguration(); + cfgLib.removeExternalSetting(cfgLib.getExternalSettings()[0]); + cfgLib.createExternalSetting(null, null, null, entries2); + coreModel.setProjectDescription(libProj, desLib); + + // Check the exported settings is correct + checkEquivContents(entries2, cfgLib.getExternalSettings()[0].getEntries()); + // Fetch the configuration a-fresh to pick up the settings + ICConfigurationDescription cfgMain = coreModel.getProjectDescription(mainProj, false).getActiveConfiguration(); + assertTrue(cfgMain.getReferenceInfo().get(libProj.getName()).equals(cfgLib.getId())); + + // Referenced settings have changed from entries -> entries2 + for (ICLanguageSettingEntry e : entries) + assertTrue(!cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + for (ICLanguageSettingEntry e : entries2) + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + /** + * Bug 312575 tests that updating a .cproject external (e.g. via a repository update) + * causes referencing projects to correctly pick up changes to the project exports. + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=312575 + */ + public void _testExportedSettingsExternalUpdate() throws Exception { + final IProject libProj = ResourceHelper.createCDTProjectWithConfig("libProj312575"); + final IProject mainProj = ResourceHelper.createCDTProjectWithConfig("mainProj312575"); + + // .cproject file and its backup + IFile libCproject = libProj.getFile(".cproject"); + IFile libCproject_back = libProj.getFile(".cproject_back"); + + // set the settings on the lib config; reference it from the main config + { + ICProjectDescription desLib = coreModel.getProjectDescription(libProj); + ICProjectDescription desMain = coreModel.getProjectDescription(mainProj); + final ICConfigurationDescription cfgLib = desLib.getActiveConfiguration(); + ICConfigurationDescription cfgMain = desMain.getActiveConfiguration(); + + cfgLib.createExternalSetting(null, null, null, entries); + coreModel.setProjectDescription(libProj, desLib); + + // Main Project references lib project + cfgMain.setReferenceInfo(new HashMap() {{ put(libProj.getName(), cfgLib.getId()); }}); + coreModel.setProjectDescription(mainProj, desMain); + checkEquivContents(entries, cfgLib.getExternalSettings()[0].getEntries()); + + // Referenced settings have been picked up + for (ICLanguageSettingEntry e : entries) { + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + + // Backup the .cproject + libCproject_back.create(libCproject.getContents(), false, null); + + // Now apply different language setting entries + cfgLib.removeExternalSetting(cfgLib.getExternalSettings()[0]); + cfgLib.createExternalSetting(null, null, null, entries2); + coreModel.setProjectDescription(libProj, desLib); + checkEquivContents(entries2, cfgLib.getExternalSettings()[0].getEntries()); + // Referenced settings have been picked up + for (ICLanguageSettingEntry e : entries2) { + assertTrue(coreModel.getProjectDescription(mainProj).getActiveConfiguration().getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + // Now replace the .cproject with .cproject_back. The exported settings should be picked up in the referenced config + libCproject.setContents(libCproject_back.getContents(), IResource.NONE, null); + + // Referenced settings should still exist + ICConfigurationDescription cfgLib = coreModel.getProjectDescription(libProj, false).getActiveConfiguration(); + ICConfigurationDescription cfgMain = coreModel.getProjectDescription(mainProj, false).getActiveConfiguration(); + + checkEquivContents(entries, cfgLib.getExternalSettings()[0].getEntries()); + // Referencing project contains entries and not entries2 + for (ICLanguageSettingEntry e : entries) { + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + for (ICLanguageSettingEntry e : entries2) { + assertTrue(!cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + /** + * Two configurations in two projects reference each other. + * Test that the system is happy with this and updates each correctly on + * the other's change. + */ + public void _testExportedSettingsCyclicExternalUpdate() throws Exception { + final IProject libProj = ResourceHelper.createCDTProjectWithConfig("libProjCyclic"); + final IProject mainProj = ResourceHelper.createCDTProjectWithConfig("libProjCyclic2"); + + // .cproject file and its backup + final IFile libCproject = libProj.getFile(".cproject"); + final IFile libCproject_back = libProj.getFile(".cproject_back"); + final IFile mainCproject = mainProj.getFile(".cproject"); + final IFile mainCproject_back = mainProj.getFile(".cproject_back"); + + // set the settings on the lib config; reference it from the main config & vice versa + { + ICProjectDescription desLib = coreModel.getProjectDescription(libProj); + ICProjectDescription desMain = coreModel.getProjectDescription(mainProj); + final ICConfigurationDescription cfgLib = desLib.getActiveConfiguration(); + final ICConfigurationDescription cfgMain = desMain.getActiveConfiguration(); + + // Lib Exports entries + cfgLib.createExternalSetting(null, null, null, entries); + // Main Exports entries2 + cfgMain.createExternalSetting(null, null, null, entries2); + + // Main Project references lib project + cfgMain.setReferenceInfo(new HashMap() {{ put(libProj.getName(), cfgLib.getId()); }}); + cfgLib.setReferenceInfo(new HashMap() {{ put(mainProj.getName(), cfgMain.getId()); }}); + coreModel.setProjectDescription(libProj, desLib); + coreModel.setProjectDescription(mainProj, desMain); + + checkEquivContents(entries, cfgLib.getExternalSettings()[0].getEntries()); + checkEquivContents(entries2, cfgMain.getExternalSettings()[0].getEntries()); + + // Backup the .cproject + libCproject_back.create(libCproject.getContents(), false, null); + mainCproject_back.create(mainCproject.getContents(), false, null); + + // Now apply different language setting entries + cfgLib.removeExternalSetting(cfgLib.getExternalSettings()[0]); + cfgLib.createExternalSetting(null, null, null, entries2); + coreModel.setProjectDescription(libProj, desLib); + cfgMain.removeExternalSetting(cfgMain.getExternalSettings()[0]); + cfgMain.createExternalSetting(null, null, null, entries); + coreModel.setProjectDescription(mainProj, desMain); + + checkEquivContents(entries2, cfgLib.getExternalSettings()[0].getEntries()); + checkEquivContents(entries, cfgMain.getExternalSettings()[0].getEntries()); + + } + ICConfigurationDescription cfgLib = coreModel.getProjectDescription(libProj).getActiveConfiguration(); + ICConfigurationDescription cfgMain = coreModel.getProjectDescription(mainProj).getActiveConfiguration(); + + // Tests the exports are now the right way round + for (ICLanguageSettingEntry e : entries) { + assertTrue(!cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + assertTrue(cfgLib.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + for (ICLanguageSettingEntry e : entries2) { + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + assertTrue(!cfgLib.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + + // Now replace the .cproject with .cproject_back. The exported settings should be picked up in the referenced config + ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + libCproject.setContents(libCproject_back.getContents(), IResource.NONE, null); + mainCproject.setContents(mainCproject_back.getContents(), IResource.NONE, null); + } + }, null); + + // Referenced settings should still exist + cfgLib = coreModel.getProjectDescription(libProj).getActiveConfiguration(); + cfgMain = coreModel.getProjectDescription(mainProj).getActiveConfiguration(); + + checkEquivContents(entries, cfgLib.getExternalSettings()[0].getEntries()); + checkEquivContents(entries2, cfgMain.getExternalSettings()[0].getEntries()); + // Referencing project contains entries and not entries2 + for (ICLanguageSettingEntry e : entries) { + assertTrue(cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + assertTrue(!cfgLib.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + for (ICLanguageSettingEntry e : entries2) { + assertTrue(!cfgMain.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + assertTrue(cfgLib.getRootFolderDescription().getLanguageSettingForFile("a.c"). + getSettingEntriesList(e.getKind()).contains(e)); + } + } + + + private void checkEquivContents(Object[] expected, Object[] actual) { + if(expected == null){ + assertTrue(actual == null); return; } - assertTrue(a2 != null); - assertEquals(a1.length, a2.length); + assertTrue(actual != null); + assertEquals(expected.length, actual.length); - Set s1 = new HashSet(Arrays.asList(a1)); - Set s2 = new HashSet(Arrays.asList(a2)); - assertEquals(a1.length, s1.size()); + Set s1 = new HashSet(Arrays.asList(expected)); + Set s2 = new HashSet(Arrays.asList(actual)); + assertEquals(expected.length, s1.size()); assertEquals(s1, s2); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICConfigurationDescription.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICConfigurationDescription.java index 94a7fdcd11f..121b8408c74 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICConfigurationDescription.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICConfigurationDescription.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Intel Corporation and others. + * Copyright (c) 2007, 2010 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -195,26 +195,41 @@ public interface ICConfigurationDescription extends ICSettingContainer, ICSettin void setSourceEntries(ICSourceEntry[] entries) throws CoreException, WriteAccessException; /** - * returns the reference information for this configuration, i.e. the information on the projects/configurations - * this configuration references - * the map contains the project_name<->configuration_id associations - * if the current configuration does not reference any other configurations, - * empty map is returned + * Returns a Map of configurations referenced by this configuration. Settings exported + * by a project configuration are automatically picked up by any referencing configurations. + *

+ * This Map is keyed by project name with value equal to the referenced configuration's ID, or the + * empty string. The empty string is a special configuration value which indicates the reference + * tracks the Active configuration in the referenced Project. + *

+ * If the current configuration does not reference any other configurations, + * an empty map is returned. + * + * @return Map of referenced Project -> Configuration ID + * @see {@link #setReferenceInfo(Map)}
+ * {@link #getExternalSettings()}
+ * {@link #createExternalSetting(String[], String[], String[], ICSettingEntry[])} */ Map getReferenceInfo(); /** - * sets the reference information for this configuration, i.e. the information on the projects/configurations - * this configuration references - * the map should contain the project_name<->configuration_id associations - * - * @param refs - * + * Sets the reference information for this configuration. This configuration + * will pick up settings exported by referenced configurations. + *

+ * This reference information is a map from project name to configuration ID + * within the referenced project. + * The empty string is a special configuration value which indicates the reference + * tracks the Active configuration in the referenced Project. + * + * @param refs Map of project name -> configuration ID of referenced configurations * @throws WriteAccessException when the configuration description is read-only * see {@link CoreModel#getProjectDescription(org.eclipse.core.resources.IProject, boolean)} + * @see {@link #getReferenceInfo()}
+ * {@link #getExternalSettings()}
+ * {@link #createExternalSetting(String[], String[], String[], ICSettingEntry[])} */ void setReferenceInfo(Map refs) throws WriteAccessException; - + /** * returns an array of settings exported by this configuration * in case some configurations refer (depend on) this configuration diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingContainerFactory.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingContainerFactory.java index 4929066bf52..842fa867d4e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingContainerFactory.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingContainerFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Intel Corporation and others. + * Copyright (c) 2007, 2010 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,6 +15,21 @@ import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +/** + * Root of the External Settings Provider Factory hierarchy. These + * are responsible for creating {@link CExternalSettingsContainer}s + * for a given settings provider id. The container + * is a simple container for external settings accessible via: + * {@link CExternalSettingsContainer#getExternalSettings()} + * + * There are two concrete implementation of this in CDT: + *

    + *
  • {@link CfgExportSettingContainerFactory} responsible for settings propagated + * referenced configurations.
  • + *
  • {@link ExtensionContainerFactory} responsible for settings contributed + * using the external settings extension point.
  • + *
+ */ public abstract class CExternalSettingContainerFactory { /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsContainer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsContainer.java index 889d1288db4..6b711a9a188 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsContainer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsContainer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Intel Corporation and others. + * Copyright (c) 2007, 2010 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,14 +7,24 @@ * * Contributors: * Intel Corporation - Initial API and implementation + * James Blackburn (Broadcom Corp.) *******************************************************************************/ package org.eclipse.cdt.internal.core.settings.model; import org.eclipse.cdt.core.settings.model.CExternalSetting; - +/** + * Container class which returns the {@link CExternalSetting}s + * for a given context. + */ public abstract class CExternalSettingsContainer { + /** Empty array of external settings */ + public static final CExternalSetting[] EMPTY_EXT_SETTINGS_ARRAY = new CExternalSetting[0]; + + /** + * @return CExternalSetting[] of settings in this container; never null + */ public abstract CExternalSetting[] getExternalSettings(); - + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsHolder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsHolder.java index 0b8645a6b40..43f79fb5cb2 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsHolder.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsHolder.java @@ -25,7 +25,6 @@ import org.eclipse.cdt.internal.core.settings.model.CExternalSettinsDeltaCalcula public class CExternalSettingsHolder extends CExternalSettingsContainer { private Map fSettingsMap; static final String ELEMENT_EXT_SETTINGS_CONTAINER = "externalSettings"; //$NON-NLS-1$ - static final CExternalSetting[] EMPTY_EXT_SETTINGS_ARRAY = new CExternalSetting[0]; private boolean fIsModified; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsManager.java index 96dc8ed3c3e..4cfe5dcb376 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CExternalSettingsManager.java @@ -199,32 +199,12 @@ public class CExternalSettingsManager implements ICExternalSettingsListener, ICP private static class NullFactory extends CExternalSettingContainerFactory { static NullFactory INSTANCE = new NullFactory(); - - @Override - public void addListener(ICExternalSettingsListener listener) { - } @Override public CExternalSettingsContainer createContainer(String id, IProject project, ICConfigurationDescription cfgDes, CExternalSetting[] previousSettings) throws CoreException { return NullContainer.INSTANCE; } - -// public String[] getSupplierIds() { -// return null; -// } - - @Override - public void removeListener(ICExternalSettingsListener listener) { - } - - @Override - public void shutdown() { - } - - @Override - public void startup() { - } } private class FactoryDescriptor { @@ -760,7 +740,7 @@ public class CExternalSettingsManager implements ICExternalSettingsListener, ICP CfgListCfgContainer cfgCr = new CfgListCfgContainer(list, i); CfgContainerRefInfoContainer ric = new CfgContainerRefInfoContainer(cfgCr); CContainerRef[] refs = ric.getRefInfo(false).getReferences(); - for(int k = 0; k < refs.length; k++){ + for(int k = 0; k < refs.length; k++) { if(containerContentsChanged(cfgCr, refs[k], null)) changed = true; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CfgExportSettingContainerFactory.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CfgExportSettingContainerFactory.java index 52f8271fbf0..e5996944b1f 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CfgExportSettingContainerFactory.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CfgExportSettingContainerFactory.java @@ -11,12 +11,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.settings.model; -import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.settings.model.CExternalSetting; @@ -34,12 +34,18 @@ import org.eclipse.core.runtime.CoreException; /** * A class responsible for persisting CDT Projects and Configuration IDs as referenced * by other configurations in other projects. - * The user controls this via RefsTab and integrators can use + * The user controls this via RefsTab. This External settings factory listens + * for CProjectDescription model changes and notifies the {@link CExternalSettingsManager}, + * which is a listener, of changes to the set of external settings. * {@link ICConfigurationDescription#setReferenceInfo(Map)} and {@link ICConfigurationDescription#getReferenceInfo()} */ public class CfgExportSettingContainerFactory extends CExternalSettingContainerFactoryWithListener implements ICProjectDescriptionListener { + + /** ID of this external settings factory */ static final String FACTORY_ID = CCorePlugin.PLUGIN_ID + ".cfg.export.settings.sipplier"; //$NON-NLS-1$ + + /** Empty String is a the magic configuration ID which maps to the Active configuration */ private static final String ACTIVE_CONFIG_ID = ""; //$NON-NLS-1$ private static final char DELIMITER = ';'; @@ -230,7 +236,7 @@ public class CfgExportSettingContainerFactory extends } /** - * Returns the set of ReferenceIDs (project_name;config_id) for the project descriptions + * Returns the set of containers (Project configurations) (project_name;config_id) for the project descriptions * reported as changed by the ICDescriptionDelta * @param delta * @return String[] of Configuration Reference IDs @@ -240,7 +246,7 @@ public class CfgExportSettingContainerFactory extends return new String[0]; int deltaKind = delta.getDeltaKind(); - List cfgIds = new ArrayList(); + Set cfgIds = new HashSet(); switch(deltaKind){ case ICDescriptionDelta.ADDED: case ICDescriptionDelta.REMOVED: @@ -264,28 +270,23 @@ public class CfgExportSettingContainerFactory extends String[] ids = new String[cfgIds.size()]; if(ids.length != 0){ String projName = ((ICProjectDescription)delta.getSetting()).getProject().getName(); - for(int i = 0; i < ids.length; i++){ - ids[i] = createId(projName, cfgIds.get(i)); - } + int i = 0; + for (String config : cfgIds) + ids[i++] = createId(projName, config); } return ids; } - + /** - * Return the set of changed {Added, Remove & Changed} configuration IDs as discvoered + * Return the set of changed {Added, Remove & Changed} configuration IDs as discovered * from an ICDescrptionDelta[] * @param deltas * @param c * @return */ private Collection collectCfgIds(ICDescriptionDelta[] deltas, Collection c){ - if(c == null) - c = new ArrayList(); - for(int i = 0; i < deltas.length; i++){ - ICDescriptionDelta delta = deltas[i]; - int deltaKind = delta.getDeltaKind(); - - switch(deltaKind){ + for (ICDescriptionDelta delta : deltas) { + switch (delta.getDeltaKind()) { case ICDescriptionDelta.ADDED: case ICDescriptionDelta.REMOVED: c.add(delta.getSetting().getId()); @@ -296,6 +297,9 @@ public class CfgExportSettingContainerFactory extends (ICDescriptionDelta.EXTERNAL_SETTINGS_ADDED | ICDescriptionDelta.EXTERNAL_SETTINGS_REMOVED)) != 0){ c.add(delta.getSetting().getId()); + // If this is the Active configuration, then record it as changed too (bug 312575) + if (delta.getSetting().getConfiguration().isActive()) + c.add(ACTIVE_CONFIG_ID); } break; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ICExternalSettingsListener.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ICExternalSettingsListener.java index 0419ed7fce0..722b2b00912 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ICExternalSettingsListener.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ICExternalSettingsListener.java @@ -12,6 +12,9 @@ package org.eclipse.cdt.internal.core.settings.model; import org.eclipse.core.resources.IProject; +/** + * Listener for external settings changes + */ public interface ICExternalSettingsListener { void settingsChanged(IProject project, String cfgId, CExternalSettingChangeEvent event); }