1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

Support for IResourceChangeListener providers

This commit is contained in:
Andrew Gvozdev 2011-09-22 15:23:00 -04:00
parent 6a200bcbce
commit d581c14367
4 changed files with 238 additions and 16 deletions

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider;
import org.eclipse.cdt.core.settings.model.WriteAccessException;
import org.eclipse.cdt.core.testplugin.CModelMock;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
@ -103,13 +104,20 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
}
}
private class MockProvider extends LanguageSettingsSerializable {
public MockProvider(String id, String name) {
private class MockEditableProvider extends LanguageSettingsSerializable implements ILanguageSettingsEditableProvider {
public MockEditableProvider(String id, String name) {
super(id, name);
}
@Override
public MockEditableProvider cloneShallow() throws CloneNotSupportedException {
return (MockEditableProvider) super.cloneShallow();
}
@Override
public MockEditableProvider clone() throws CloneNotSupportedException {
return (MockEditableProvider) super.clone();
}
}
/**
* Constructor.
* @param name - name of the test.
@ -178,21 +186,88 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
/**
*/
public void testReadOnlyDescription() throws Exception {
public void testProjectDescription_ReadWriteProviders() throws Exception {
// create a project
IProject project = ResourceHelper.createCDTProjectWithConfig(getName());
// get read-only description
ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false);
assertNotNull(prjDescription);
ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration();
assertNotNull(cfgDescription);
{
// get read-only description
ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false);
assertNotNull(prjDescription);
ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration();
assertNotNull(cfgDescription);
// try to write to it
try {
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
cfgDescription.setLanguageSettingProviders(providers);
fail("WriteAccessException was expected but it was not throw.");
} catch (WriteAccessException e) {
// exception is expected
}
}
try {
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
entries.add(new CIncludePathEntry("path0", 0));
{
// get project descriptions
ICProjectDescription writableProjDescription = coreModel.getProjectDescription(project);
assertNotNull(writableProjDescription);
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
assertEquals(1, cfgDescriptions.length);
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
// create a provider
LanguageSettingsSerializable mockProvider = new MockEditableProvider(PROVIDER_0, PROVIDER_NAME_0);
mockProvider.setStoringEntriesInProjectArea(true);
mockProvider.setSettingEntries(cfgDescription, null, null, entries);
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
providers.add(mockProvider);
cfgDescription.setLanguageSettingProviders(providers);
fail("WriteAccessException was expected but it was not throw.");
} catch (WriteAccessException e) {
// exception is expected
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
assertEquals(1, storedProviders.size());
// apply new project description to the project model
coreModel.setProjectDescription(project, writableProjDescription);
}
{
// get read-only project descriptions
ICProjectDescription readOnlyProjDescription = coreModel.getProjectDescription(project, false);
assertNotNull(readOnlyProjDescription);
ICConfigurationDescription[] cfgDescriptions = readOnlyProjDescription.getConfigurations();
assertEquals(1, cfgDescriptions.length);
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
assertEquals(1, providers.size());
ILanguageSettingsProvider loadedProvider = providers.get(0);
assertTrue(loadedProvider instanceof LanguageSettingsSerializable);
assertEquals(PROVIDER_0, loadedProvider.getId());
assertEquals(PROVIDER_NAME_0, loadedProvider.getName());
List<ICLanguageSettingEntry> actual = loadedProvider.getSettingEntries(cfgDescription, null, null);
assertEquals(entries.get(0), actual.get(0));
assertEquals(entries.size(), actual.size());
}
{
// get writable project descriptions
ICProjectDescription writableProjDescription = coreModel.getProjectDescription(project);
assertNotNull(writableProjDescription);
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
assertEquals(1, cfgDescriptions.length);
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
assertEquals(1, providers.size());
ILanguageSettingsProvider loadedProvider = providers.get(0);
assertTrue(loadedProvider instanceof LanguageSettingsSerializable);
assertEquals(PROVIDER_0, loadedProvider.getId());
assertEquals(PROVIDER_NAME_0, loadedProvider.getName());
List<ICLanguageSettingEntry> actual = loadedProvider.getSettingEntries(cfgDescription, null, null);
assertEquals(entries.get(0), actual.get(0));
assertEquals(entries.size(), actual.size());
}
}

View file

@ -12,6 +12,7 @@
package org.eclipse.cdt.internal.core.language.settings.providers;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -24,11 +25,13 @@ import org.eclipse.cdt.core.AbstractExecutableExtensionBase;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsBaseProvider;
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
@ -37,7 +40,10 @@ import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
@ -613,5 +619,141 @@ public class LanguageSettingsExtensionManager {
return provider.equals(extensionProvider);
}
/**
* TODO - remove me
* Temporary method to report inconsistency in log.
*/
@Deprecated
public static void assertConsistency(ICProjectDescription prjDescription) {
if (prjDescription != null) {
List<ILanguageSettingsProvider> prjProviders = new ArrayList<ILanguageSettingsProvider>();
for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) {
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
for (ILanguageSettingsProvider provider : providers) {
if (!LanguageSettingsManager.isWorkspaceProvider(provider)) {
if (isObjectInTheList(prjProviders, provider)) {
IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Inconsistent state, duplicate LSP in project description "
+ "[" + System.identityHashCode(provider) + "] "
+ provider);
CoreException e = new CoreException(status);
CCorePlugin.log(e);
}
prjProviders.add(provider);
}
}
}
}
}
/**
* TODO - remove me
* Temporary method to report inconsistency in log.
*/
@Deprecated
public static void assertConsistency(ICConfigurationDescription cfgDescription) {
List<ILanguageSettingsProvider> listeners = new ArrayList<ILanguageSettingsProvider>();
List<ILanguageSettingsProvider> 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);
}
}
/**
* Get a providers list including only providers of type IResourceChangeListener
* for a given project description - collecting from all configurations.
*/
private static List<IResourceChangeListener> getResourceChangeListeners(ICProjectDescription prjDescription) {
List<IResourceChangeListener> listeners = new ArrayList<IResourceChangeListener>();
if (prjDescription != null) {
for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) {
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
for (ILanguageSettingsProvider provider : providers) {
if (provider instanceof IResourceChangeListener) {
listeners.add((IResourceChangeListener) provider);
}
}
}
}
return listeners;
}
/**
* Unregister listeners which are not used anymore and register new listeners.
* The method is used when project description is applied to workspace.
* @param oldPrjDescription - old project descriptions being replaced in the workspace.
* @param newPrjDescription - new project description being applied to the workspace.
*/
public static void reRegisterListeners(ICProjectDescription oldPrjDescription, ICProjectDescription newPrjDescription) {
if (oldPrjDescription == newPrjDescription) {
assertConsistency(oldPrjDescription); // TODO - remove me
return;
}
assertConsistency(oldPrjDescription); // TODO - remove me
assertConsistency(newPrjDescription); // TODO - remove me
IWorkspace workspace = ResourcesPlugin.getWorkspace();
List<IResourceChangeListener> oldListeners = getResourceChangeListeners(oldPrjDescription);
List<IResourceChangeListener> newListeners = getResourceChangeListeners(newPrjDescription);
for (IResourceChangeListener listener : oldListeners) {
if (!isObjectInTheList(newListeners, listener)) {
workspace.removeResourceChangeListener(listener);
// TODO - remove me
CCorePlugin.log(new Status(IStatus.WARNING,CCorePlugin.PLUGIN_ID, oldPrjDescription.getProject() + ": Removed IResourceChangeListener "
+ "[" + System.identityHashCode(listener) + "] "
+ listener));
}
}
for (IResourceChangeListener listener : newListeners) {
if (!isObjectInTheList(oldListeners, listener)) {
workspace.addResourceChangeListener(listener);
// TODO - remove me
CCorePlugin.log(new Status(IStatus.WARNING,CCorePlugin.PLUGIN_ID, newPrjDescription.getProject() + ": Added IResourceChangeListener "
+ "[" + System.identityHashCode(listener) + "] "
+ listener));
}
}
}
private static <T> boolean isObjectInTheList(Collection<T> 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.
*
* @param baseProviders - list of providers to clone.
* @return newly cloned list.
*/
public static List<ILanguageSettingsProvider> cloneProviders(List<ILanguageSettingsProvider> baseProviders) {
List<ILanguageSettingsProvider> newProviders = new ArrayList<ILanguageSettingsProvider>();
for (ILanguageSettingsProvider provider : baseProviders) {
if (provider instanceof ILanguageSettingsEditableProvider) {
try {
provider = ((ILanguageSettingsEditableProvider) provider).clone();
} catch (CloneNotSupportedException e) {
IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Not able to clone provider " + provider.getClass());
CCorePlugin.log(new CoreException(status));
}
}
newProviders.add(provider);
}
return new ArrayList<ILanguageSettingsProvider>(newProviders);
}
}

View file

@ -41,6 +41,7 @@ import org.eclipse.cdt.internal.core.COwner;
import org.eclipse.cdt.internal.core.COwnerConfiguration;
import org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables;
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager;
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
import org.eclipse.cdt.utils.envvar.StorableEnvironment;
import org.eclipse.core.runtime.CoreException;
@ -188,7 +189,7 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{
copyExtensionInfo(base);
fLanguageSettingsProviders = new ArrayList<ILanguageSettingsProvider>(base.getLanguageSettingProviders());
fLanguageSettingsProviders = LanguageSettingsExtensionManager.cloneProviders(base.getLanguageSettingProviders());
}
// private void copyRefInfos(Map infosMap){

View file

@ -34,7 +34,6 @@ import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager_TBD;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.settings.model.ICSettingsStorage;
@ -43,6 +42,7 @@ import org.eclipse.cdt.core.settings.model.extension.ICProjectConverter;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.internal.core.XmlUtil;
import org.eclipse.cdt.internal.core.envvar.ContributedEnvironment;
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager;
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
import org.eclipse.cdt.internal.core.settings.model.AbstractCProjectDescriptionStorage;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescription;
@ -365,6 +365,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
if (!overwriteIfExists && fProjectDescription.get() != null)
return false;
ICProjectDescription oldDes = fProjectDescription.get();
if (des != null) {
if (project.exists() && project.isOpen()) {
fProjectDescription = new SoftReference<ICProjectDescription>(des);
@ -375,6 +376,8 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
} else {
fProjectDescription = new SoftReference<ICProjectDescription>(null);
}
LanguageSettingsExtensionManager.reRegisterListeners(oldDes, fProjectDescription.get());
return true;
}
@ -484,10 +487,11 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
// Update the modification stamp
projectModificaitonStamp = getModificationStamp(project.getFile(ICProjectDescriptionStorageType.STORAGE_FILE_NAME));
CProjectDescription des = new CProjectDescription(project, new XmlStorage(storage), storage, true, false);
LanguageSettingsProvidersSerializer.loadLanguageSettings(des);
try {
setThreadLocalProjectDesc(des);
des.loadDatas();
LanguageSettingsProvidersSerializer.loadLanguageSettings(des);
des.doneLoading();
} finally {
setThreadLocalProjectDesc(null);