mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Serialization of LSE entries in workspace area
This commit is contained in:
parent
6088b4e980
commit
36c081996e
5 changed files with 941 additions and 321 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Andrew Gvozdev and others.
|
||||
* Copyright (c) 2009, 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
|
||||
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
|
@ -30,6 +31,7 @@ import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSetting
|
|||
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
@ -38,6 +40,7 @@ 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
|
||||
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";
|
||||
|
@ -162,6 +165,16 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
return cfgDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNoProviders() throws Exception {
|
||||
// serialize language settings of user defined providers (on workspace level)
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace();
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsWorkspace();
|
||||
|
||||
// test passes if no exception was thrown
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testWorkspacePersistence_ModifiedExtensionProvider() throws Exception {
|
||||
|
@ -317,6 +330,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
|
||||
LanguageSettingsSerializable serializableProvider = new LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
serializableProvider.setSettingEntries(null, null, null, entries);
|
||||
serializableProvider.setStoringEntriesInProjectArea(true);
|
||||
|
||||
ArrayList<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(serializableProvider);
|
||||
|
@ -326,12 +340,12 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
|
@ -378,6 +392,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
assertNotNull(cfgDescription1);
|
||||
assertEquals(CFG_ID, cfgDescription1.getId());
|
||||
LanguageSettingsSerializable provider1 = new LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
provider1.setStoringEntriesInProjectArea(true);
|
||||
provider1.setSettingEntries(null, null, null, entries);
|
||||
ArrayList<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(provider1);
|
||||
|
@ -389,6 +404,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
assertNotNull(cfgDescription2);
|
||||
assertEquals(CFG_ID_2, cfgDescription2.getId());
|
||||
LanguageSettingsSerializable provider2 = new LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
provider2.setStoringEntriesInProjectArea(true);
|
||||
provider2.setSettingEntries(null, null, null, entries2);
|
||||
ArrayList<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(provider2);
|
||||
|
@ -433,7 +449,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
}
|
||||
{
|
||||
// re-create a project description and re-load language settings for each configuration
|
||||
|
@ -443,7 +459,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
new MockConfigurationDescription(CFG_ID_2),
|
||||
});
|
||||
// load
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
|
@ -495,6 +511,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
|
||||
LanguageSettingsSerializable serializableProvider = new MockLanguageSettingsSerializableProvider(PROVIDER_0, PROVIDER_NAME_0);
|
||||
serializableProvider.setSettingEntries(null, null, null, entries);
|
||||
serializableProvider.setStoringEntriesInProjectArea(true);
|
||||
|
||||
ArrayList<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(serializableProvider);
|
||||
|
@ -504,12 +521,12 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
|
@ -553,12 +570,12 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
}
|
||||
{
|
||||
// re-load
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
|
@ -593,7 +610,8 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
assertNotNull(cfgDescription);
|
||||
|
||||
// populate with provider overriding the extension (must be SerializableLanguageSettingsProvider or a class from another extension)
|
||||
ILanguageSettingsProvider providerOverride = new MockLanguageSettingsSerializableProvider(idExt, PROVIDER_NAME_0);
|
||||
MockLanguageSettingsSerializableProvider providerOverride = new MockLanguageSettingsSerializableProvider(idExt, PROVIDER_NAME_0);
|
||||
providerOverride.setStoringEntriesInProjectArea(true);
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(providerOverride);
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
|
@ -603,12 +621,12 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
}
|
||||
{
|
||||
// re-load
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
|
@ -658,9 +676,11 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
// 3. Providers defined in a configuration
|
||||
// 3.1
|
||||
LanguageSettingsSerializable mockProvider1 = new LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
mockProvider1.setStoringEntriesInProjectArea(true);
|
||||
mockProvider1.setSettingEntries(null, null, null, entries_31);
|
||||
// 3.2
|
||||
LanguageSettingsSerializable mockProvider2 = new MockLanguageSettingsSerializableProvider(PROVIDER_2, PROVIDER_NAME_2);
|
||||
mockProvider2.setStoringEntriesInProjectArea(true);
|
||||
mockProvider2.setSettingEntries(null, null, null, entries_32);
|
||||
|
||||
ArrayList<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
|
@ -674,13 +694,13 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
XmlUtil.toString(doc);
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettings(rootElement, mockPrjDescription);
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(rootElement, null, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
|
@ -736,6 +756,7 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
|
||||
// create a provider
|
||||
LanguageSettingsSerializable mockProvider = new LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
mockProvider.setStoringEntriesInProjectArea(true);
|
||||
mockProvider.setSettingEntries(cfgDescription, null, null, entries);
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(mockProvider);
|
||||
|
@ -772,6 +793,12 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
assertFalse(xmlFile.exists());
|
||||
assertTrue(xmlFileOut.exists());
|
||||
}
|
||||
{
|
||||
// Should not pollute workspace area with file with no meaningful data
|
||||
String xmlWspStorageFileLocation = getStoreLocationInWorkspaceArea(project.getName()+'.'+LANGUAGE_SETTINGS_WORKSPACE_XML);
|
||||
java.io.File xmlStorageFileWsp = new java.io.File(xmlWspStorageFileLocation);
|
||||
assertFalse(xmlStorageFileWsp.exists());
|
||||
}
|
||||
|
||||
{
|
||||
// clear configuration
|
||||
|
@ -836,5 +863,223 @@ public class LanguageSettingsPersistenceProjectTests extends TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testProjectPersistence_SplitStorageDOM() throws Exception {
|
||||
Element prjStorageElement = null;
|
||||
Element wspStorageElement = null;
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 0));
|
||||
|
||||
{
|
||||
// create a provider
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
assertNotNull(cfgDescription);
|
||||
|
||||
LanguageSettingsSerializable serializableProvider = new LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
serializableProvider.setSettingEntries(null, null, null, entries);
|
||||
// do not store entries inside project
|
||||
serializableProvider.setStoringEntriesInProjectArea(false);
|
||||
|
||||
ArrayList<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(serializableProvider);
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
|
||||
// prepare DOM storage
|
||||
Document prjDoc = XmlUtil.newDocument();
|
||||
prjStorageElement = XmlUtil.appendElement(prjDoc, ELEM_TEST);
|
||||
Document wspDoc = XmlUtil.newDocument();
|
||||
wspStorageElement = XmlUtil.appendElement(wspDoc, ELEM_TEST);
|
||||
// serialize language settings to the DOM
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInternal(prjStorageElement, wspStorageElement, mockPrjDescription);
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
MockProjectDescription mockPrjDescription = new MockProjectDescription(new MockConfigurationDescription(CFG_ID));
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsInternal(prjStorageElement, wspStorageElement, mockPrjDescription);
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = mockPrjDescription.getConfigurations();
|
||||
assertNotNull(cfgDescriptions);
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
assertNotNull(cfgDescription);
|
||||
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
assertNotNull(providers);
|
||||
assertEquals(1, providers.size());
|
||||
ILanguageSettingsProvider provider = providers.get(0);
|
||||
assertTrue(provider instanceof LanguageSettingsSerializable);
|
||||
|
||||
List<ICLanguageSettingEntry> actual = provider.getSettingEntries(null, null, null);
|
||||
assertEquals(entries.get(0), actual.get(0));
|
||||
assertEquals(entries.size(), actual.size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: refactor with ErrorParserManager
|
||||
*
|
||||
* @param store - name of the store
|
||||
* @return location of the store in the plug-in state area
|
||||
*/
|
||||
private static String getStoreLocationInWorkspaceArea(String store) {
|
||||
IPath location = CCorePlugin.getDefault().getStateLocation().append(store);
|
||||
return location.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testProjectPersistence_RealProjectSplitStorage() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
String xmlStorageFileLocation;
|
||||
String xmlOutOfTheWay;
|
||||
String xmlWspStorageFileLocation;
|
||||
String xmlWspOutOfTheWay;
|
||||
|
||||
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 LanguageSettingsSerializable(PROVIDER_0, PROVIDER_NAME_0);
|
||||
mockProvider.setStoringEntriesInProjectArea(false);
|
||||
mockProvider.setSettingEntries(cfgDescription, null, null, entries);
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(mockProvider);
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
coreModel.setProjectDescription(project, writableProjDescription);
|
||||
IFile xmlStorageFile = project.getFile(LANGUAGE_SETTINGS_PROJECT_XML);
|
||||
assertTrue(xmlStorageFile.exists());
|
||||
xmlStorageFileLocation = xmlStorageFile.getLocation().toOSString();
|
||||
// TODO - cleanup names
|
||||
xmlWspStorageFileLocation = getStoreLocationInWorkspaceArea(project.getName()+'.'+LANGUAGE_SETTINGS_WORKSPACE_XML);
|
||||
java.io.File xmlStorageFileWsp = new java.io.File(xmlWspStorageFileLocation);
|
||||
assertTrue(xmlStorageFileWsp.exists());
|
||||
}
|
||||
{
|
||||
coreModel.getProjectDescription(project);
|
||||
ICConfigurationDescription cfgDescription = getFirstConfigurationDescription(project);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, providers.size());
|
||||
ILanguageSettingsProvider provider = providers.get(0);
|
||||
assertTrue(provider instanceof LanguageSettingsSerializable);
|
||||
assertEquals(PROVIDER_0, provider.getId());
|
||||
assertEquals(PROVIDER_NAME_0, provider.getName());
|
||||
|
||||
List<ICLanguageSettingEntry> actual = provider.getSettingEntries(cfgDescription, null, null);
|
||||
assertEquals(entries.get(0), actual.get(0));
|
||||
assertEquals(entries.size(), actual.size());
|
||||
}
|
||||
// Move storages out of the way
|
||||
{
|
||||
java.io.File xmlFile = new java.io.File(xmlStorageFileLocation);
|
||||
xmlOutOfTheWay = xmlStorageFileLocation+".out-of-the-way";
|
||||
java.io.File xmlFileOut = new java.io.File(xmlOutOfTheWay);
|
||||
xmlFile.renameTo(xmlFileOut);
|
||||
assertFalse(xmlFile.exists());
|
||||
assertTrue(xmlFileOut.exists());
|
||||
}
|
||||
{
|
||||
// TODO - workspace file
|
||||
java.io.File xmlStorageFileWsp = new java.io.File(xmlWspStorageFileLocation);
|
||||
assertTrue(xmlStorageFileWsp.exists());
|
||||
xmlWspOutOfTheWay = xmlWspStorageFileLocation+".out-of-the-way";
|
||||
java.io.File xmlWspFileOut = new java.io.File(xmlWspOutOfTheWay);
|
||||
boolean result = xmlStorageFileWsp.renameTo(xmlWspFileOut);
|
||||
assertTrue(result);
|
||||
assertFalse(xmlStorageFileWsp.exists());
|
||||
assertTrue(xmlWspFileOut.exists());
|
||||
}
|
||||
|
||||
{
|
||||
// clear configuration
|
||||
ICProjectDescription writableProjDescription = coreModel.getProjectDescription(project);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
assertNotNull(cfgDescription);
|
||||
|
||||
cfgDescription.setLanguageSettingProviders(new ArrayList<ILanguageSettingsProvider>());
|
||||
coreModel.setProjectDescription(project, writableProjDescription);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, providers.size());
|
||||
}
|
||||
{
|
||||
// re-check if it really took it
|
||||
ICConfigurationDescription cfgDescription = getFirstConfigurationDescription(project);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, providers.size());
|
||||
}
|
||||
{
|
||||
// close the project
|
||||
project.close(null);
|
||||
}
|
||||
{
|
||||
// open to double-check the data is not kept in some other kind of cache
|
||||
project.open(null);
|
||||
ICConfigurationDescription cfgDescription = getFirstConfigurationDescription(project);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, providers.size());
|
||||
// and close
|
||||
project.close(null);
|
||||
}
|
||||
|
||||
{
|
||||
// Move storage back
|
||||
java.io.File xmlFile = new java.io.File(xmlStorageFileLocation);
|
||||
xmlFile.delete();
|
||||
assertFalse("File "+xmlFile+ " still exist", xmlFile.exists());
|
||||
java.io.File xmlFileOut = new java.io.File(xmlOutOfTheWay);
|
||||
xmlFileOut.renameTo(xmlFile);
|
||||
assertTrue("File "+xmlFile+ " does not exist", xmlFile.exists());
|
||||
assertFalse("File "+xmlFileOut+ " still exist", xmlFileOut.exists());
|
||||
}
|
||||
|
||||
{
|
||||
// TODO
|
||||
// Move storage back
|
||||
java.io.File xmlWspFile = new java.io.File(xmlWspStorageFileLocation);
|
||||
xmlWspFile.delete();
|
||||
assertFalse("File "+xmlWspFile+ " still exist", xmlWspFile.exists());
|
||||
java.io.File xmlWspFileOut = new java.io.File(xmlWspOutOfTheWay);
|
||||
xmlWspFileOut.renameTo(xmlWspFile);
|
||||
assertTrue("File "+xmlWspFile+ " does not exist", xmlWspFile.exists());
|
||||
assertFalse("File "+xmlWspFileOut+ " still exist", xmlWspFileOut.exists());
|
||||
}
|
||||
|
||||
{
|
||||
// Remove project from internal cache
|
||||
CProjectDescriptionManager.getInstance().projectClosedRemove(project);
|
||||
// open project and check if providers are loaded
|
||||
project.open(null);
|
||||
ICConfigurationDescription cfgDescription = getFirstConfigurationDescription(project);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
|||
import org.eclipse.cdt.core.testplugin.CModelMock;
|
||||
import org.eclipse.cdt.core.testplugin.ResourceHelper;
|
||||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
@ -43,12 +42,7 @@ import org.w3c.dom.Element;
|
|||
* Test cases testing LanguageSettingsProvider functionality
|
||||
*/
|
||||
public class LanguageSettingsSerializableTests extends TestCase {
|
||||
// Should match id of extension point defined in plugin.xml
|
||||
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";
|
||||
private static final String CFG_ID_1 = "test.configuration.id.1";
|
||||
private static final String CFG_ID_2 = "test.configuration.id.2";
|
||||
private static final ICConfigurationDescription MOCK_CFG = new CModelMock.DummyCConfigurationDescription(CFG_ID);
|
||||
private static final IResource MOCK_RC = ResourcesPlugin.getWorkspace().getRoot();
|
||||
private static final String LANG_ID = "test.lang.id";
|
||||
|
@ -101,7 +95,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testProvider() throws Exception {
|
||||
public void testProvider_SettersGetters() throws Exception {
|
||||
// benchmark data
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 0));
|
||||
|
@ -121,9 +115,9 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
mockProvider.setCustomParameter(CUSTOM_PARAMETER);
|
||||
assertEquals(CUSTOM_PARAMETER, mockProvider.getCustomParameter());
|
||||
|
||||
assertEquals(false, mockProvider.isEntriesStorageWithProject());
|
||||
mockProvider.setEntriesStorageWithProject(true);
|
||||
assertEquals(true, mockProvider.isEntriesStorageWithProject());
|
||||
assertEquals(false, mockProvider.isStoringEntriesInProjectArea());
|
||||
mockProvider.setStoringEntriesInProjectArea(true);
|
||||
assertEquals(true, mockProvider.isStoringEntriesInProjectArea());
|
||||
|
||||
mockProvider.setLanguageScope(languages);
|
||||
assertEquals(languages, mockProvider.getLanguageScope());
|
||||
|
@ -143,17 +137,153 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNoProviders() throws Exception {
|
||||
// serialize language settings of user defined providers (on workspace level)
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace();
|
||||
LanguageSettingsProvidersSerializer.loadLanguageSettingsWorkspace();
|
||||
public void testProvider_RegularDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
{
|
||||
// create customized provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider.setStoringEntriesInProjectArea(true);
|
||||
provider.setCustomParameter(CUSTOM_PARAMETER);
|
||||
|
||||
// test passes if no exception was thrown
|
||||
List<String> languageScope = new ArrayList<String>();
|
||||
languageScope.add(LANG_ID);
|
||||
provider.setLanguageScope(languageScope);
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 1));
|
||||
provider.setSettingEntries(null, null, null, entries);
|
||||
|
||||
// serialize
|
||||
Document doc = XmlUtil.newDocument();
|
||||
Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
elementProvider = provider.serialize(rootElement);
|
||||
// check XML
|
||||
String xmlString = XmlUtil.toString(doc);
|
||||
assertTrue(xmlString.contains(PROVIDER_1));
|
||||
assertTrue(xmlString.contains(PROVIDER_NAME_1));
|
||||
assertTrue(xmlString.contains(CUSTOM_PARAMETER));
|
||||
assertTrue(xmlString.contains(LANG_ID));
|
||||
assertTrue(xmlString.contains("path0"));
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(elementProvider);
|
||||
assertEquals(PROVIDER_1, provider.getId());
|
||||
assertEquals(true, provider.isStoringEntriesInProjectArea());
|
||||
assertEquals(CUSTOM_PARAMETER, provider.getCustomParameter());
|
||||
assertNotNull(provider.getLanguageScope());
|
||||
assertTrue(provider.getLanguageScope().size()>0);
|
||||
assertEquals(LANG_ID, provider.getLanguageScope().get(0));
|
||||
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, null, null);
|
||||
assertNotNull(entries);
|
||||
assertTrue(entries.size()>0);
|
||||
assertEquals(new CIncludePathEntry("path0", 1), entries.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testEmptyProvider() throws Exception {
|
||||
public void testProvider_serializeAttributesDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
{
|
||||
// create customized provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider.setStoringEntriesInProjectArea(true);
|
||||
provider.setCustomParameter(CUSTOM_PARAMETER);
|
||||
|
||||
List<String> languageScope = new ArrayList<String>();
|
||||
languageScope.add(LANG_ID);
|
||||
provider.setLanguageScope(languageScope);
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 1));
|
||||
provider.setSettingEntries(null, null, null, entries);
|
||||
|
||||
// serialize
|
||||
Document doc = XmlUtil.newDocument();
|
||||
Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
elementProvider = provider.serializeAttributes(rootElement);
|
||||
// check XML
|
||||
String xmlString = XmlUtil.toString(doc);
|
||||
assertTrue(xmlString.contains(PROVIDER_1));
|
||||
assertTrue(xmlString.contains(PROVIDER_NAME_1));
|
||||
assertTrue(xmlString.contains(CUSTOM_PARAMETER));
|
||||
assertTrue(xmlString.contains(LANG_ID));
|
||||
// no entries
|
||||
assertFalse(xmlString.contains("path0"));
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable();
|
||||
provider.loadAttributes(elementProvider);
|
||||
assertEquals(PROVIDER_1, provider.getId());
|
||||
assertEquals(true, provider.isStoringEntriesInProjectArea());
|
||||
assertEquals(CUSTOM_PARAMETER, provider.getCustomParameter());
|
||||
assertNotNull(provider.getLanguageScope());
|
||||
assertTrue(provider.getLanguageScope().size()>0);
|
||||
assertEquals(LANG_ID, provider.getLanguageScope().get(0));
|
||||
// no entries should be loaded
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, null, null);
|
||||
assertNull(entries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testProvider_serializeEntriesDOM() throws Exception {
|
||||
Element rootElement;
|
||||
{
|
||||
// create customized provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider.setStoringEntriesInProjectArea(true);
|
||||
provider.setCustomParameter(CUSTOM_PARAMETER);
|
||||
|
||||
List<String> languageScope = new ArrayList<String>();
|
||||
languageScope.add(LANG_ID);
|
||||
provider.setLanguageScope(languageScope);
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 1));
|
||||
provider.setSettingEntries(null, null, null, entries);
|
||||
|
||||
// serialize
|
||||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
provider.serializeEntries(rootElement);
|
||||
// check XML
|
||||
String xmlString = XmlUtil.toString(doc);
|
||||
// no attributes
|
||||
assertFalse(xmlString.contains(PROVIDER_1));
|
||||
assertFalse(xmlString.contains(PROVIDER_NAME_1));
|
||||
assertFalse(xmlString.contains(CUSTOM_PARAMETER));
|
||||
assertFalse(xmlString.contains(LANG_ID));
|
||||
// entries should be present
|
||||
assertTrue(xmlString.contains("path0"));
|
||||
}
|
||||
{
|
||||
// re-load and check language settings of the newly loaded provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(PROVIDER_2, PROVIDER_NAME_2);
|
||||
provider.loadEntries(rootElement);
|
||||
assertEquals(PROVIDER_2, provider.getId());
|
||||
assertEquals(PROVIDER_NAME_2, provider.getName());
|
||||
// no attributes should be loaded
|
||||
assertFalse(PROVIDER_1.equals(provider.getId()));
|
||||
assertFalse(PROVIDER_NAME_1.equals(provider.getName()));
|
||||
assertFalse(true==provider.isStoringEntriesInProjectArea());
|
||||
assertFalse(CUSTOM_PARAMETER.equals(provider.getCustomParameter()));
|
||||
assertNull(provider.getLanguageScope());
|
||||
// entries should be loaded
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, null, null);
|
||||
assertNotNull(entries);
|
||||
assertTrue(entries.size()>0);
|
||||
assertEquals(new CIncludePathEntry("path0", 1), entries.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testProvider_EmptyDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
{
|
||||
// create null provider
|
||||
|
@ -180,7 +310,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCustomParameter() throws Exception {
|
||||
public void testCustomParameterDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
{
|
||||
// create provider with custom parameter
|
||||
|
@ -203,14 +333,14 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testStoreEntriesWithProject() throws Exception {
|
||||
public void testStoreEntriesWithProjectDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
{
|
||||
// create provider with custom parameter
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(PROVIDER_1, PROVIDER_NAME_1);
|
||||
assertEquals(false, provider.isEntriesStorageWithProject());
|
||||
provider.setEntriesStorageWithProject(true);
|
||||
assertEquals(true, provider.isEntriesStorageWithProject());
|
||||
assertEquals(false, provider.isStoringEntriesInProjectArea());
|
||||
provider.setStoringEntriesInProjectArea(true);
|
||||
assertEquals(true, provider.isStoringEntriesInProjectArea());
|
||||
|
||||
Document doc = XmlUtil.newDocument();
|
||||
Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
|
@ -222,13 +352,13 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
{
|
||||
// re-load and check custom parameter of the newly loaded provider
|
||||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(elementProvider);
|
||||
assertEquals(true, provider.isEntriesStorageWithProject());
|
||||
assertEquals(true, provider.isStoringEntriesInProjectArea());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testLanguages() throws Exception {
|
||||
public void testLanguagesDOM() throws Exception {
|
||||
List<String> expectedLanguageIds = new ArrayList<String>();
|
||||
expectedLanguageIds.add(LANG_ID);
|
||||
expectedLanguageIds.add(LANG_ID_1);
|
||||
|
@ -262,7 +392,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testLanguageScope() throws Exception {
|
||||
public void testLanguageScopeDOM() throws Exception {
|
||||
// benchmark entries
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 0));
|
||||
|
@ -347,7 +477,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullConfiguration() throws Exception {
|
||||
public void testNullConfigurationDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -376,7 +506,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullLanguage() throws Exception {
|
||||
public void testNullLanguageDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -406,7 +536,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullLanguageScope() throws Exception {
|
||||
public void testNullLanguageScopeDOM() throws Exception {
|
||||
// define benchmark entries
|
||||
List<ICLanguageSettingEntry> entriesNullLanguage = new ArrayList<ICLanguageSettingEntry>();
|
||||
entriesNullLanguage.add(new CIncludePathEntry("path_null", 0));
|
||||
|
@ -481,7 +611,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullResource() throws Exception {
|
||||
public void testNullResourceDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -510,7 +640,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullConfigurationLanguage() throws Exception {
|
||||
public void testNullConfigurationLanguageDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -540,7 +670,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullConfigurationResource() throws Exception {
|
||||
public void testNullConfigurationResourceDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -570,7 +700,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullLanguageResource() throws Exception {
|
||||
public void testNullLanguageResourceDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -600,7 +730,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testNullConfigurationLanguageResourceFlag() throws Exception {
|
||||
public void testNullConfigurationLanguageResourceFlagDOM() throws Exception {
|
||||
// provider/configuration/language/resource/settingEntry
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -633,7 +763,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCIncludePathEntry() throws Exception {
|
||||
public void testCIncludePathEntryDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 1));
|
||||
|
@ -666,7 +796,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCIncludeFileEntry() throws Exception {
|
||||
public void testCIncludeFileEntryDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludeFileEntry("name", 1));
|
||||
|
@ -698,7 +828,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCMacroEntry() throws Exception {
|
||||
public void testCMacroEntryDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CMacroEntry("MACRO0", "value0",1));
|
||||
|
@ -730,7 +860,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCMacroFileEntry() throws Exception {
|
||||
public void testCMacroFileEntryDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CMacroFileEntry("name", 1));
|
||||
|
@ -762,7 +892,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCLibraryPathEntry() throws Exception {
|
||||
public void testCLibraryPathEntryDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CLibraryPathEntry("name", 1));
|
||||
|
@ -794,7 +924,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testCLibraryFileEntry() throws Exception {
|
||||
public void testCLibraryFileEntryDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CLibraryFileEntry("name", 1));
|
||||
|
@ -826,7 +956,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testMixedSettingEntries() throws Exception {
|
||||
public void testMixedSettingEntriesDOM() throws Exception {
|
||||
Element elementProvider;
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 1));
|
||||
|
@ -856,7 +986,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testLanguageAndNull() throws Exception {
|
||||
public void testLanguageAndNullDOM() throws Exception {
|
||||
Element elementProvider = null;
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -892,7 +1022,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testTwoLanguages() throws Exception {
|
||||
public void testTwoLanguagesDOM() throws Exception {
|
||||
Element elementProvider = null;
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
@ -930,7 +1060,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
|
||||
/**
|
||||
*/
|
||||
public void testTwoResources() throws Exception {
|
||||
public void testTwoResourcesDOM() throws Exception {
|
||||
// Create resources
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
IFile rc1 = ResourceHelper.createFile(project, "rc1");
|
||||
|
@ -1043,8 +1173,8 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
LanguageSettingsSerializable provider1 = new LanguageSettingsSerializable(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider1.setLanguageScope(sampleLanguages);
|
||||
provider1.setCustomParameter(CUSTOM_PARAMETER);
|
||||
assertEquals(false, provider1.isEntriesStorageWithProject());
|
||||
provider1.setEntriesStorageWithProject(true);
|
||||
assertEquals(false, provider1.isStoringEntriesInProjectArea());
|
||||
provider1.setStoringEntriesInProjectArea(true);
|
||||
provider1.setSettingEntries(MOCK_CFG, MOCK_RC, LANG_ID, sampleEntries_1);
|
||||
provider1.setSettingEntries(null, null, LANG_ID, sampleEntries_2);
|
||||
|
||||
|
@ -1070,7 +1200,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
assertFalse(provider1.equals(provider2));
|
||||
assertFalse(provider1.hashCode()==provider2.hashCode());
|
||||
|
||||
provider2.setEntriesStorageWithProject(true);
|
||||
provider2.setStoringEntriesInProjectArea(true);
|
||||
|
||||
// All set now, so they should be equal
|
||||
assertTrue(provider1.equals(provider2));
|
||||
|
@ -1120,8 +1250,8 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
LanguageSettingsSerializableMock provider1 = new LanguageSettingsSerializableMock(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider1.setLanguageScope(sampleLanguages);
|
||||
provider1.setCustomParameter(CUSTOM_PARAMETER);
|
||||
assertEquals(false, provider1.isEntriesStorageWithProject());
|
||||
provider1.setEntriesStorageWithProject(true);
|
||||
assertEquals(false, provider1.isStoringEntriesInProjectArea());
|
||||
provider1.setStoringEntriesInProjectArea(true);
|
||||
provider1.setSettingEntries(MOCK_CFG, MOCK_RC, LANG_ID, sampleEntries_1);
|
||||
provider1.setSettingEntries(null, null, LANG_ID, sampleEntries_2);
|
||||
|
||||
|
@ -1131,7 +1261,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
assertTrue(provider1.equals(providerClone));
|
||||
assertTrue(provider1.getClass()==providerClone.getClass());
|
||||
assertEquals(provider1.getCustomParameter(), providerClone.getCustomParameter());
|
||||
assertEquals(provider1.isEntriesStorageWithProject(), providerClone.isEntriesStorageWithProject());
|
||||
assertEquals(provider1.isStoringEntriesInProjectArea(), providerClone.isStoringEntriesInProjectArea());
|
||||
assertEquals(provider1.getLanguageScope().get(0), providerClone.getLanguageScope().get(0));
|
||||
|
||||
List<ICLanguageSettingEntry> actual1 = providerClone.getSettingEntries(MOCK_CFG, MOCK_RC, LANG_ID);
|
||||
|
@ -1168,8 +1298,8 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
LanguageSettingsSerializableMock provider1 = new LanguageSettingsSerializableMock(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider1.setLanguageScope(sampleLanguages);
|
||||
provider1.setCustomParameter(CUSTOM_PARAMETER);
|
||||
assertEquals(false, provider1.isEntriesStorageWithProject());
|
||||
provider1.setEntriesStorageWithProject(true);
|
||||
assertEquals(false, provider1.isStoringEntriesInProjectArea());
|
||||
provider1.setStoringEntriesInProjectArea(true);
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path", 1));
|
||||
|
@ -1181,7 +1311,7 @@ public class LanguageSettingsSerializableTests extends TestCase {
|
|||
assertFalse(provider1.equals(providerClone));
|
||||
assertTrue(provider1.getClass()==providerClone.getClass());
|
||||
assertEquals(provider1.getCustomParameter(), providerClone.getCustomParameter());
|
||||
assertEquals(provider1.isEntriesStorageWithProject(), providerClone.isEntriesStorageWithProject());
|
||||
assertEquals(provider1.isStoringEntriesInProjectArea(), providerClone.isStoringEntriesInProjectArea());
|
||||
assertEquals(provider1.getLanguageScope().get(0), providerClone.getLanguageScope().get(0));
|
||||
|
||||
List<ICLanguageSettingEntry> actual = providerClone.getSettingEntries(null, null, null);
|
||||
|
|
|
@ -33,6 +33,13 @@ import org.w3c.dom.Node;
|
|||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
||||
/**
|
||||
* This class is the base class for language settings providers able to serialize
|
||||
* into XML storage.
|
||||
*
|
||||
* TODO - more JavaDoc, info and hints about class hierarchy
|
||||
*
|
||||
*/
|
||||
public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
||||
public static final String ELEM_PROVIDER = "provider"; //$NON-NLS-1$
|
||||
private static final String ATTR_ID = "id"; //$NON-NLS-1$
|
||||
|
@ -54,7 +61,12 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
private static final String VALUE_WORKSPACE = "workspace"; //$NON-NLS-1$
|
||||
private static final String VALUE_PROJECT = "project"; //$NON-NLS-1$
|
||||
|
||||
private static WeakHashSet<List<ICLanguageSettingEntry>> lseListPool = new WeakHashSet<List<ICLanguageSettingEntry>>() {
|
||||
/**
|
||||
* Pool of LSE lists implemented as WeakHashSet. That allows to gain memory savings
|
||||
* at the expense of CPU time. WeakHashSet handles garbage collection when a list is not
|
||||
* referenced anywhere else. See JavaDoc {@link java.lang.ref.WeakReference} about weak reference objects.
|
||||
*/
|
||||
private static WeakHashSet<List<ICLanguageSettingEntry>> listPool = new WeakHashSet<List<ICLanguageSettingEntry>>() {
|
||||
@Override
|
||||
public synchronized List<ICLanguageSettingEntry> add(List<ICLanguageSettingEntry> list) {
|
||||
return super.add(list);
|
||||
|
@ -62,20 +74,39 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
|
||||
};
|
||||
|
||||
private boolean isEntriesStorageWithProject = false;
|
||||
/** Tells if language settings entries are persisted with the project or in workspace area while serializing. */
|
||||
private boolean storeEntriesInProjectArea = false;
|
||||
|
||||
/**
|
||||
* Storage to keep settings entries. Note that it is not necessary to keep configuration in the maps
|
||||
* as the configuration is always the one provider belongs to.
|
||||
*/
|
||||
private Map<String, // languageId
|
||||
Map<String, // resource project path
|
||||
List<ICLanguageSettingEntry>>> fStorage = new HashMap<String, Map<String, List<ICLanguageSettingEntry>>>();
|
||||
|
||||
/**
|
||||
* Default constructor. This constructor has to be always followed with setting id and name of the provider.
|
||||
*/
|
||||
public LanguageSettingsSerializable() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param id - id of the provider.
|
||||
* @param name - name of the provider. Note that this name may show up in UI.
|
||||
*/
|
||||
public LanguageSettingsSerializable(String id, String name) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor which allows to instantiate provider defined via XML markup.
|
||||
*
|
||||
* @param elementProvider
|
||||
*/
|
||||
public LanguageSettingsSerializable(Element elementProvider) {
|
||||
super();
|
||||
load(elementProvider);
|
||||
|
@ -117,6 +148,12 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
this.languageScope = new ArrayList<String>(languages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom parameter for the provider.
|
||||
* Subclasses are free to define how their behavior depends on custom parameter.
|
||||
*
|
||||
* @param customParameter
|
||||
*/
|
||||
public void setCustomParameter(String customParameter) {
|
||||
this.customParameter = customParameter;
|
||||
}
|
||||
|
@ -128,8 +165,8 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
*
|
||||
* @return {@code true} if LSE persisted with the project or {@code false} if in the workspace.
|
||||
*/
|
||||
public boolean isEntriesStorageWithProject() {
|
||||
return isEntriesStorageWithProject;
|
||||
public boolean isStoringEntriesInProjectArea() {
|
||||
return storeEntriesInProjectArea;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,14 +174,20 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
* @param storeEntriesWithProject - {@code true} if with the project,
|
||||
* {@code false} if in workspace area.
|
||||
*/
|
||||
public void setEntriesStorageWithProject(boolean storeEntriesWithProject) {
|
||||
this.isEntriesStorageWithProject = storeEntriesWithProject;
|
||||
public void setStoringEntriesInProjectArea(boolean storeEntriesWithProject) {
|
||||
this.storeEntriesInProjectArea = storeEntriesWithProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all the entries for all configurations, all resources and all languages.
|
||||
*/
|
||||
public void clear() {
|
||||
fStorage.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal convenience method to set language settings entries.
|
||||
*/
|
||||
private void setSettingEntriesInternal(String rcProjectPath, String languageId, List<ICLanguageSettingEntry> entries) {
|
||||
if (entries!=null) {
|
||||
Map<String, List<ICLanguageSettingEntry>> langMap = fStorage.get(languageId);
|
||||
|
@ -152,7 +195,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
langMap = new HashMap<String, List<ICLanguageSettingEntry>>();
|
||||
fStorage.put(languageId, langMap);
|
||||
}
|
||||
List<ICLanguageSettingEntry> sortedEntries = lseListPool.add(Collections.unmodifiableList(sortEntries(entries)));
|
||||
List<ICLanguageSettingEntry> sortedEntries = listPool.add(Collections.unmodifiableList(sortEntries(entries)));
|
||||
langMap.put(rcProjectPath, sortedEntries);
|
||||
} else {
|
||||
// do not keep nulls in the tables
|
||||
|
@ -166,6 +209,14 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some providers may collect entries in pretty much random order. For the purposes of
|
||||
* predictability, UI usability and efficient storage the entries are sorted by kinds
|
||||
* and secondary by name for kinds where the secondary order is not significant.
|
||||
*
|
||||
* @param entries - list of entries to sort.
|
||||
* @return - sorted entries.
|
||||
*/
|
||||
protected List<ICLanguageSettingEntry> sortEntries(List<ICLanguageSettingEntry> entries) {
|
||||
List<ICLanguageSettingEntry> sortedEntries = new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
Collections.sort(sortedEntries, new Comparator<ICLanguageSettingEntry>(){
|
||||
|
@ -202,8 +253,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <br> Note that this list is <b>unmodifiable</b>. To modify the list copy it, change and use
|
||||
* {@link #setSettingEntries(ICConfigurationDescription, IResource, String, List)}.
|
||||
*
|
||||
* Note that this list is unmodifiable.
|
||||
*/
|
||||
@Override
|
||||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
|
@ -223,6 +275,14 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider under parent XML element.
|
||||
*
|
||||
* @param parentElement - element where to serialize.
|
||||
* @return - newly created <provider> element. That element will already be
|
||||
* attached to the parent element.
|
||||
*/
|
||||
public Element serialize(Element parentElement) {
|
||||
/*
|
||||
<provider id="provider.id" ...>
|
||||
<language-scope id="lang.id"/>
|
||||
|
@ -233,20 +293,26 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
</language>
|
||||
</provider>
|
||||
*/
|
||||
// provider/configuration/language/resource/entry
|
||||
public Element serialize(Element parentElement) {
|
||||
Element elementProvider = serializeAttributes(parentElement);
|
||||
serializeEntries(elementProvider);
|
||||
return elementProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider attributes under parent XML element. That is
|
||||
* equivalent to serializing everything (including language scope) except entries.
|
||||
*
|
||||
* @param parentElement - element where to serialize.
|
||||
* @return - newly created <provider> element. That element will already be
|
||||
* attached to the parent element.
|
||||
*/
|
||||
public Element serializeAttributes(Element parentElement) {
|
||||
Element elementProvider = XmlUtil.appendElement(parentElement, ELEM_PROVIDER, new String[] {
|
||||
ATTR_ID, getId(),
|
||||
ATTR_NAME, getName(),
|
||||
ATTR_CLASS, getClass().getCanonicalName(),
|
||||
ATTR_PARAMETER, getCustomParameter(),
|
||||
ATTR_STORE_ENTRIES, isEntriesStorageWithProject() ? VALUE_PROJECT : VALUE_WORKSPACE,
|
||||
ATTR_STORE_ENTRIES, isStoringEntriesInProjectArea() ? VALUE_PROJECT : VALUE_WORKSPACE,
|
||||
});
|
||||
|
||||
if (languageScope!=null) {
|
||||
|
@ -257,12 +323,19 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
return elementProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider entries under parent XML element.
|
||||
* @param elementProvider - element where to serialize the entries.
|
||||
*/
|
||||
public void serializeEntries(Element elementProvider) {
|
||||
for (Entry<String, Map<String, List<ICLanguageSettingEntry>>> entryLang : fStorage.entrySet()) {
|
||||
serializeLanguage(elementProvider, entryLang);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider entries for a given language list.
|
||||
*/
|
||||
private void serializeLanguage(Element parentElement, Entry<String, Map<String, List<ICLanguageSettingEntry>>> entryLang) {
|
||||
String langId = entryLang.getKey();
|
||||
if (langId!=null) {
|
||||
|
@ -274,6 +347,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider entries for a given resource list.
|
||||
*/
|
||||
private void serializeResource(Element parentElement, Entry<String, List<ICLanguageSettingEntry>> entryRc) {
|
||||
String rcProjectPath = entryRc.getKey();
|
||||
if (rcProjectPath!=null) {
|
||||
|
@ -283,6 +359,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
serializeSettingEntries(parentElement, entryRc.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize given settings entries.
|
||||
*/
|
||||
private void serializeSettingEntries(Element parentElement, List<ICLanguageSettingEntry> settingEntries) {
|
||||
for (ICLanguageSettingEntry entry : settingEntries) {
|
||||
Element elementSettingEntry = XmlUtil.appendElement(parentElement, ELEM_ENTRY, new String[] {
|
||||
|
@ -294,7 +373,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
elementSettingEntry.setAttribute(ATTR_VALUE, entry.getValue());
|
||||
break;
|
||||
// case ICLanguageSettingEntry.LIBRARY_FILE:
|
||||
// TODO: sourceAttachment fields need to be covered
|
||||
// // TODO: sourceAttachment fields may need to be covered
|
||||
// break;
|
||||
}
|
||||
int flags = entry.getFlags();
|
||||
|
@ -307,6 +386,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a setting entry from XML element.
|
||||
*/
|
||||
private ICLanguageSettingEntry loadSettingEntry(Node parentElement) {
|
||||
String settingKind = XmlUtil.determineAttributeValue(parentElement, ATTR_KIND);
|
||||
String settingName = XmlUtil.determineAttributeValue(parentElement, ATTR_NAME);
|
||||
|
@ -333,17 +415,25 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
|
||||
|
||||
// provider/configuration/language/resource/entry
|
||||
/**
|
||||
* Load provider from XML provider element.
|
||||
* @param providerNode - XML element <provider> to load provider from.
|
||||
*/
|
||||
public void load(Element providerNode) {
|
||||
fStorage.clear();
|
||||
languageScope = null;
|
||||
|
||||
// provider/configuration/language/resource/entry
|
||||
if (providerNode!=null) {
|
||||
loadAttributes(providerNode);
|
||||
loadEntries(providerNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load attributes from XML provider element.
|
||||
* @param providerNode - XML element <provider> to load attributes from.
|
||||
*/
|
||||
public void loadAttributes(Element providerNode) {
|
||||
String providerId = XmlUtil.determineAttributeValue(providerNode, ATTR_ID);
|
||||
String providerName = XmlUtil.determineAttributeValue(providerNode, ATTR_NAME);
|
||||
|
@ -353,11 +443,8 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
this.setId(providerId);
|
||||
this.setName(providerName);
|
||||
this.setCustomParameter(providerParameter);
|
||||
this.setEntriesStorageWithProject(VALUE_PROJECT.equals(providerStoreEntries));
|
||||
}
|
||||
this.setStoringEntriesInProjectArea(VALUE_PROJECT.equals(providerStoreEntries));
|
||||
|
||||
public void loadEntries(Element providerNode) {
|
||||
List<ICLanguageSettingEntry> settings = new ArrayList<ICLanguageSettingEntry>();
|
||||
NodeList nodes = providerNode.getChildNodes();
|
||||
for (int i=0;i<nodes.getLength();i++) {
|
||||
Node elementNode = nodes.item(i);
|
||||
|
@ -366,7 +453,24 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
|
||||
if (ELEM_LANGUAGE_SCOPE.equals(elementNode.getNodeName())) {
|
||||
loadLanguageScopeElement(elementNode);
|
||||
} else if (ELEM_LANGUAGE.equals(elementNode.getNodeName())) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load provider entries from XML provider element.
|
||||
* @param providerNode - parent XML element <provider> where entries are defined.
|
||||
*/
|
||||
public void loadEntries(Element providerNode) {
|
||||
List<ICLanguageSettingEntry> settings = new ArrayList<ICLanguageSettingEntry>();
|
||||
NodeList nodes = providerNode.getChildNodes();
|
||||
for (int i=0;i<nodes.getLength();i++) {
|
||||
Node elementNode = nodes.item(i);
|
||||
if(elementNode.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (ELEM_LANGUAGE.equals(elementNode.getNodeName())) {
|
||||
loadLanguageElement(elementNode, null);
|
||||
} else if (ELEM_RESOURCE.equals(elementNode.getNodeName())) {
|
||||
loadResourceElement(elementNode, null, null);
|
||||
|
@ -383,6 +487,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine and set language scope from given XML node.
|
||||
*/
|
||||
private void loadLanguageScopeElement(Node parentNode) {
|
||||
if (languageScope==null) {
|
||||
languageScope = new ArrayList<String>();
|
||||
|
@ -392,6 +499,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load entries defined in language element.
|
||||
*/
|
||||
private void loadLanguageElement(Node parentNode, String cfgId) {
|
||||
String langId = XmlUtil.determineAttributeValue(parentNode, ATTR_ID);
|
||||
if (langId.length()==0) {
|
||||
|
@ -420,6 +530,9 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load entries defined in resource element.
|
||||
*/
|
||||
private void loadResourceElement(Node parentNode, String cfgId, String langId) {
|
||||
String rcProjectPath = XmlUtil.determineAttributeValue(parentNode, ATTR_PROJECT_PATH);
|
||||
|
||||
|
@ -444,15 +557,14 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone storage for the entries. Copies references for lists of entries as a whole.
|
||||
* Note that is OK as the lists kept in storage are unmodifiable.
|
||||
*/
|
||||
private Map<String, Map<String, List<ICLanguageSettingEntry>>> cloneStorage() {
|
||||
Map<String, // languageId
|
||||
Map<String, // resource String
|
||||
Map<String, // resource
|
||||
List<ICLanguageSettingEntry>>> storageClone = new HashMap<String, Map<String, List<ICLanguageSettingEntry>>>();
|
||||
// Set<Entry<String, Map<String, Map<String, List<ICLanguageSettingEntry>>>>> entrySetCfg = fStorage.entrySet();
|
||||
// for (Entry<String, Map<String, Map<String, List<ICLanguageSettingEntry>>>> entryCfg : entrySetCfg) {
|
||||
// String cfgDescriptionId = entryCfg.getKey();
|
||||
// Map<String, Map<String, List<ICLanguageSettingEntry>>> mapLang = entryCfg.getValue();
|
||||
// Map<String, Map<String, List<ICLanguageSettingEntry>>> mapLangClone = new HashMap<String, Map<String, List<ICLanguageSettingEntry>>>();
|
||||
Set<Entry<String, Map<String, List<ICLanguageSettingEntry>>>> entrySetLang = fStorage.entrySet();
|
||||
for (Entry<String, Map<String, List<ICLanguageSettingEntry>>> entryLang : entrySetLang) {
|
||||
String langId = entryLang.getKey();
|
||||
|
@ -462,16 +574,21 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
for (Entry<String, List<ICLanguageSettingEntry>> entryRc : entrySetRc) {
|
||||
String rcProjectPath = entryRc.getKey();
|
||||
List<ICLanguageSettingEntry> lsEntries = entryRc.getValue();
|
||||
// don't need to clone entries, they are from the pool
|
||||
// don't need to clone entries, they are from the LSE pool
|
||||
mapRcClone.put(rcProjectPath, lsEntries);
|
||||
}
|
||||
// mapLangClone.put(langId, mapRcClone);
|
||||
storageClone.put(langId, mapRcClone);
|
||||
}
|
||||
// }
|
||||
return storageClone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow clone of the provider. "Shallow" is defined here as the exact copy except that
|
||||
* the copy will have zero language settings entries.
|
||||
*
|
||||
* @return shallow copy of the provider.
|
||||
* @throws CloneNotSupportedException in case {@link #clone()} throws the exception.
|
||||
*/
|
||||
protected LanguageSettingsSerializable cloneShallow() throws CloneNotSupportedException {
|
||||
LanguageSettingsSerializable clone = (LanguageSettingsSerializable)super.clone();
|
||||
if (languageScope!=null)
|
||||
|
@ -481,9 +598,6 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
return clone;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
protected LanguageSettingsSerializable clone() throws CloneNotSupportedException {
|
||||
LanguageSettingsSerializable clone = cloneShallow();
|
||||
|
@ -499,7 +613,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
|
||||
result = prime * result + ((languageScope == null) ? 0 : languageScope.hashCode());
|
||||
result = prime * result + ((customParameter == null) ? 0 : customParameter.hashCode());
|
||||
result = prime * result + (isEntriesStorageWithProject ? 0 : 1);
|
||||
result = prime * result + (storeEntriesInProjectArea ? 0 : 1);
|
||||
result = prime * result + ((fStorage == null) ? 0 : fStorage.hashCode());
|
||||
result = prime * result + getClass().hashCode();
|
||||
return result;
|
||||
|
@ -507,7 +621,6 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
|
||||
/**
|
||||
* @return {@code true} if the objects are equal, {@code false } otherwise.
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
|
@ -548,7 +661,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
} else if (!customParameter.equals(other.customParameter))
|
||||
return false;
|
||||
|
||||
if (isEntriesStorageWithProject!=other.isEntriesStorageWithProject)
|
||||
if (storeEntriesInProjectArea!=other.storeEntriesInProjectArea)
|
||||
return false;
|
||||
|
||||
if (fStorage == null) {
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 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.internal.core.language.settings.providers;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -41,6 +52,7 @@ public class LanguageSettingsProvidersSerializer {
|
|||
private static final String ATTR_POINT = "point"; //$NON-NLS-1$
|
||||
private static final String ELEM_PROJECT = "project"; //$NON-NLS-1$
|
||||
private static final String ELEM_CONFIGURATION = "configuration"; //$NON-NLS-1$
|
||||
private static final String ELEM_PROVIDER = "provider"; //$NON-NLS-1$
|
||||
private static final String ELEM_PROVIDER_REFERENCE = "provider-reference"; //$NON-NLS-1$
|
||||
/** Cache of globally available providers to be consumed by calling clients */
|
||||
private static Map<String, ILanguageSettingsProvider> rawGlobalWorkspaceProviders = new HashMap<String, ILanguageSettingsProvider>();
|
||||
|
@ -104,9 +116,31 @@ public class LanguageSettingsProvidersSerializer {
|
|||
} catch (Throwable e) {
|
||||
CCorePlugin.log("Error loading workspace language settings providers", e); //$NON-NLS-1$
|
||||
} finally {
|
||||
// swallow any exception
|
||||
}
|
||||
}
|
||||
|
||||
private static IFile getStoreInProjectArea(IProject project) throws CoreException {
|
||||
IFolder folder = project.getFolder(SETTINGS_FOLDER_NAME);
|
||||
if (!folder.exists()) {
|
||||
folder.create(true, true, null);
|
||||
}
|
||||
IFile storage = folder.getFile(STORAGE_PROJECT_LANGUAGE_SETTINGS);
|
||||
return storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: refactor with ErrorParserManager ?
|
||||
*
|
||||
* @param store - name of the store
|
||||
* @return location of the store in the plug-in state area
|
||||
*/
|
||||
private static URI getStoreInWorkspaceArea(String store) {
|
||||
IPath location = CCorePlugin.getDefault().getStateLocation().append(store);
|
||||
URI uri = URIUtil.toURI(location);
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and store in workspace area user defined providers.
|
||||
*
|
||||
|
@ -151,20 +185,8 @@ public class LanguageSettingsProvidersSerializer {
|
|||
rawGlobalWorkspaceProviders = rawWorkspaceProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: refactor with ErrorParserManager
|
||||
*
|
||||
* @param store - name of the store
|
||||
* @return location of the store in the plug-in state area
|
||||
*/
|
||||
private static URI getStoreLocationInWorkspaceArea(String store) {
|
||||
IPath location = CCorePlugin.getDefault().getStateLocation().append(store);
|
||||
URI uri = URIUtil.toURI(location);
|
||||
return uri;
|
||||
}
|
||||
|
||||
public static void serializeLanguageSettingsWorkspace() throws CoreException {
|
||||
URI uriLocation = getStoreLocationInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
URI uriLocation = getStoreInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
List<LanguageSettingsSerializable> serializableExtensionProviders = new ArrayList<LanguageSettingsSerializable>();
|
||||
for (ILanguageSettingsProvider provider : rawGlobalWorkspaceProviders.values()) {
|
||||
if (provider instanceof LanguageSettingsSerializable) {
|
||||
|
@ -206,7 +228,7 @@ public class LanguageSettingsProvidersSerializer {
|
|||
public static void loadLanguageSettingsWorkspace() throws CoreException {
|
||||
List <ILanguageSettingsProvider> providers = null;
|
||||
|
||||
URI uriLocation = getStoreLocationInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
URI uriLocation = getStoreInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
|
||||
Document doc = null;
|
||||
try {
|
||||
|
@ -246,17 +268,24 @@ public class LanguageSettingsProvidersSerializer {
|
|||
setWorkspaceProvidersInternal(providers);
|
||||
}
|
||||
|
||||
public static void serializeLanguageSettings(Element parentElement, ICProjectDescription prjDescription) throws CoreException {
|
||||
/**
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* It is public solely for benefit of JUnit testing.
|
||||
*/
|
||||
public static void serializeLanguageSettingsInternal(Element projectElementPrjStore, Element projectElementWspStore, ICProjectDescription prjDescription) throws CoreException {
|
||||
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
|
||||
for (ICConfigurationDescription cfgDescription : cfgDescriptions) {
|
||||
Element elementConfiguration = XmlUtil.appendElement(parentElement, ELEM_CONFIGURATION, new String[] {
|
||||
Element elementConfiguration = XmlUtil.appendElement(projectElementPrjStore, ELEM_CONFIGURATION, new String[] {
|
||||
LanguageSettingsExtensionManager.ATTR_ID, cfgDescription.getId(),
|
||||
LanguageSettingsExtensionManager.ATTR_NAME, cfgDescription.getName(),
|
||||
});
|
||||
Element elementConfigurationWsp = null;
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
if (providers.size()>0) {
|
||||
Element elementExtension = XmlUtil.appendElement(elementConfiguration, ELEM_EXTENSION, new String[] {
|
||||
ATTR_POINT, LanguageSettingsExtensionManager.PROVIDER_EXTENSION_FULL_ID});
|
||||
Element elementExtensionWsp = null;
|
||||
for (ILanguageSettingsProvider provider : providers) {
|
||||
if (isWorkspaceProvider(provider)) {
|
||||
// Element elementProviderReference =
|
||||
|
@ -265,7 +294,29 @@ public class LanguageSettingsProvidersSerializer {
|
|||
continue;
|
||||
}
|
||||
if (provider instanceof LanguageSettingsSerializable) {
|
||||
((LanguageSettingsSerializable) provider).serialize(elementExtension);
|
||||
LanguageSettingsSerializable lss = (LanguageSettingsSerializable) provider;
|
||||
|
||||
boolean useWsp = projectElementWspStore!=null && projectElementPrjStore!=projectElementWspStore;
|
||||
if (lss.isStoringEntriesInProjectArea() || !useWsp) {
|
||||
lss.serialize(elementExtension);
|
||||
} else {
|
||||
lss.serializeAttributes(elementExtension);
|
||||
|
||||
// lazy initialization of elements - to avoid serialization of no-data file
|
||||
if (elementExtensionWsp==null) {
|
||||
if (elementConfigurationWsp==null) {
|
||||
elementConfigurationWsp = XmlUtil.appendElement(projectElementWspStore, ELEM_CONFIGURATION, new String[] {
|
||||
LanguageSettingsExtensionManager.ATTR_ID, cfgDescription.getId(),
|
||||
LanguageSettingsExtensionManager.ATTR_NAME, cfgDescription.getName(),
|
||||
});
|
||||
}
|
||||
elementExtensionWsp = XmlUtil.appendElement(elementConfigurationWsp, ELEM_EXTENSION, new String[] {
|
||||
ATTR_POINT, LanguageSettingsExtensionManager.PROVIDER_EXTENSION_FULL_ID});
|
||||
}
|
||||
Element elementProviderWsp = XmlUtil.appendElement(elementExtensionWsp, ELEM_PROVIDER, new String[] {
|
||||
LanguageSettingsExtensionManager.ATTR_ID, provider.getId()});
|
||||
lss.serializeEntries(elementProviderWsp);
|
||||
}
|
||||
} else {
|
||||
// Element elementProvider =
|
||||
XmlUtil.appendElement(elementExtension, LanguageSettingsExtensionManager.ELEM_PROVIDER, new String[] {
|
||||
|
@ -279,25 +330,33 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
private static IFile getStorage(IProject project) throws CoreException {
|
||||
IFolder folder = project.getFolder(SETTINGS_FOLDER_NAME);
|
||||
if (!folder.exists()) {
|
||||
folder.create(true, true, null);
|
||||
}
|
||||
IFile storage = folder.getFile(STORAGE_PROJECT_LANGUAGE_SETTINGS);
|
||||
return storage;
|
||||
}
|
||||
|
||||
public static void serializeLanguageSettings(ICProjectDescription prjDescription) throws CoreException {
|
||||
IProject project = prjDescription.getProject();
|
||||
try {
|
||||
Document doc = XmlUtil.newDocument();
|
||||
Element rootElement = XmlUtil.appendElement(doc, ELEM_PROJECT);
|
||||
serializeLanguageSettings(rootElement, prjDescription);
|
||||
// Document to store in project area
|
||||
Document docPrjStore = XmlUtil.newDocument();
|
||||
Element projectElementPrjStore = XmlUtil.appendElement(docPrjStore, ELEM_PROJECT);
|
||||
// Document to store in workspace area
|
||||
Document docWspStore = XmlUtil.newDocument();
|
||||
Element projectElementWspStore = XmlUtil.appendElement(docWspStore, ELEM_PROJECT);
|
||||
|
||||
serializeLanguageSettingsInternal(projectElementPrjStore, projectElementWspStore, prjDescription);
|
||||
|
||||
IFile filePrjStore = getStoreInProjectArea(project);
|
||||
URI uriWspStore = null;
|
||||
boolean isWorkspaceStoreEmpty = projectElementWspStore.getChildNodes().getLength() == 0;
|
||||
uriWspStore = getStoreInWorkspaceArea(project.getName()+'.'+STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
|
||||
IFile file = getStorage(project);
|
||||
synchronized (serializingLock){
|
||||
XmlUtil.serializeXml(doc, file);
|
||||
// The project store should not be absent. Absent store means legacy project, not 0 providers.
|
||||
XmlUtil.serializeXml(docPrjStore, filePrjStore);
|
||||
|
||||
// project-specific location in workspace area
|
||||
if (!isWorkspaceStoreEmpty) {
|
||||
XmlUtil.serializeXml(docWspStore, uriWspStore);
|
||||
} else {
|
||||
new java.io.File(uriWspStore).delete();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
@ -307,7 +366,11 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
public static void loadLanguageSettings(Element parentElement, ICProjectDescription prjDescription) {
|
||||
/**
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* It is public solely for benefit of JUnit testing.
|
||||
*/
|
||||
public static void loadLanguageSettingsInternal(Element projectElementPrj, Element projectElementWsp, ICProjectDescription prjDescription) {
|
||||
/*
|
||||
<project>
|
||||
<configuration id="cfg.id">
|
||||
|
@ -318,7 +381,7 @@ public class LanguageSettingsProvidersSerializer {
|
|||
</configuration>
|
||||
</project>
|
||||
*/
|
||||
NodeList configurationNodes = parentElement.getChildNodes();
|
||||
NodeList configurationNodes = projectElementPrj.getChildNodes();
|
||||
for (int ic=0;ic<configurationNodes.getLength();ic++) {
|
||||
Node cfgNode = configurationNodes.item(ic);
|
||||
if (!(cfgNode instanceof Element && cfgNode.getNodeName().equals(ELEM_CONFIGURATION)) )
|
||||
|
@ -348,6 +411,12 @@ public class LanguageSettingsProvidersSerializer {
|
|||
provider = getWorkspaceProvider(providerId);
|
||||
} else if (providerNode.getNodeName().equals(LanguageSettingsExtensionManager.ELEM_PROVIDER)) {
|
||||
provider = loadProvider(providerNode);
|
||||
if (provider instanceof LanguageSettingsSerializable) {
|
||||
LanguageSettingsSerializable lss = (LanguageSettingsSerializable) provider;
|
||||
if (!lss.isStoringEntriesInProjectArea() && projectElementWsp!=null) {
|
||||
loadProviderEntries(lss, cfgId, projectElementWsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (provider!=null) {
|
||||
providers.add(provider);
|
||||
|
@ -362,6 +431,56 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
private static void loadProviderEntries(LanguageSettingsSerializable provider, String cfgId, Element projectElementWsp) {
|
||||
/*
|
||||
<project>
|
||||
<configuration id="cfg.id">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider .../>
|
||||
<provider-reference id="..."/>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
||||
*/
|
||||
NodeList configurationNodes = projectElementWsp.getChildNodes();
|
||||
for (int ic=0;ic<configurationNodes.getLength();ic++) {
|
||||
Node cfgNode = configurationNodes.item(ic);
|
||||
if (!(cfgNode instanceof Element && cfgNode.getNodeName().equals(ELEM_CONFIGURATION)) )
|
||||
continue;
|
||||
String cfgIdXml = XmlUtil.determineAttributeValue(cfgNode, LanguageSettingsExtensionManager.ATTR_ID);
|
||||
if (!cfgId.equals(cfgIdXml))
|
||||
continue;
|
||||
|
||||
NodeList extensionAndReferenceNodes = cfgNode.getChildNodes();
|
||||
for (int ie=0;ie<extensionAndReferenceNodes.getLength();ie++) {
|
||||
Node extNode = extensionAndReferenceNodes.item(ie);
|
||||
if (!(extNode instanceof Element))
|
||||
continue;
|
||||
|
||||
if (extNode.getNodeName().equals(ELEM_EXTENSION)) {
|
||||
NodeList providerNodes = extNode.getChildNodes();
|
||||
|
||||
for (int i=0;i<providerNodes.getLength();i++) {
|
||||
Node providerNode = providerNodes.item(i);
|
||||
if (!(providerNode instanceof Element))
|
||||
continue;
|
||||
if (!providerNode.getNodeName().equals(LanguageSettingsExtensionManager.ELEM_PROVIDER))
|
||||
continue;
|
||||
String providerIdXml = XmlUtil.determineAttributeValue(providerNode, LanguageSettingsExtensionManager.ATTR_ID);
|
||||
if (!provider.getId().equals(providerIdXml))
|
||||
continue;
|
||||
|
||||
provider.loadEntries((Element) providerNode);
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static ILanguageSettingsProvider loadProvider(Node providerNode) {
|
||||
String attrClass = XmlUtil.determineAttributeValue(providerNode, LanguageSettingsExtensionManager.ATTR_CLASS);
|
||||
ILanguageSettingsProvider provider = LanguageSettingsExtensionManager.getProviderInstance(attrClass);
|
||||
|
@ -388,8 +507,21 @@ public class LanguageSettingsProvidersSerializer {
|
|||
synchronized (serializingLock) {
|
||||
doc = XmlUtil.loadXml(file);
|
||||
}
|
||||
Element rootElement = doc.getDocumentElement(); // <project/>
|
||||
loadLanguageSettings(rootElement, prjDescription);
|
||||
Element rootElementPrj = doc.getDocumentElement(); // <project/>
|
||||
|
||||
URI uriLocation = getStoreInWorkspaceArea(project.getName()+'.'+STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
Document docWsp = null;
|
||||
synchronized (serializingLock) {
|
||||
docWsp = XmlUtil.loadXml(uriLocation);
|
||||
}
|
||||
|
||||
Element rootElementWsp = null; // <project/>
|
||||
if (docWsp!=null) {
|
||||
rootElementWsp = docWsp.getDocumentElement();
|
||||
}
|
||||
|
||||
|
||||
loadLanguageSettingsInternal(rootElementPrj, rootElementWsp, prjDescription);
|
||||
} catch (Exception e) {
|
||||
CCorePlugin.log("Can't load preferences from file "+file.getLocation(), e); //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -406,7 +406,7 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
|
|||
provider = toggleGlobalProvider(provider, isGlobal);
|
||||
}
|
||||
projectStorageCheckBox.setSelection(provider instanceof LanguageSettingsSerializable
|
||||
&& ((LanguageSettingsSerializable) provider).isEntriesStorageWithProject());
|
||||
&& ((LanguageSettingsSerializable) provider).isStoringEntriesInProjectArea());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -424,7 +424,7 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
|
|||
boolean isWithProject = projectStorageCheckBox.getSelection();
|
||||
ILanguageSettingsProvider provider = getWorkingCopy(getSelectedProvider().getId());
|
||||
Assert.isTrue(provider instanceof LanguageSettingsSerializable);
|
||||
((LanguageSettingsSerializable)provider).setEntriesStorageWithProject(isWithProject);
|
||||
((LanguageSettingsSerializable)provider).setStoringEntriesInProjectArea(isWithProject);
|
||||
refreshItem(provider);
|
||||
}
|
||||
|
||||
|
@ -605,7 +605,7 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
|
|||
projectStorageCheckBox.setEnabled(!isGlobal);
|
||||
projectStorageCheckBox.setVisible(rawProvider instanceof LanguageSettingsSerializable);
|
||||
projectStorageCheckBox.setSelection(provider instanceof LanguageSettingsSerializable
|
||||
&& ((LanguageSettingsSerializable)provider).isEntriesStorageWithProject());
|
||||
&& ((LanguageSettingsSerializable)provider).isStoringEntriesInProjectArea());
|
||||
|
||||
boolean needPreferencesLink=isGlobal && currentOptionsPage!=null;
|
||||
// TODO: message
|
||||
|
|
Loading…
Add table
Reference in a new issue