mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
ILanguageSettingsChangeEvent notifications
This commit is contained in:
parent
babba4a0a7
commit
5fffd285f0
20 changed files with 1826 additions and 669 deletions
|
@ -18,9 +18,14 @@ import junit.framework.TestCase;
|
|||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.settings.model.CMacroEntry;
|
||||
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.testplugin.ResourceHelper;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.ILanguageSettingsChangeEvent;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.ILanguageSettingsChangeListener;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
||||
/**
|
||||
|
@ -29,12 +34,38 @@ import org.eclipse.core.resources.IProject;
|
|||
public class LanguageSettingsListenersTests extends TestCase {
|
||||
// Must match provider id defined as extension point
|
||||
private static final String EXTENSION_REGISTERER_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.listener.registerer.provider";
|
||||
private static final String EXTENSION_EDITABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.editable.language.settings.provider";
|
||||
|
||||
private static final String PROVIDER_1 = "test.provider.1.id";
|
||||
private static final String PROVIDER_NAME_1 = "test.provider.1.name";
|
||||
private static final String PROVIDER_CUSTOM_GLOBAL = "test.provider.custom.global.id";
|
||||
private static final String PROVIDER_CUSTOM_GLOBAL_NAME = "test.provider.custom.global.name";
|
||||
|
||||
private static final CMacroEntry SAMPLE_LSE = new CMacroEntry("MACRO", "value",0);
|
||||
private class MockLanguageSettingsChangeListener implements ILanguageSettingsChangeListener {
|
||||
private int count = 0;
|
||||
private ILanguageSettingsChangeEvent lastEvent = null;
|
||||
|
||||
public void handleEvent(ILanguageSettingsChangeEvent event) {
|
||||
count++;
|
||||
lastEvent = event;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void resetCount() {
|
||||
count = 0;
|
||||
lastEvent = null;
|
||||
}
|
||||
|
||||
public ILanguageSettingsChangeEvent getLastEvent() {
|
||||
return lastEvent;
|
||||
}
|
||||
}
|
||||
private MockLanguageSettingsChangeListener mockLseListener = new MockLanguageSettingsChangeListener();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param name - name of the test.
|
||||
|
@ -50,6 +81,7 @@ public class LanguageSettingsListenersTests extends TestCase {
|
|||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
LanguageSettingsProvidersSerializer.unregisterLanguageSettingsChangeListener(mockLseListener);
|
||||
LanguageSettingsManager.setWorkspaceProviders(null);
|
||||
ResourceHelper.cleanUp();
|
||||
}
|
||||
|
@ -489,6 +521,543 @@ public class LanguageSettingsListenersTests extends TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_cfgProvider_AddEmptyProvider() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
// First clear default providers
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// clear providers
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Add empty provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// create a provider and add to cfgDescription
|
||||
ILanguageSettingsProvider mockProvider = new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1);
|
||||
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.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// No notifications expected
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_cfgProvider_AddNonEmptyProvider() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
// First clear default providers
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// clear providers
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Add non-empty provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescription.getId();
|
||||
|
||||
// create a provider and add entries
|
||||
MockLanguageSettingsEditableProvider mockProvider = new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1);
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(SAMPLE_LSE);
|
||||
mockProvider.setSettingEntries(cfgDescription, project, 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.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
|
||||
// inspect notifications
|
||||
assertEquals(1, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNotNull(event);
|
||||
|
||||
assertEquals(project.getName(), event.getProjectName());
|
||||
assertEquals(1, event.getConfigurationDescriptionIds().length);
|
||||
assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]);
|
||||
assertEquals(1, event.getResources(cfgDescriptionId).length);
|
||||
assertEquals(project, event.getResources(cfgDescriptionId)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_cfgProvider_SerializeEntries() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
|
||||
// add the mock provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// create a provider and add to cfgDescription
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1));
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Change the provider's entries
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, false);
|
||||
assertNotNull(prjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescription.getId();
|
||||
|
||||
// Add entries
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(SAMPLE_LSE);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, providers.size());
|
||||
assertTrue(providers.get(0) instanceof MockLanguageSettingsEditableProvider);
|
||||
MockLanguageSettingsEditableProvider mockProvider = (MockLanguageSettingsEditableProvider) providers.get(0);
|
||||
mockProvider.setSettingEntries(cfgDescription, project, null, entries);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Serialize settings
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(prjDescription);
|
||||
// inspect event
|
||||
assertEquals(1, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNotNull(event);
|
||||
|
||||
assertEquals(project.getName(), event.getProjectName());
|
||||
assertEquals(1, event.getConfigurationDescriptionIds().length);
|
||||
assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]);
|
||||
assertEquals(1, event.getResources(cfgDescriptionId).length);
|
||||
assertEquals(project, event.getResources(cfgDescriptionId)[0]);
|
||||
// TODO - drill to the entries
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_cfgProvider_SerializeEntriesConcurrent() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
|
||||
// add the mock provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// create a provider and add to cfgDescription
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(new MockLanguageSettingsEditableProvider(PROVIDER_1, PROVIDER_NAME_1));
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Change the provider's entries concurrently
|
||||
|
||||
// get project descriptions
|
||||
ICProjectDescription prjDescription_1 = CoreModel.getDefault().getProjectDescription(project, false);
|
||||
assertNotNull(prjDescription_1);
|
||||
ICProjectDescription prjDescription_2 = CoreModel.getDefault().getProjectDescription(project, false);
|
||||
assertNotNull(prjDescription_2);
|
||||
{
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription_1.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescriptionWritable.getId();
|
||||
|
||||
// Add entries
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(SAMPLE_LSE);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescriptionWritable.getLanguageSettingProviders();
|
||||
assertEquals(1, providers.size());
|
||||
assertTrue(providers.get(0) instanceof MockLanguageSettingsEditableProvider);
|
||||
MockLanguageSettingsEditableProvider mockProvider = (MockLanguageSettingsEditableProvider) providers.get(0);
|
||||
mockProvider.setSettingEntries(cfgDescriptionWritable, project, null, entries);
|
||||
|
||||
// reset count
|
||||
mockLseListener.resetCount();
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertNull(mockLseListener.getLastEvent());
|
||||
|
||||
// Serialize settings
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(prjDescription_1);
|
||||
// inspect event
|
||||
assertEquals(1, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNotNull(event);
|
||||
|
||||
assertEquals(project.getName(), event.getProjectName());
|
||||
assertEquals(1, event.getConfigurationDescriptionIds().length);
|
||||
assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]);
|
||||
assertEquals(1, event.getResources(cfgDescriptionId).length);
|
||||
assertEquals(project, event.getResources(cfgDescriptionId)[0]);
|
||||
// TODO - drill to the entries
|
||||
}
|
||||
{
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription_2.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescriptionWritable = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescriptionWritable.getId();
|
||||
|
||||
// Add same entries
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(SAMPLE_LSE);
|
||||
List<ILanguageSettingsProvider> providers = cfgDescriptionWritable.getLanguageSettingProviders();
|
||||
assertEquals(1, providers.size());
|
||||
assertTrue(providers.get(0) instanceof MockLanguageSettingsEditableProvider);
|
||||
MockLanguageSettingsEditableProvider mockProvider = (MockLanguageSettingsEditableProvider) providers.get(0);
|
||||
mockProvider.setSettingEntries(cfgDescriptionWritable, project, null, entries);
|
||||
|
||||
// reset count
|
||||
mockLseListener.resetCount();
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertNull(mockLseListener.getLastEvent());
|
||||
|
||||
// Serialize settings
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettings(prjDescription_2);
|
||||
// inspect event
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNull(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_globalProvider_AddEmptyProvider() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
// First clear default providers
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// clear providers
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Add empty global provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// retrieve a global provider
|
||||
ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID);
|
||||
assertNotNull(wspProvider);
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider);
|
||||
// clear it
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).clear();
|
||||
assertEquals(null, wspProvider.getSettingEntries(cfgDescription, project, null));
|
||||
// add the provider to cfgDescription
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(wspProvider);
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// No notifications expected
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_globalProvider_AddNonEmptyProvider() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
// First clear default providers
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// clear providers
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(0, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Add non-empty provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescription.getId();
|
||||
|
||||
// retrieve a global provider
|
||||
ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID);
|
||||
assertNotNull(wspProvider);
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider);
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).clear();
|
||||
// add entries
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(SAMPLE_LSE);
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).setSettingEntries(cfgDescription, project, null, entries);
|
||||
assertEquals(SAMPLE_LSE, wspProvider.getSettingEntries(cfgDescription, project, null).get(0));
|
||||
// add the provider to cfgDescription
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(wspProvider);
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
|
||||
// inspect notifications
|
||||
assertEquals(1, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNotNull(event);
|
||||
|
||||
assertEquals(project.getName(), event.getProjectName());
|
||||
assertEquals(1, event.getConfigurationDescriptionIds().length);
|
||||
assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]);
|
||||
assertEquals(1, event.getResources(cfgDescriptionId).length);
|
||||
assertEquals(project, event.getResources(cfgDescriptionId)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void testNotification_globalProvider_SerializeEntries() throws Exception {
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(this.getName());
|
||||
|
||||
// register mock listener to inspect the notifications
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(mockLseListener);
|
||||
|
||||
// Add empty global provider
|
||||
{
|
||||
// get project descriptions
|
||||
ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
assertNotNull(writableProjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
// retrieve a global provider
|
||||
ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID);
|
||||
assertNotNull(wspProvider);
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider);
|
||||
// clear it
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).clear();
|
||||
assertEquals(null, wspProvider.getSettingEntries(cfgDescription, project, null));
|
||||
// add the provider to cfgDescription
|
||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||
providers.add(wspProvider);
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
List<ILanguageSettingsProvider> storedProviders = cfgDescription.getLanguageSettingProviders();
|
||||
assertEquals(1, storedProviders.size());
|
||||
|
||||
// write to project description
|
||||
CoreModel.getDefault().setProjectDescription(project, writableProjDescription);
|
||||
}
|
||||
|
||||
// Change the provider's entries
|
||||
{
|
||||
// retrieve a global provider
|
||||
ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID);
|
||||
assertNotNull(wspProvider);
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider);
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).clear();
|
||||
// add entries
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(SAMPLE_LSE);
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).setSettingEntries(null, project, null, entries);
|
||||
assertEquals(SAMPLE_LSE, wspProvider.getSettingEntries(null, project, null).get(0));
|
||||
|
||||
// reset count
|
||||
mockLseListener.resetCount();
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Serialize settings
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace();
|
||||
|
||||
// get cfgDescriptionId
|
||||
ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, false);
|
||||
assertNotNull(prjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescription.getId();
|
||||
|
||||
// inspect event
|
||||
assertEquals(1, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNotNull(event);
|
||||
|
||||
assertEquals(project.getName(), event.getProjectName());
|
||||
assertEquals(1, event.getConfigurationDescriptionIds().length);
|
||||
assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]);
|
||||
assertEquals(1, event.getResources(cfgDescriptionId).length);
|
||||
assertEquals(project, event.getResources(cfgDescriptionId)[0]);
|
||||
// TODO - drill to the entries
|
||||
}
|
||||
// Change the provider's entries back (bug was found for this case)
|
||||
{
|
||||
// retrieve a global provider
|
||||
ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID);
|
||||
assertNotNull(wspProvider);
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
assertTrue(rawProvider instanceof MockLanguageSettingsEditableProvider);
|
||||
// clear the provider again
|
||||
((MockLanguageSettingsEditableProvider) rawProvider).clear();
|
||||
|
||||
// reset count
|
||||
mockLseListener.resetCount();
|
||||
assertEquals(0, mockLseListener.getCount());
|
||||
assertEquals(null, mockLseListener.getLastEvent());
|
||||
|
||||
// Serialize settings
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace();
|
||||
|
||||
// get cfgDescriptionId
|
||||
ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project, false);
|
||||
assertNotNull(prjDescription);
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
|
||||
assertEquals(1, cfgDescriptions.length);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
String cfgDescriptionId = cfgDescription.getId();
|
||||
|
||||
// inspect event
|
||||
assertEquals(1, mockLseListener.getCount());
|
||||
ILanguageSettingsChangeEvent event = mockLseListener.getLastEvent();
|
||||
assertNotNull(event);
|
||||
|
||||
assertEquals(project.getName(), event.getProjectName());
|
||||
assertEquals(1, event.getConfigurationDescriptionIds().length);
|
||||
assertEquals(cfgDescriptionId, event.getConfigurationDescriptionIds()[0]);
|
||||
assertEquals(1, event.getResources(cfgDescriptionId).length);
|
||||
assertEquals(project, event.getResources(cfgDescriptionId)[0]);
|
||||
// TODO - drill to the entries
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
|||
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.language.settings.providers.LanguageSettingsExtensionManager;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
import org.eclipse.cdt.internal.core.settings.model.CConfigurationDescription;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
|
@ -561,7 +561,7 @@ public class LanguageSettingsManagerTests extends TestCase {
|
|||
|
||||
{
|
||||
// retrieve local entries
|
||||
List<ICLanguageSettingEntry> includes = LanguageSettingsExtensionManager
|
||||
List<ICLanguageSettingEntry> includes = LanguageSettingsProvidersSerializer
|
||||
.getLocalSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH);
|
||||
assertEquals(localIncludeEntry, includes.get(0));
|
||||
assertEquals(1, includes.size());
|
||||
|
@ -569,7 +569,7 @@ public class LanguageSettingsManagerTests extends TestCase {
|
|||
|
||||
{
|
||||
// retrieve system entries
|
||||
List<ICLanguageSettingEntry> includes = LanguageSettingsExtensionManager
|
||||
List<ICLanguageSettingEntry> includes = LanguageSettingsProvidersSerializer
|
||||
.getSystemSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH);
|
||||
assertEquals(systemIncludeEntry, includes.get(0));
|
||||
assertEquals(1, includes.size());
|
||||
|
@ -577,7 +577,7 @@ public class LanguageSettingsManagerTests extends TestCase {
|
|||
|
||||
{
|
||||
// retrieve both local and system
|
||||
List<ICLanguageSettingEntry> includes = LanguageSettingsExtensionManager
|
||||
List<ICLanguageSettingEntry> includes = LanguageSettingsProvidersSerializer
|
||||
.getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, ICSettingEntry.INCLUDE_PATH);
|
||||
assertEquals(entries.get(0), includes.get(0));
|
||||
assertEquals(entries.get(1), includes.get(1));
|
||||
|
@ -799,7 +799,7 @@ public class LanguageSettingsManagerTests extends TestCase {
|
|||
LanguageSettingsSerializable provider = new LanguageSettingsSerializable(PROVIDER_1, PROVIDER_NAME_1);
|
||||
provider.setSettingEntries(null, file, null, entries);
|
||||
// build the hierarchy
|
||||
LanguageSettingsExtensionManager.buildResourceTree(provider, null, null, project);
|
||||
LanguageSettingsProvidersSerializer.buildResourceTree(provider, null, null, project);
|
||||
|
||||
// check that entries go to highest possible level
|
||||
assertEquals(entries, LanguageSettingsManager.getSettingEntriesUpResourceTree(provider, null, file, null));
|
||||
|
|
|
@ -19,6 +19,10 @@ public class MockLanguageSettingsEditableProvider extends LanguageSettingsSerial
|
|||
super();
|
||||
}
|
||||
|
||||
public MockLanguageSettingsEditableProvider(String id, String name) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
public MockLanguageSettingsEditableProvider cloneShallow() throws CloneNotSupportedException {
|
||||
return (MockLanguageSettingsEditableProvider) super.cloneShallow();
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class LanguageSettingsManager {
|
|||
* although individual providers return {@code null} if no settings defined.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSettingEntriesUpResourceTree(ILanguageSettingsProvider provider, ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
return LanguageSettingsExtensionManager.getSettingEntriesUpResourceTree(provider, cfgDescription, rc, languageId);
|
||||
return LanguageSettingsProvidersSerializer.getSettingEntriesUpResourceTree(provider, cfgDescription, rc, languageId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +71,7 @@ public class LanguageSettingsManager {
|
|||
* @param project - the project which is considered the root of the resource tree.
|
||||
*/
|
||||
public static void buildResourceTree(LanguageSettingsSerializable provider, ICConfigurationDescription cfgDescription, String languageId, IProject project) {
|
||||
LanguageSettingsExtensionManager.buildResourceTree(provider, cfgDescription, languageId, project);
|
||||
LanguageSettingsProvidersSerializer.buildResourceTree(provider, cfgDescription, languageId, project);
|
||||
}
|
||||
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class LanguageSettingsManager {
|
|||
*/
|
||||
// FIXME: get rid of callers PathEntryTranslator and DescriptionScannerInfoProvider
|
||||
public static List<ICLanguageSettingEntry> getSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return LanguageSettingsExtensionManager.getSettingEntriesByKind(cfgDescription, rc, languageId, kind);
|
||||
return LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, languageId, kind);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSetting
|
|||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* This temporary class keeps the utility methods being looking for better home
|
||||
|
@ -53,11 +52,6 @@ public class LanguageSettingsManager_TBD {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Deprecated // Shouldn't be API
|
||||
public static void serializeWorkspaceProviders() throws CoreException {
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace();
|
||||
}
|
||||
|
||||
public static boolean isReconfigured(ILanguageSettingsProvider provider) {
|
||||
if (provider instanceof ILanguageSettingsEditableProvider) {
|
||||
try {
|
||||
|
|
|
@ -12,13 +12,9 @@
|
|||
package org.eclipse.cdt.core.language.settings.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
|
@ -26,7 +22,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
|||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||
import org.eclipse.cdt.core.settings.model.util.LanguageSettingEntriesSerializer;
|
||||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.internal.core.parser.util.WeakHashSet;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsStorage;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -45,45 +41,17 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
private static final String ATTR_ID = "id"; //$NON-NLS-1$
|
||||
|
||||
private static final String ELEM_LANGUAGE_SCOPE = "language-scope"; //$NON-NLS-1$
|
||||
private static final String ELEM_LANGUAGE = "language"; //$NON-NLS-1$
|
||||
private static final String ELEM_RESOURCE = "resource"; //$NON-NLS-1$
|
||||
private static final String ATTR_PROJECT_PATH = "project-relative-path"; //$NON-NLS-1$
|
||||
|
||||
private static final String ELEM_ENTRY = "entry"; //$NON-NLS-1$
|
||||
private static final String ATTR_KIND = "kind"; //$NON-NLS-1$
|
||||
private static final String ATTR_NAME = "name"; //$NON-NLS-1$
|
||||
private static final String ATTR_VALUE = "value"; //$NON-NLS-1$
|
||||
private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
|
||||
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
|
||||
private static final String ELEM_FLAG = "flag"; //$NON-NLS-1$
|
||||
|
||||
private static final String ATTR_STORE_ENTRIES = "store-entries"; //$NON-NLS-1$
|
||||
private static final String VALUE_WORKSPACE = "workspace"; //$NON-NLS-1$
|
||||
private static final String VALUE_PROJECT = "project"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** 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>>>();
|
||||
private LanguageSettingsStorage fStorage = new LanguageSettingsStorage();
|
||||
|
||||
/**
|
||||
* Default constructor. This constructor has to be always followed with setting id and name of the provider.
|
||||
|
@ -185,57 +153,6 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
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);
|
||||
if (langMap==null) {
|
||||
langMap = new HashMap<String, List<ICLanguageSettingEntry>>();
|
||||
fStorage.put(languageId, langMap);
|
||||
}
|
||||
List<ICLanguageSettingEntry> sortedEntries = listPool.add(Collections.unmodifiableList(sortEntries(entries)));
|
||||
langMap.put(rcProjectPath, sortedEntries);
|
||||
} else {
|
||||
// do not keep nulls in the tables
|
||||
Map<String, List<ICLanguageSettingEntry>> langMap = fStorage.get(languageId);
|
||||
if (langMap!=null) {
|
||||
langMap.remove(rcProjectPath);
|
||||
if (langMap.size()==0) {
|
||||
fStorage.remove(languageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>(){
|
||||
/**
|
||||
* This comparator sorts by kinds first and the macros are sorted additionally by name.
|
||||
*/
|
||||
public int compare(ICLanguageSettingEntry entry0, ICLanguageSettingEntry entry1) {
|
||||
int kind0 = entry0.getKind();
|
||||
int kind1 = entry1.getKind();
|
||||
if (kind0==ICSettingEntry.MACRO && kind1==ICSettingEntry.MACRO) {
|
||||
return entry0.getName().compareTo(entry1.getName());
|
||||
}
|
||||
|
||||
return kind0 - kind1;
|
||||
}});
|
||||
|
||||
return sortedEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets language settings entries for the provider.
|
||||
* Note that the entries are not persisted at that point. To persist use TODO
|
||||
|
@ -248,7 +165,12 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
*/
|
||||
public void setSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId, List<ICLanguageSettingEntry> entries) {
|
||||
String rcProjectPath = rc!=null ? rc.getProjectRelativePath().toString() : null;
|
||||
setSettingEntriesInternal(rcProjectPath, languageId, entries);
|
||||
fStorage.setSettingEntries(rcProjectPath, languageId, entries);
|
||||
|
||||
// // TODO - not sure what is more efficient, to do that or not to do that?
|
||||
// if (fStorage.equals(lastPersistedState)) {
|
||||
// lastPersistedState = null;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,28 +178,27 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
* <br> Note that this list is <b>unmodifiable</b>. To modify the list copy it, change and use
|
||||
* {@link #setSettingEntries(ICConfigurationDescription, IResource, String, List)}.
|
||||
*
|
||||
* <br/> Note also that <b>you can compare these lists with simple equality operator ==</b>,
|
||||
* as lists themselves are backed by WeakHashSet<List<ICLanguageSettingEntry>> where
|
||||
* identical copies (deep comparison is used) are replaced with the same one instance.
|
||||
*/
|
||||
@Override
|
||||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
Map<String, List<ICLanguageSettingEntry>> langMap = fStorage.get(languageId);
|
||||
if (langMap!=null) {
|
||||
String rcProjectPath = rc!=null ? rc.getProjectRelativePath().toString() : null;
|
||||
List<ICLanguageSettingEntry> entries = langMap.get(rcProjectPath);
|
||||
if (entries!=null)
|
||||
return entries;
|
||||
}
|
||||
|
||||
List<ICLanguageSettingEntry> entries = fStorage.getSettingEntries(cfgDescription, rc, languageId);
|
||||
if (entries == null) {
|
||||
if (languageId!=null && (languageScope==null || languageScope.contains(languageId))) {
|
||||
List<ICLanguageSettingEntry> entries = getSettingEntries(cfgDescription, rc, null);
|
||||
return entries;
|
||||
entries = getSettingEntries(cfgDescription, rc, null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider under parent XML element.
|
||||
* This is convenience method not intended to be overridden on purpose.
|
||||
* Override {@link #serializeAttributes(Element)} or
|
||||
* {@link #serializeEntries(Element)} instead.
|
||||
*
|
||||
* @param parentElement - element where to serialize.
|
||||
* @return - newly created <provider> element. That element will already be
|
||||
|
@ -329,98 +250,18 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
* @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);
|
||||
fStorage.serializeEntries(elementProvider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
Element elementLanguage = XmlUtil.appendElement(parentElement, ELEM_LANGUAGE, new String[] {ATTR_ID, langId});
|
||||
parentElement = elementLanguage;
|
||||
}
|
||||
for (Entry<String, List<ICLanguageSettingEntry>> entryRc : entryLang.getValue().entrySet()) {
|
||||
serializeResource(parentElement, entryRc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
Element elementRc = XmlUtil.appendElement(parentElement, ELEM_RESOURCE, new String[] {ATTR_PROJECT_PATH, rcProjectPath});
|
||||
parentElement = elementRc;
|
||||
}
|
||||
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[] {
|
||||
ATTR_KIND, LanguageSettingEntriesSerializer.kindToString(entry.getKind()),
|
||||
ATTR_NAME, entry.getName(),
|
||||
});
|
||||
switch(entry.getKind()) {
|
||||
case ICSettingEntry.MACRO:
|
||||
elementSettingEntry.setAttribute(ATTR_VALUE, entry.getValue());
|
||||
break;
|
||||
// case ICLanguageSettingEntry.LIBRARY_FILE:
|
||||
// // TODO: sourceAttachment fields may need to be covered
|
||||
// break;
|
||||
}
|
||||
int flags = entry.getFlags();
|
||||
if (flags!=0) {
|
||||
// Element elementFlag =
|
||||
XmlUtil.appendElement(elementSettingEntry, ELEM_FLAG, new String[] {
|
||||
ATTR_VALUE, LanguageSettingEntriesSerializer.composeFlagsString(entry.getFlags())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
NodeList flagNodes = parentElement.getChildNodes();
|
||||
int flags = 0;
|
||||
for (int i=0;i<flagNodes.getLength();i++) {
|
||||
Node flagNode = flagNodes.item(i);
|
||||
if(flagNode.getNodeType() != Node.ELEMENT_NODE || !ELEM_FLAG.equals(flagNode.getNodeName()))
|
||||
continue;
|
||||
|
||||
String settingFlags = XmlUtil.determineAttributeValue(flagNode, ATTR_VALUE);
|
||||
int bitFlag = LanguageSettingEntriesSerializer.composeFlags(settingFlags);
|
||||
flags |= bitFlag;
|
||||
|
||||
}
|
||||
|
||||
String settingValue = null;
|
||||
int kind = LanguageSettingEntriesSerializer.stringToKind(settingKind);
|
||||
if (kind == ICSettingEntry.MACRO)
|
||||
settingValue = XmlUtil.determineAttributeValue(parentElement, ATTR_VALUE);
|
||||
ICLanguageSettingEntry entry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, settingName, settingValue, null, flags);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load provider from XML provider element.
|
||||
* This is convenience method not intended to be overridden on purpose.
|
||||
* Override {@link #loadAttributes(Element)} or
|
||||
* {@link #loadEntries(Element)} instead.
|
||||
*
|
||||
* @param providerNode - XML element <provider> to load provider from.
|
||||
*/
|
||||
public void load(Element providerNode) {
|
||||
final public void load(Element providerNode) {
|
||||
fStorage.clear();
|
||||
languageScope = null;
|
||||
|
||||
|
@ -431,6 +272,18 @@ 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>();
|
||||
}
|
||||
String id = XmlUtil.determineAttributeValue(parentNode, ATTR_ID);
|
||||
languageScope.add(id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load attributes from XML provider element.
|
||||
* @param providerNode - XML element <provider> to load attributes from.
|
||||
|
@ -464,123 +317,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
* @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);
|
||||
} else if (ELEM_ENTRY.equals(elementNode.getNodeName())) {
|
||||
ICLanguageSettingEntry entry = loadSettingEntry(elementNode);
|
||||
if (entry!=null) {
|
||||
settings.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set settings
|
||||
if (settings.size()>0) {
|
||||
setSettingEntriesInternal(null, null, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine and set language scope from given XML node.
|
||||
*/
|
||||
private void loadLanguageScopeElement(Node parentNode) {
|
||||
if (languageScope==null) {
|
||||
languageScope = new ArrayList<String>();
|
||||
}
|
||||
String id = XmlUtil.determineAttributeValue(parentNode, ATTR_ID);
|
||||
languageScope.add(id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load entries defined in language element.
|
||||
*/
|
||||
private void loadLanguageElement(Node parentNode, String cfgId) {
|
||||
String langId = XmlUtil.determineAttributeValue(parentNode, ATTR_ID);
|
||||
if (langId.length()==0) {
|
||||
langId=null;
|
||||
}
|
||||
|
||||
List<ICLanguageSettingEntry> settings = new ArrayList<ICLanguageSettingEntry>();
|
||||
NodeList nodes = parentNode.getChildNodes();
|
||||
for (int i=0;i<nodes.getLength();i++) {
|
||||
Node elementNode = nodes.item(i);
|
||||
if(elementNode.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (ELEM_RESOURCE.equals(elementNode.getNodeName())) {
|
||||
loadResourceElement(elementNode, cfgId, langId);
|
||||
} else if (ELEM_ENTRY.equals(elementNode.getNodeName())) {
|
||||
ICLanguageSettingEntry entry = loadSettingEntry(elementNode);
|
||||
if (entry!=null) {
|
||||
settings.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set settings
|
||||
if (settings.size()>0) {
|
||||
setSettingEntriesInternal(null, langId, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load entries defined in resource element.
|
||||
*/
|
||||
private void loadResourceElement(Node parentNode, String cfgId, String langId) {
|
||||
String rcProjectPath = XmlUtil.determineAttributeValue(parentNode, ATTR_PROJECT_PATH);
|
||||
|
||||
List<ICLanguageSettingEntry> settings = new ArrayList<ICLanguageSettingEntry>();
|
||||
NodeList nodes = parentNode.getChildNodes();
|
||||
for (int i=0;i<nodes.getLength();i++) {
|
||||
Node elementNode = nodes.item(i);
|
||||
if(elementNode.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (ELEM_ENTRY.equals(elementNode.getNodeName())) {
|
||||
ICLanguageSettingEntry entry = loadSettingEntry(elementNode);
|
||||
if (entry!=null) {
|
||||
settings.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set settings
|
||||
if (settings.size()>0) {
|
||||
setSettingEntriesInternal(rcProjectPath, langId, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
List<ICLanguageSettingEntry>>> storageClone = 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();
|
||||
Map<String, List<ICLanguageSettingEntry>> mapRc = entryLang.getValue();
|
||||
Map<String, List<ICLanguageSettingEntry>> mapRcClone = new HashMap<String, List<ICLanguageSettingEntry>>();
|
||||
Set<Entry<String, List<ICLanguageSettingEntry>>> entrySetRc = mapRc.entrySet();
|
||||
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 LSE pool
|
||||
mapRcClone.put(rcProjectPath, lsEntries);
|
||||
}
|
||||
storageClone.put(langId, mapRcClone);
|
||||
}
|
||||
return storageClone;
|
||||
fStorage.loadEntries(providerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -592,7 +329,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
if (languageScope!=null)
|
||||
clone.languageScope = new ArrayList<String>(languageScope);
|
||||
|
||||
clone.fStorage = new HashMap<String, Map<String, List<ICLanguageSettingEntry>>>();
|
||||
clone.fStorage = new LanguageSettingsStorage();
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
@ -610,7 +347,7 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
@Override
|
||||
protected LanguageSettingsSerializable clone() throws CloneNotSupportedException {
|
||||
LanguageSettingsSerializable clone = cloneShallowInternal();
|
||||
clone.fStorage = cloneStorage();
|
||||
clone.fStorage = fStorage.cloneStorage();
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
@ -680,4 +417,11 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider {
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
public LanguageSettingsStorage getStorageInternal() {
|
||||
return fStorage;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ package org.eclipse.cdt.core.language.settings.providers;
|
|||
|
||||
// TODO: move ILanguageSettingsEditableProvider here
|
||||
|
||||
public class LanguageSettingsSerializableEditable extends LanguageSettingsSerializable implements ILanguageSettingsEditableProvider {
|
||||
// TODO this one is unused - remove
|
||||
final public class LanguageSettingsSerializableEditable extends LanguageSettingsSerializable implements ILanguageSettingsEditableProvider {
|
||||
@Override
|
||||
public LanguageSettingsSerializableEditable clone() throws CloneNotSupportedException {
|
||||
return (LanguageSettingsSerializableEditable) super.clone();
|
||||
|
|
|
@ -395,6 +395,8 @@ public interface ICConfigurationDescription extends ICSettingContainer, ICSettin
|
|||
* or preprocessor macros.
|
||||
*
|
||||
* @param providers the list of providers to assign to the configuration description.
|
||||
* Warning: the providers will be cloned before actual addition to the project model
|
||||
* due to TODO - very important reason but I forgot why by now.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2011 Andrew Gvozdev and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Gvozdev - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.language.settings.providers;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
||||
/**
|
||||
* Contains the details of changes that occurred as a result of modifying
|
||||
* language settings entries {@link ICLanguageSettingEntry}.
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ILanguageSettingsChangeEvent {
|
||||
public String getProjectName();
|
||||
|
||||
public String[] getConfigurationDescriptionIds();
|
||||
|
||||
public IResource[] getResources(String cfgDescriptionId);
|
||||
|
||||
// // AG - YAGNI
|
||||
// public List<ICLanguageSettingEntry> getSettingEntriesOld(ICConfigurationDescription cfgDescription, IResource rc, String languageId);
|
||||
// public List<ICLanguageSettingEntry> getSettingEntriesNew(ICConfigurationDescription cfgDescription, IResource rc, String languageId);
|
||||
// // AG - or maybe
|
||||
// ILanguageSettingsDelta getDelta(ICConfigurationDescription cfgDescription);
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2011 Andrew Gvozdev and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Gvozdev - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.language.settings.providers;
|
||||
|
||||
/**
|
||||
* Listens to changes in language settings.
|
||||
*/
|
||||
public interface ILanguageSettingsChangeListener {
|
||||
/**
|
||||
* Indicates that language settings have been changed.
|
||||
* @param event
|
||||
*/
|
||||
public void handleEvent(ILanguageSettingsChangeEvent event);
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2011 Andrew Gvozdev and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Gvozdev - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.language.settings.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
|
||||
|
||||
// TODO possibly make an interface from that
|
||||
public class LanguageSettingsDelta {
|
||||
// maps need to be ordered by providers
|
||||
private LinkedHashMap<String, // providerId
|
||||
LanguageSettingsStorage> oldLanguageSettingsState;
|
||||
private LinkedHashMap<String, // providerId
|
||||
LanguageSettingsStorage> newLanguageSettingsState;
|
||||
|
||||
public LanguageSettingsDelta(LinkedHashMap<String, LanguageSettingsStorage> oldState, LinkedHashMap<String, LanguageSettingsStorage> newState) {
|
||||
oldLanguageSettingsState = oldState;
|
||||
newLanguageSettingsState = newState;
|
||||
}
|
||||
|
||||
// FIXME - this API is no good
|
||||
public Set<IResource> getChangedResources(IProject project, ICConfigurationDescription cfgDescription) {
|
||||
Set<IResource> resources = new HashSet<IResource>();
|
||||
|
||||
// Ordered collections
|
||||
Collection<LanguageSettingsStorage> oldStateStorages = oldLanguageSettingsState.values();
|
||||
Collection<LanguageSettingsStorage> newStateStorages = newLanguageSettingsState.values();
|
||||
|
||||
for (LanguageSettingsStorage lss : oldStateStorages) {
|
||||
// Map<String, // languageId
|
||||
// Map<String, // resource project path
|
||||
// List<ICLanguageSettingEntry>>>
|
||||
Map<String, Map<String, List<ICLanguageSettingEntry>>> mapInternal = lss.getMapInternal();
|
||||
synchronized (mapInternal) {
|
||||
for (Entry<String, Map<String, List<ICLanguageSettingEntry>>> entryLang : mapInternal.entrySet()) {
|
||||
String langId = entryLang.getKey();
|
||||
for (Entry<String, List<ICLanguageSettingEntry>> entryRc : entryLang.getValue().entrySet()) {
|
||||
String rcName = entryRc.getKey();
|
||||
IResource rc = (rcName != null) ? project.findMember(rcName) : project;
|
||||
if (resources.contains(rc))
|
||||
continue;
|
||||
|
||||
List<ICLanguageSettingEntry> lsEntriesOld = entryRc.getValue();
|
||||
List<ICLanguageSettingEntry> lsEntriesNew = getSettingEntries(newStateStorages, cfgDescription, rc, langId);
|
||||
|
||||
if (!lsEntriesNew.equals(lsEntriesOld) && !(lsEntriesOld==null && lsEntriesNew.size()==0)) {
|
||||
resources.add(rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (LanguageSettingsStorage lss : newStateStorages) {
|
||||
// Map<String, // languageId
|
||||
// Map<String, // resource project path
|
||||
// List<ICLanguageSettingEntry>>>
|
||||
Map<String, Map<String, List<ICLanguageSettingEntry>>> mapInternal = lss.getMapInternal();
|
||||
synchronized (mapInternal) {
|
||||
for (Entry<String, Map<String, List<ICLanguageSettingEntry>>> entryLang : mapInternal.entrySet()) {
|
||||
String langId = entryLang.getKey();
|
||||
for (Entry<String, List<ICLanguageSettingEntry>> entryRc : entryLang.getValue().entrySet()) {
|
||||
String rcName = entryRc.getKey();
|
||||
IResource rc = (rcName != null) ? project.findMember(rcName) : project;
|
||||
if (resources.contains(rc))
|
||||
continue;
|
||||
|
||||
List<ICLanguageSettingEntry> lsEntriesNew = entryRc.getValue();
|
||||
List<ICLanguageSettingEntry> lsEntriesOld = getSettingEntries(oldStateStorages, cfgDescription, rc, langId);
|
||||
|
||||
if (!lsEntriesOld.equals(lsEntriesNew) && !(lsEntriesNew==null && lsEntriesOld.size()==0)) {
|
||||
resources.add(rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
private static boolean checkBit(int flags, int bit) {
|
||||
return (flags & bit) == bit;
|
||||
}
|
||||
|
||||
private static List<ICLanguageSettingEntry> getSettingEntries(Collection<LanguageSettingsStorage> stores, ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
List<String> alreadyAdded = new ArrayList<String>();
|
||||
|
||||
for (LanguageSettingsStorage store: stores) {
|
||||
List<ICLanguageSettingEntry> providerEntries = getSettingEntriesUpResourceTree(store, cfgDescription, rc, languageId);
|
||||
for (ICLanguageSettingEntry entry : providerEntries) {
|
||||
if (entry!=null) {
|
||||
String entryName = entry.getName();
|
||||
// Only first entry is considered
|
||||
// Entry flagged as "UNDEFINED" prevents adding entry with the same name down the line
|
||||
if (!alreadyAdded.contains(entryName)) {
|
||||
int flags = entry.getFlags();
|
||||
if (!checkBit(flags, ICSettingEntry.UNDEFINED)) {
|
||||
entries.add(entry);
|
||||
}
|
||||
alreadyAdded.add(entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static List<ICLanguageSettingEntry> getSettingEntriesUpResourceTree(LanguageSettingsStorage store, ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
Assert.isTrue( !(rc instanceof IWorkspaceRoot) );
|
||||
if (store!=null) {
|
||||
List<ICLanguageSettingEntry> entries = store.getSettingEntries(cfgDescription, rc, languageId);
|
||||
if (entries!=null) {
|
||||
return new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
}
|
||||
if (rc!=null) {
|
||||
IResource parentFolder = (rc instanceof IProject) ? null : rc.getParent();
|
||||
if (parentFolder!=null) {
|
||||
return getSettingEntriesUpResourceTree(store, cfgDescription, parentFolder, languageId);
|
||||
}
|
||||
// if out of parent resources - get default entries for the applicable language scope
|
||||
entries = store.getSettingEntries(null, null, languageId);
|
||||
if (entries!=null) {
|
||||
return new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<ICLanguageSettingEntry>(0);
|
||||
}
|
||||
}
|
|
@ -13,10 +13,8 @@ package org.eclipse.cdt.internal.core.language.settings.providers;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
@ -26,19 +24,9 @@ import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditabl
|
|||
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.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.ICSettingEntry;
|
||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||
import org.eclipse.cdt.core.settings.model.util.LanguageSettingEntriesSerializer;
|
||||
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.IWorkspaceRoot;
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
|
@ -340,267 +328,6 @@ public class LanguageSettingsExtensionManager {
|
|||
return list;
|
||||
}
|
||||
|
||||
private static List<ICLanguageSettingEntry> safeGetSettingEntries(ILanguageSettingsProvider provider,
|
||||
ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
|
||||
try {
|
||||
return provider.getSettingEntries(cfgDescription, rc, languageId);
|
||||
} catch (Throwable e) {
|
||||
String cfgId = cfgDescription!=null ? cfgDescription.getId() : null;
|
||||
String msg = "Exception in provider "+provider.getId()+": getSettingEntries("+cfgId+", "+rc+", "+languageId+")";
|
||||
CCorePlugin.log(msg, e);
|
||||
// return empty array to prevent climbing up the resource tree
|
||||
return new ArrayList<ICLanguageSettingEntry>(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of setting entries of the given provider
|
||||
* for the given configuration description, resource and language.
|
||||
* This method reaches to the parent folder of the resource recursively
|
||||
* in case the resource does not define the entries for the given provider.
|
||||
*
|
||||
* @param provider - language settings provider.
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
*
|
||||
* @return the list of setting entries. Never returns {@code null}
|
||||
* although individual providers mandated to return {@code null} if no settings defined.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSettingEntriesUpResourceTree(ILanguageSettingsProvider provider, ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
Assert.isTrue( !(rc instanceof IWorkspaceRoot) );
|
||||
if (provider!=null) {
|
||||
List<ICLanguageSettingEntry> entries = safeGetSettingEntries(provider, cfgDescription, rc, languageId);
|
||||
if (entries!=null) {
|
||||
return new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
}
|
||||
if (rc!=null) {
|
||||
IResource parentFolder = (rc instanceof IProject) ? null : rc.getParent();
|
||||
if (parentFolder!=null) {
|
||||
return getSettingEntriesUpResourceTree(provider, cfgDescription, parentFolder, languageId);
|
||||
}
|
||||
// if out of parent resources - get default entries for the applicable language scope
|
||||
entries = safeGetSettingEntries(provider, null, null, languageId);
|
||||
if (entries!=null) {
|
||||
return new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<ICLanguageSettingEntry>(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds for the provider a nice looking resource tree to present hierarchical view to the user.
|
||||
* Note that it is not advisable to "compact" the tree because of potential loss of information
|
||||
* which is especially important during partial or incremental builds.
|
||||
*
|
||||
* @param provider - language settings provider to build the tree for.
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param languageId - language ID.
|
||||
* @param folder - container where the tree roots.
|
||||
*/
|
||||
public static void buildResourceTree(LanguageSettingsSerializable provider, ICConfigurationDescription cfgDescription, String languageId, IContainer folder) {
|
||||
IResource[] members = null;
|
||||
try {
|
||||
members = folder.members();
|
||||
} catch (Exception e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
if (members==null)
|
||||
return;
|
||||
|
||||
for (IResource rc : members) {
|
||||
if (rc instanceof IContainer) {
|
||||
buildResourceTree(provider, cfgDescription, languageId, (IContainer) rc);
|
||||
}
|
||||
}
|
||||
|
||||
int rcNumber = members.length;
|
||||
|
||||
Map<List<ICLanguageSettingEntry>, Integer> listMap = new HashMap<List<ICLanguageSettingEntry>, Integer>();
|
||||
|
||||
// on the first pass find majority entries
|
||||
List<ICLanguageSettingEntry> majorityEntries = null;
|
||||
List<ICLanguageSettingEntry> candidate = null;
|
||||
int candidateCount = 0;
|
||||
for (IResource rc : members) {
|
||||
if (!isLanguageInScope(rc, cfgDescription, languageId)) {
|
||||
rcNumber--;
|
||||
} else {
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, rc, languageId);
|
||||
if (entries==null && rc instanceof IContainer) {
|
||||
rcNumber--;
|
||||
} else {
|
||||
Integer count = listMap.get(entries);
|
||||
if (count==null) {
|
||||
count = 0;
|
||||
}
|
||||
count++;
|
||||
|
||||
if (count>candidateCount) {
|
||||
candidateCount = count;
|
||||
candidate = entries;
|
||||
}
|
||||
|
||||
listMap.put(entries, count);
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateCount > rcNumber/2) {
|
||||
majorityEntries = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (majorityEntries!=null) {
|
||||
provider.setSettingEntries(cfgDescription, folder, languageId, majorityEntries);
|
||||
}
|
||||
|
||||
// second pass - assign the entries to the folders
|
||||
for (IResource rc : members) {
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, rc, languageId);
|
||||
if (entries!=null && entries==majorityEntries) {
|
||||
if (!(rc instanceof IFile)) { // preserve information which files were collected
|
||||
provider.setSettingEntries(cfgDescription, rc, languageId, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLanguageInScope(IResource rc, ICConfigurationDescription cfgDescription, String languageId) {
|
||||
if (rc instanceof IFile) {
|
||||
ILanguage lang = null;
|
||||
try {
|
||||
lang = LanguageManager.getInstance().getLanguageForFile((IFile) rc, cfgDescription);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log("Error loading language settings providers extensions", e); //$NON-NLS-1$
|
||||
}
|
||||
if (lang==null || (languageId!=null && !languageId.equals(lang.getId()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean checkBit(int flags, int bit) {
|
||||
return (flags & bit) == bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of setting entries of a certain kind (such as include paths)
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
* @param checkLocality - specifies if parameter {@code isLocal} should be considered.
|
||||
* @param isLocal - {@code true} if "local" entries should be provided and
|
||||
* {@code false} for "system" entries. This makes sense for include paths where
|
||||
* [#include "..."] is "local" and [#include <...>] is system.
|
||||
*
|
||||
* @return the list of setting entries found.
|
||||
*/
|
||||
private static List<ICLanguageSettingEntry> getSettingEntriesByKind(ICConfigurationDescription cfgDescription,
|
||||
IResource rc, String languageId, int kind, boolean checkLocality, boolean isLocal) {
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
List<String> alreadyAdded = new ArrayList<String>();
|
||||
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
for (ILanguageSettingsProvider provider: providers) {
|
||||
List<ICLanguageSettingEntry> providerEntries = getSettingEntriesUpResourceTree(provider, cfgDescription, rc, languageId);
|
||||
for (ICLanguageSettingEntry entry : providerEntries) {
|
||||
if (entry!=null) {
|
||||
String entryName = entry.getName();
|
||||
boolean isRightKind = (entry.getKind() & kind) != 0;
|
||||
// Only first entry is considered
|
||||
// Entry flagged as "UNDEFINED" prevents adding entry with the same name down the line
|
||||
if (isRightKind && !alreadyAdded.contains(entryName)) {
|
||||
int flags = entry.getFlags();
|
||||
boolean isRightLocal = !checkLocality || (checkBit(flags, ICSettingEntry.LOCAL) == isLocal);
|
||||
if (isRightLocal) {
|
||||
if (!checkBit(flags, ICSettingEntry.UNDEFINED)) {
|
||||
entries.add(entry);
|
||||
}
|
||||
alreadyAdded.add(entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of setting entries of a certain kind (such as include paths)
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined. For include paths both
|
||||
* local (#include "...") and system (#include <...>) entries are returned.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
*
|
||||
* @return the list of setting entries.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return getSettingEntriesByKind(cfgDescription, rc, languageId, kind, /* checkLocality */ false, /* isLocal */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of "system" (such as [#include <...>]) setting entries of a certain kind
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
*
|
||||
* @return the list of setting entries.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSystemSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return getSettingEntriesByKind(cfgDescription, rc, languageId, kind, /* checkLocality */ true, /* isLocal */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of "local" (such as [#include "..."]) setting entries of a certain kind
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
*
|
||||
* @return the list of setting entries.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getLocalSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return getSettingEntriesByKind(cfgDescription, rc, languageId, kind, /* checkLocality */ true, /* isLocal */ true);
|
||||
}
|
||||
|
||||
public static boolean equalsExtensionProviderShallow(ILanguageSettingsEditableProvider provider) throws CloneNotSupportedException {
|
||||
String id = provider.getId();
|
||||
ILanguageSettingsProvider extensionProviderShallow = getExtensionProviderShallow(id);
|
||||
|
|
|
@ -25,19 +25,29 @@ import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvide
|
|||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
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.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.internal.core.settings.model.CConfigurationSpecSettings;
|
||||
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
|
||||
import org.eclipse.cdt.internal.core.settings.model.IInternalCCfgInfo;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.ILock;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
|
@ -61,11 +71,15 @@ public class LanguageSettingsProvidersSerializer {
|
|||
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$
|
||||
|
||||
private static ILock serializingLock = Job.getJobManager().newLock();
|
||||
|
||||
/** Cache of globally available providers to be consumed by calling clients */
|
||||
private static Map<String, ILanguageSettingsProvider> rawGlobalWorkspaceProviders = new HashMap<String, ILanguageSettingsProvider>();
|
||||
private static Map<String, ILanguageSettingsProvider> globalWorkspaceProviders = new HashMap<String, ILanguageSettingsProvider>();
|
||||
|
||||
private static ListenerList fLanguageSettingsChangeListeners = new ListenerList(ListenerList.IDENTITY);
|
||||
|
||||
private static class ListenerAssociation {
|
||||
private ICListenerRegisterer listener;
|
||||
private ICConfigurationDescription cfgDescription;
|
||||
|
@ -161,6 +175,75 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
private static class LanguageSettingsChangeEvent implements ILanguageSettingsChangeEvent {
|
||||
private String projectName = null;
|
||||
private Map<String /*cfg*/, LanguageSettingsDelta> deltaMap = new HashMap<String, LanguageSettingsDelta>();
|
||||
|
||||
private IResource[] resources = null;
|
||||
|
||||
/**
|
||||
* The act of creating event resets internal delta count in configuration state.
|
||||
* That implies that when the event is retrieved it must be fired or delta will go missing.
|
||||
* That side effect is here to ensure atomic processing of firing & resetting the delta.
|
||||
*/
|
||||
public LanguageSettingsChangeEvent(ICProjectDescription prjDescription) {
|
||||
Assert.isTrue(prjDescription.isReadOnly());
|
||||
|
||||
projectName = prjDescription.getName();
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
|
||||
for (ICConfigurationDescription cfgDescription : cfgDescriptions) {
|
||||
if (cfgDescription instanceof IInternalCCfgInfo) {
|
||||
CConfigurationSpecSettings specSettings = null;
|
||||
try {
|
||||
specSettings = ((IInternalCCfgInfo) cfgDescription).getSpecSettings();
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
if (specSettings != null) {
|
||||
LanguageSettingsDelta delta = specSettings.dropDelta();
|
||||
if (delta != null)
|
||||
deltaMap.put(cfgDescription.getId(), delta);
|
||||
} else {
|
||||
IStatus ss = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Internal error: Missing specSettings for " + cfgDescription.getClass().getSimpleName());
|
||||
CCorePlugin.log(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, ss.getMessage(), new CoreException(ss)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
public String[] getConfigurationDescriptionIds() {
|
||||
String[] ids = deltaMap.keySet().toArray(new String[deltaMap.size()]);
|
||||
return ids;
|
||||
}
|
||||
|
||||
public IResource[] getResources(String cfgDescriptionId) {
|
||||
if (resources == null) {
|
||||
LanguageSettingsDelta delta = deltaMap.get(cfgDescriptionId);
|
||||
if (delta == null) {
|
||||
resources = new IResource[0];
|
||||
} else {
|
||||
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
|
||||
ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false);
|
||||
ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration();
|
||||
resources = delta.getChangedResources(project, cfgDescription).toArray(new IResource[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LanguageSettingsChangeEvent for project=[" + getProjectName() + "]"
|
||||
+ ", configurations=" + deltaMap.keySet()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/** static initializer */
|
||||
static {
|
||||
|
@ -261,24 +344,66 @@ public class LanguageSettingsProvidersSerializer {
|
|||
rawGlobalWorkspaceProviders = rawWorkspaceProviders;
|
||||
}
|
||||
|
||||
private static List<LanguageSettingsChangeEvent> createLanguageLettingsChangeEvents(List<LanguageSettingsSerializable> serializableProviders) {
|
||||
List<LanguageSettingsChangeEvent> events = new ArrayList<LanguageSettingsProvidersSerializer.LanguageSettingsChangeEvent>();
|
||||
|
||||
List<String> serializableIds = new ArrayList<String>();
|
||||
for (LanguageSettingsSerializable provider : serializableProviders) {
|
||||
serializableIds.add(provider.getId());
|
||||
}
|
||||
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IProject[] projects = root.getProjects();
|
||||
projects:
|
||||
for (IProject project : projects) {
|
||||
if (project.isAccessible()) {
|
||||
ICProjectDescription prjDescription = CCorePlugin.getDefault().getProjectDescription(project, false);
|
||||
if (prjDescription != null) {
|
||||
ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
|
||||
for (ICConfigurationDescription cfgDescription : cfgDescriptions) {
|
||||
for (ILanguageSettingsProvider provider : cfgDescription.getLanguageSettingProviders()) {
|
||||
if (isWorkspaceProvider(provider) && serializableIds.contains(provider.getId())) {
|
||||
LanguageSettingsChangeEvent event = new LanguageSettingsChangeEvent(prjDescription);
|
||||
if (event.getConfigurationDescriptionIds().length > 0) {
|
||||
events.add(event);
|
||||
}
|
||||
continue projects;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
public static void serializeLanguageSettingsWorkspace() throws CoreException {
|
||||
// AG TODO - remove the log
|
||||
CCorePlugin.log(new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, IStatus.OK,
|
||||
"LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace()", new Exception()));
|
||||
|
||||
URI uriStoreWsp = getStoreInWorkspaceArea(STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
List<LanguageSettingsSerializable> serializableExtensionProviders = new ArrayList<LanguageSettingsSerializable>();
|
||||
List<LanguageSettingsSerializable> serializableWorkspaceProviders = new ArrayList<LanguageSettingsSerializable>();
|
||||
for (ILanguageSettingsProvider provider : rawGlobalWorkspaceProviders.values()) {
|
||||
if (provider instanceof LanguageSettingsSerializable) {
|
||||
// serialize all editable providers which are different from corresponding extension
|
||||
// and serialize all serializable ones that are not editable (those are singletons and we don't know whether they changed)
|
||||
if (!(provider instanceof ILanguageSettingsEditableProvider) || !LanguageSettingsExtensionManager.equalsExtensionProvider(provider)) {
|
||||
serializableExtensionProviders.add((LanguageSettingsSerializable)provider);
|
||||
serializableWorkspaceProviders.add((LanguageSettingsSerializable)provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (serializableExtensionProviders.isEmpty()) {
|
||||
List<LanguageSettingsChangeEvent> events = null;
|
||||
if (serializableWorkspaceProviders.isEmpty()) {
|
||||
java.io.File fileStoreWsp = new java.io.File(uriStoreWsp);
|
||||
serializingLock.acquire();
|
||||
try {
|
||||
serializingLock.acquire();
|
||||
fileStoreWsp.delete();
|
||||
// manufacture events while inside the lock
|
||||
events = createLanguageLettingsChangeEvents(serializableWorkspaceProviders);
|
||||
} finally {
|
||||
serializingLock.release();
|
||||
}
|
||||
|
@ -287,17 +412,23 @@ public class LanguageSettingsProvidersSerializer {
|
|||
Element rootElement = XmlUtil.appendElement(doc, ELEM_PLUGIN);
|
||||
Element elementExtension = XmlUtil.appendElement(rootElement, ELEM_EXTENSION, new String[] {ATTR_POINT, LanguageSettingsExtensionManager.PROVIDER_EXTENSION_FULL_ID});
|
||||
|
||||
for (LanguageSettingsSerializable provider : serializableExtensionProviders) {
|
||||
for (LanguageSettingsSerializable provider : serializableWorkspaceProviders) {
|
||||
provider.serialize(elementExtension);
|
||||
}
|
||||
|
||||
serializingLock.acquire();
|
||||
try {
|
||||
serializingLock.acquire();
|
||||
XmlUtil.serializeXml(doc, uriStoreWsp);
|
||||
// manufacture events while inside the lock
|
||||
events = createLanguageLettingsChangeEvents(serializableWorkspaceProviders);
|
||||
} finally {
|
||||
serializingLock.release();
|
||||
}
|
||||
}
|
||||
// notify the listeners outside the lock
|
||||
for (LanguageSettingsChangeEvent event : events) {
|
||||
notifyLanguageSettingsChangeListeners(event);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
CCorePlugin.log("Internal error while trying to serialize language settings", e); //$NON-NLS-1$
|
||||
|
@ -414,6 +545,10 @@ public class LanguageSettingsProvidersSerializer {
|
|||
|
||||
public static void serializeLanguageSettings(ICProjectDescription prjDescription) throws CoreException {
|
||||
IProject project = prjDescription.getProject();
|
||||
// AG TODO - remove the log
|
||||
CCorePlugin.log(new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, IStatus.OK,
|
||||
"LanguageSettingsProvidersSerializer.serializeLanguageSettings() for " + project, new Exception()));
|
||||
|
||||
try {
|
||||
// Document to store in project area
|
||||
Document docStorePrj = XmlUtil.newDocument();
|
||||
|
@ -422,26 +557,37 @@ public class LanguageSettingsProvidersSerializer {
|
|||
Document docStoreWsp = XmlUtil.newDocument();
|
||||
Element projectElementStoreWsp = XmlUtil.appendElement(docStoreWsp, ELEM_PROJECT);
|
||||
|
||||
serializeLanguageSettingsInternal(projectElementStorePrj, projectElementStoreWsp, prjDescription);
|
||||
|
||||
IFile fileStorePrj = getStoreInProjectArea(project);
|
||||
// The project store should not be absent. Absent store means legacy project, not 0 providers.
|
||||
IFile fileStorePrj = getStoreInProjectArea(project);
|
||||
|
||||
URI uriStoreWsp = getStoreInWorkspaceArea(project.getName()+'.'+STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
LanguageSettingsChangeEvent event = null;
|
||||
|
||||
try {
|
||||
serializingLock.acquire();
|
||||
|
||||
// Note that need for serialization may exist even if LSE event delta is empty,
|
||||
// as number or properties of providers may differ
|
||||
serializeLanguageSettingsInternal(projectElementStorePrj, projectElementStoreWsp, prjDescription);
|
||||
XmlUtil.serializeXml(docStorePrj, fileStorePrj);
|
||||
|
||||
URI uriStoreWsp = null;
|
||||
boolean isWorkspaceStoreEmpty = projectElementStoreWsp.getChildNodes().getLength() == 0;
|
||||
uriStoreWsp = getStoreInWorkspaceArea(project.getName()+'.'+STORAGE_WORKSPACE_LANGUAGE_SETTINGS);
|
||||
serializingLock.acquire();
|
||||
try {
|
||||
// project-specific location in workspace area
|
||||
boolean isWorkspaceStoreEmpty = projectElementStoreWsp.getChildNodes().getLength() == 0;
|
||||
if (!isWorkspaceStoreEmpty) {
|
||||
XmlUtil.serializeXml(docStoreWsp, uriStoreWsp);
|
||||
} else {
|
||||
new java.io.File(uriStoreWsp).delete();
|
||||
}
|
||||
|
||||
// manufacture the event only if serialization was successful
|
||||
event = new LanguageSettingsChangeEvent(prjDescription);
|
||||
} finally {
|
||||
serializingLock.release();
|
||||
}
|
||||
// notify the listeners outside the lock
|
||||
if (event.getConfigurationDescriptionIds().length > 0) {
|
||||
notifyLanguageSettingsChangeListeners(event);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
IStatus s = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Internal error while trying to serialize language settings", e);
|
||||
|
@ -510,8 +656,16 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
|
||||
ICConfigurationDescription cfgDescription = prjDescription.getConfigurationById(cfgId);
|
||||
if (cfgDescription!=null)
|
||||
if (cfgDescription!=null) {
|
||||
cfgDescription.setLanguageSettingProviders(providers);
|
||||
if (cfgDescription instanceof IInternalCCfgInfo) {
|
||||
try {
|
||||
((IInternalCCfgInfo) cfgDescription).getSpecSettings().dropDelta();
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -839,8 +993,9 @@ public class LanguageSettingsProvidersSerializer {
|
|||
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));
|
||||
IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, Status.OK,
|
||||
"Not able to clone provider " + provider.getClass(), e);
|
||||
CCorePlugin.log(status);
|
||||
}
|
||||
}
|
||||
newProviders.add(provider);
|
||||
|
@ -848,4 +1003,300 @@ public class LanguageSettingsProvidersSerializer {
|
|||
return new ArrayList<ILanguageSettingsProvider>(newProviders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener that will be notified of changes in language settings.
|
||||
*
|
||||
* @param listener the ILanguageMappingChangeListener to add
|
||||
*/
|
||||
public static void registerLanguageSettingsChangeListener(ILanguageSettingsChangeListener listener) {
|
||||
fLanguageSettingsChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a language settings change listener.
|
||||
*
|
||||
* @param listener the ILanguageMappingChangeListener to remove.
|
||||
*/
|
||||
public static void unregisterLanguageSettingsChangeListener(ILanguageSettingsChangeListener listener) {
|
||||
fLanguageSettingsChangeListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all language settings change listeners of a change.
|
||||
*
|
||||
* @param event the ILanguageSettingsChangeEvent event to be broadcast.
|
||||
*/
|
||||
public static void notifyLanguageSettingsChangeListeners(ILanguageSettingsChangeEvent event) {
|
||||
// AG TODO - remove the log
|
||||
CCorePlugin.log(new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, IStatus.OK,
|
||||
"Firing " + event, new Exception()));
|
||||
|
||||
Object[] listeners = fLanguageSettingsChangeListeners.getListeners();
|
||||
for (Object obj : listeners) {
|
||||
ILanguageSettingsChangeListener listener = (ILanguageSettingsChangeListener) obj;
|
||||
listener.handleEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ICLanguageSettingEntry> safeGetSettingEntries(ILanguageSettingsProvider provider,
|
||||
ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
|
||||
try {
|
||||
return provider.getSettingEntries(cfgDescription, rc, languageId);
|
||||
} catch (Throwable e) {
|
||||
String cfgId = cfgDescription!=null ? cfgDescription.getId() : null;
|
||||
String msg = "Exception in provider "+provider.getId()+": getSettingEntries("+cfgId+", "+rc+", "+languageId+")";
|
||||
CCorePlugin.log(msg, e);
|
||||
// return empty array to prevent climbing up the resource tree
|
||||
return new ArrayList<ICLanguageSettingEntry>(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of setting entries of the given provider
|
||||
* for the given configuration description, resource and language.
|
||||
* This method reaches to the parent folder of the resource recursively
|
||||
* in case the resource does not define the entries for the given provider.
|
||||
*
|
||||
* @param provider - language settings provider.
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
*
|
||||
* @return the list of setting entries. Never returns {@code null}
|
||||
* although individual providers mandated to return {@code null} if no settings defined.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSettingEntriesUpResourceTree(ILanguageSettingsProvider provider, ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
Assert.isTrue( !(rc instanceof IWorkspaceRoot) );
|
||||
if (provider!=null) {
|
||||
List<ICLanguageSettingEntry> entries = safeGetSettingEntries(provider, cfgDescription, rc, languageId);
|
||||
if (entries!=null) {
|
||||
return new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
}
|
||||
if (rc!=null) {
|
||||
IResource parentFolder = (rc instanceof IProject) ? null : rc.getParent();
|
||||
if (parentFolder!=null) {
|
||||
return getSettingEntriesUpResourceTree(provider, cfgDescription, parentFolder, languageId);
|
||||
}
|
||||
// if out of parent resources - get default entries for the applicable language scope
|
||||
entries = safeGetSettingEntries(provider, null, null, languageId);
|
||||
if (entries!=null) {
|
||||
return new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<ICLanguageSettingEntry>(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds for the provider a nice looking resource tree to present hierarchical view to the user.
|
||||
* Note that it is not advisable to "compact" the tree because of potential loss of information
|
||||
* which is especially important during partial or incremental builds.
|
||||
*
|
||||
* @param provider - language settings provider to build the tree for.
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param languageId - language ID.
|
||||
* @param folder - container where the tree roots.
|
||||
*/
|
||||
public static void buildResourceTree(LanguageSettingsSerializable provider, ICConfigurationDescription cfgDescription, String languageId, IContainer folder) {
|
||||
IResource[] members = null;
|
||||
try {
|
||||
members = folder.members();
|
||||
} catch (Exception e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
if (members==null)
|
||||
return;
|
||||
|
||||
for (IResource rc : members) {
|
||||
if (rc instanceof IContainer) {
|
||||
buildResourceTree(provider, cfgDescription, languageId, (IContainer) rc);
|
||||
}
|
||||
}
|
||||
|
||||
int rcNumber = members.length;
|
||||
|
||||
Map<List<ICLanguageSettingEntry>, Integer> listMap = new HashMap<List<ICLanguageSettingEntry>, Integer>();
|
||||
|
||||
// on the first pass find majority entries
|
||||
List<ICLanguageSettingEntry> majorityEntries = null;
|
||||
List<ICLanguageSettingEntry> candidate = null;
|
||||
int candidateCount = 0;
|
||||
for (IResource rc : members) {
|
||||
if (!isLanguageInScope(rc, cfgDescription, languageId)) {
|
||||
rcNumber--;
|
||||
} else {
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, rc, languageId);
|
||||
if (entries==null && rc instanceof IContainer) {
|
||||
rcNumber--;
|
||||
} else {
|
||||
Integer count = listMap.get(entries);
|
||||
if (count==null) {
|
||||
count = 0;
|
||||
}
|
||||
count++;
|
||||
|
||||
if (count>candidateCount) {
|
||||
candidateCount = count;
|
||||
candidate = entries;
|
||||
}
|
||||
|
||||
listMap.put(entries, count);
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateCount > rcNumber/2) {
|
||||
majorityEntries = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (majorityEntries!=null) {
|
||||
provider.setSettingEntries(cfgDescription, folder, languageId, majorityEntries);
|
||||
}
|
||||
|
||||
// second pass - assign the entries to the folders
|
||||
for (IResource rc : members) {
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, rc, languageId);
|
||||
if (entries!=null && entries==majorityEntries) {
|
||||
if (!(rc instanceof IFile)) { // preserve information which files were collected
|
||||
provider.setSettingEntries(cfgDescription, rc, languageId, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLanguageInScope(IResource rc, ICConfigurationDescription cfgDescription, String languageId) {
|
||||
if (rc instanceof IFile) {
|
||||
ILanguage lang = null;
|
||||
try {
|
||||
lang = LanguageManager.getInstance().getLanguageForFile((IFile) rc, cfgDescription);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log("Error loading language settings providers extensions", e); //$NON-NLS-1$
|
||||
}
|
||||
if (lang==null || (languageId!=null && !languageId.equals(lang.getId()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean checkBit(int flags, int bit) {
|
||||
return (flags & bit) == bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of setting entries of a certain kind (such as include paths)
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
* @param checkLocality - specifies if parameter {@code isLocal} should be considered.
|
||||
* @param isLocal - {@code true} if "local" entries should be provided and
|
||||
* {@code false} for "system" entries. This makes sense for include paths where
|
||||
* [#include "..."] is "local" and [#include <...>] is system.
|
||||
*
|
||||
* @return the list of setting entries found.
|
||||
*/
|
||||
private static List<ICLanguageSettingEntry> getSettingEntriesByKind(ICConfigurationDescription cfgDescription,
|
||||
IResource rc, String languageId, int kind, boolean checkLocality, boolean isLocal) {
|
||||
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
List<String> alreadyAdded = new ArrayList<String>();
|
||||
|
||||
List<ILanguageSettingsProvider> providers = cfgDescription.getLanguageSettingProviders();
|
||||
for (ILanguageSettingsProvider provider: providers) {
|
||||
List<ICLanguageSettingEntry> providerEntries = getSettingEntriesUpResourceTree(provider, cfgDescription, rc, languageId);
|
||||
for (ICLanguageSettingEntry entry : providerEntries) {
|
||||
if (entry!=null) {
|
||||
String entryName = entry.getName();
|
||||
boolean isRightKind = (entry.getKind() & kind) != 0;
|
||||
// Only first entry is considered
|
||||
// Entry flagged as "UNDEFINED" prevents adding entry with the same name down the line
|
||||
if (isRightKind && !alreadyAdded.contains(entryName)) {
|
||||
int flags = entry.getFlags();
|
||||
boolean isRightLocal = !checkLocality || (checkBit(flags, ICSettingEntry.LOCAL) == isLocal);
|
||||
if (isRightLocal) {
|
||||
if (!checkBit(flags, ICSettingEntry.UNDEFINED)) {
|
||||
entries.add(entry);
|
||||
}
|
||||
alreadyAdded.add(entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of setting entries of a certain kind (such as include paths)
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined. For include paths both
|
||||
* local (#include "...") and system (#include <...>) entries are returned.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
*
|
||||
* @return the list of setting entries.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return getSettingEntriesByKind(cfgDescription, rc, languageId, kind, /* checkLocality */ false, /* isLocal */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of "system" (such as [#include <...>]) setting entries of a certain kind
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
*
|
||||
* @return the list of setting entries.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getSystemSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return getSettingEntriesByKind(cfgDescription, rc, languageId, kind, /* checkLocality */ true, /* isLocal */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of "local" (such as [#include "..."]) setting entries of a certain kind
|
||||
* for the given configuration description, resource and language. This is a
|
||||
* combined list for all providers taking into account settings of parent folder
|
||||
* if settings for the given resource are not defined.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* @param rc - resource such as file or folder.
|
||||
* @param languageId - language id.
|
||||
* @param kind - kind of language settings entries, such as
|
||||
* {@link ICSettingEntry#INCLUDE_PATH} etc. This is a binary flag
|
||||
* and it is possible to specify composite kind.
|
||||
* Use {@link ICSettingEntry#ALL} to get all kinds.
|
||||
*
|
||||
* @return the list of setting entries.
|
||||
*/
|
||||
public static List<ICLanguageSettingEntry> getLocalSettingEntriesByKind(ICConfigurationDescription cfgDescription, IResource rc, String languageId, int kind) {
|
||||
return getSettingEntriesByKind(cfgDescription, rc, languageId, kind, /* checkLocality */ true, /* isLocal */ true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -80,23 +80,23 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider
|
|||
LinkedHashSet<ICLanguageSettingEntry> macroEntries = new LinkedHashSet<ICLanguageSettingEntry>();
|
||||
|
||||
for (String langId : languageIds) {
|
||||
List<ICLanguageSettingEntry> incSys = LanguageSettingsExtensionManager.getSystemSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
List<ICLanguageSettingEntry> incSys = LanguageSettingsProvidersSerializer.getSystemSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
ICSettingEntry.INCLUDE_PATH);
|
||||
includePathEntries.addAll(incSys);
|
||||
|
||||
List<ICLanguageSettingEntry> incLocal = LanguageSettingsExtensionManager.getLocalSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
List<ICLanguageSettingEntry> incLocal = LanguageSettingsProvidersSerializer.getLocalSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
ICSettingEntry.INCLUDE_PATH);
|
||||
includePathLocalEntries.addAll(incLocal);
|
||||
|
||||
List<ICLanguageSettingEntry> incFiles = LanguageSettingsExtensionManager.getSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
List<ICLanguageSettingEntry> incFiles = LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
ICSettingEntry.INCLUDE_FILE);
|
||||
includeFileEntries.addAll(incFiles);
|
||||
|
||||
List<ICLanguageSettingEntry> macroFiles = LanguageSettingsExtensionManager.getSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
List<ICLanguageSettingEntry> macroFiles = LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
ICSettingEntry.MACRO_FILE);
|
||||
macroFileEntries.addAll(macroFiles);
|
||||
|
||||
List<ICLanguageSettingEntry> macros = LanguageSettingsExtensionManager.getSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
List<ICLanguageSettingEntry> macros = LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, langId,
|
||||
ICSettingEntry.MACRO);
|
||||
macroEntries.addAll(macros);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,378 @@
|
|||
package org.eclipse.cdt.internal.core.language.settings.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||
import org.eclipse.cdt.core.settings.model.util.LanguageSettingEntriesSerializer;
|
||||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.internal.core.parser.util.WeakHashSet;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class LanguageSettingsStorage {
|
||||
private static final String ELEM_LANGUAGE = "language"; //$NON-NLS-1$
|
||||
private static final String ATTR_LANGUAGE_ID = "id"; //$NON-NLS-1$
|
||||
private static final String ELEM_RESOURCE = "resource"; //$NON-NLS-1$
|
||||
private static final String ATTR_PROJECT_PATH = "project-relative-path"; //$NON-NLS-1$
|
||||
|
||||
private static final String ELEM_ENTRY = "entry"; //$NON-NLS-1$
|
||||
private static final String ATTR_KIND = "kind"; //$NON-NLS-1$
|
||||
private static final String ATTR_NAME = "name"; //$NON-NLS-1$
|
||||
private static final String ATTR_VALUE = "value"; //$NON-NLS-1$
|
||||
private static final String ELEM_FLAG = "flag"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* 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>>>();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* <br> Note that this list is <b>unmodifiable</b>. To modify the list copy it, change and use
|
||||
* {@link #setSettingEntries(ICConfigurationDescription, IResource, String, List)}.
|
||||
*
|
||||
*/
|
||||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
List<ICLanguageSettingEntry> entries = null;
|
||||
Map<String, List<ICLanguageSettingEntry>> langMap = fStorage.get(languageId);
|
||||
if (langMap!=null) {
|
||||
String rcProjectPath = rc!=null ? rc.getProjectRelativePath().toString() : null;
|
||||
entries = langMap.get(rcProjectPath);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private List<ICLanguageSettingEntry> sortEntries(List<ICLanguageSettingEntry> entries) {
|
||||
List<ICLanguageSettingEntry> sortedEntries = new ArrayList<ICLanguageSettingEntry>(entries);
|
||||
Collections.sort(sortedEntries, new Comparator<ICLanguageSettingEntry>(){
|
||||
/**
|
||||
* This comparator sorts by kinds first and the macros are sorted additionally by name.
|
||||
*/
|
||||
public int compare(ICLanguageSettingEntry entry0, ICLanguageSettingEntry entry1) {
|
||||
int kind0 = entry0.getKind();
|
||||
int kind1 = entry1.getKind();
|
||||
if (kind0==ICSettingEntry.MACRO && kind1==ICSettingEntry.MACRO) {
|
||||
return entry0.getName().compareTo(entry1.getName());
|
||||
}
|
||||
|
||||
return kind0 - kind1;
|
||||
}});
|
||||
|
||||
return sortedEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setSettingEntries(String rcProjectPath, String languageId, List<ICLanguageSettingEntry> entries) {
|
||||
synchronized (fStorage) {
|
||||
if (entries!=null) {
|
||||
Map<String, List<ICLanguageSettingEntry>> langMap = fStorage.get(languageId);
|
||||
if (langMap==null) {
|
||||
langMap = new HashMap<String, List<ICLanguageSettingEntry>>();
|
||||
fStorage.put(languageId, langMap);
|
||||
}
|
||||
List<ICLanguageSettingEntry> sortedEntries = listPool.add(Collections.unmodifiableList(sortEntries(entries)));
|
||||
langMap.put(rcProjectPath, sortedEntries);
|
||||
} else {
|
||||
// do not keep nulls in the tables
|
||||
Map<String, List<ICLanguageSettingEntry>> langMap = fStorage.get(languageId);
|
||||
if (langMap!=null) {
|
||||
langMap.remove(rcProjectPath);
|
||||
if (langMap.size()==0) {
|
||||
fStorage.remove(languageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the provider does not keep any settings yet or {@code false} if there are some.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return fStorage.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all the entries for all configurations, all resources and all languages.
|
||||
*/
|
||||
public void clear() {
|
||||
synchronized (fStorage) {
|
||||
fStorage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the provider entries under parent XML element.
|
||||
* @param elementProvider - element where to serialize the entries.
|
||||
*/
|
||||
public void serializeEntries(Element elementProvider) {
|
||||
synchronized (fStorage) {
|
||||
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) {
|
||||
Element elementLanguage = XmlUtil.appendElement(parentElement, ELEM_LANGUAGE, new String[] {ATTR_LANGUAGE_ID, langId});
|
||||
parentElement = elementLanguage;
|
||||
}
|
||||
for (Entry<String, List<ICLanguageSettingEntry>> entryRc : entryLang.getValue().entrySet()) {
|
||||
serializeResource(parentElement, entryRc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
Element elementRc = XmlUtil.appendElement(parentElement, ELEM_RESOURCE, new String[] {ATTR_PROJECT_PATH, rcProjectPath});
|
||||
parentElement = elementRc;
|
||||
}
|
||||
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[] {
|
||||
ATTR_KIND, LanguageSettingEntriesSerializer.kindToString(entry.getKind()),
|
||||
ATTR_NAME, entry.getName(),
|
||||
});
|
||||
switch(entry.getKind()) {
|
||||
case ICSettingEntry.MACRO:
|
||||
elementSettingEntry.setAttribute(ATTR_VALUE, entry.getValue());
|
||||
break;
|
||||
// case ICLanguageSettingEntry.LIBRARY_FILE:
|
||||
// // TODO: sourceAttachment fields may need to be covered
|
||||
// break;
|
||||
}
|
||||
int flags = entry.getFlags();
|
||||
if (flags!=0) {
|
||||
// Element elementFlag =
|
||||
XmlUtil.appendElement(elementSettingEntry, ELEM_FLAG, new String[] {
|
||||
ATTR_VALUE, LanguageSettingEntriesSerializer.composeFlagsString(entry.getFlags())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
} else if (ELEM_ENTRY.equals(elementNode.getNodeName())) {
|
||||
ICLanguageSettingEntry entry = loadSettingEntry(elementNode);
|
||||
if (entry!=null) {
|
||||
settings.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set settings
|
||||
if (settings.size()>0) {
|
||||
setSettingEntries(null, null, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
NodeList flagNodes = parentElement.getChildNodes();
|
||||
int flags = 0;
|
||||
for (int i=0;i<flagNodes.getLength();i++) {
|
||||
Node flagNode = flagNodes.item(i);
|
||||
if(flagNode.getNodeType() != Node.ELEMENT_NODE || !ELEM_FLAG.equals(flagNode.getNodeName()))
|
||||
continue;
|
||||
|
||||
String settingFlags = XmlUtil.determineAttributeValue(flagNode, ATTR_VALUE);
|
||||
int bitFlag = LanguageSettingEntriesSerializer.composeFlags(settingFlags);
|
||||
flags |= bitFlag;
|
||||
|
||||
}
|
||||
|
||||
String settingValue = null;
|
||||
int kind = LanguageSettingEntriesSerializer.stringToKind(settingKind);
|
||||
if (kind == ICSettingEntry.MACRO)
|
||||
settingValue = XmlUtil.determineAttributeValue(parentElement, ATTR_VALUE);
|
||||
ICLanguageSettingEntry entry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, settingName, settingValue, null, flags);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load entries defined in language element.
|
||||
*/
|
||||
private void loadLanguageElement(Node parentNode, String cfgId) {
|
||||
String langId = XmlUtil.determineAttributeValue(parentNode, ATTR_LANGUAGE_ID);
|
||||
if (langId.length()==0) {
|
||||
langId=null;
|
||||
}
|
||||
|
||||
List<ICLanguageSettingEntry> settings = new ArrayList<ICLanguageSettingEntry>();
|
||||
NodeList nodes = parentNode.getChildNodes();
|
||||
for (int i=0;i<nodes.getLength();i++) {
|
||||
Node elementNode = nodes.item(i);
|
||||
if(elementNode.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (ELEM_RESOURCE.equals(elementNode.getNodeName())) {
|
||||
loadResourceElement(elementNode, cfgId, langId);
|
||||
} else if (ELEM_ENTRY.equals(elementNode.getNodeName())) {
|
||||
ICLanguageSettingEntry entry = loadSettingEntry(elementNode);
|
||||
if (entry!=null) {
|
||||
settings.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set settings
|
||||
if (settings.size()>0) {
|
||||
setSettingEntries(null, langId, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load entries defined in resource element.
|
||||
*/
|
||||
private void loadResourceElement(Node parentNode, String cfgId, String langId) {
|
||||
String rcProjectPath = XmlUtil.determineAttributeValue(parentNode, ATTR_PROJECT_PATH);
|
||||
|
||||
List<ICLanguageSettingEntry> settings = new ArrayList<ICLanguageSettingEntry>();
|
||||
NodeList nodes = parentNode.getChildNodes();
|
||||
for (int i=0;i<nodes.getLength();i++) {
|
||||
Node elementNode = nodes.item(i);
|
||||
if(elementNode.getNodeType() != Node.ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (ELEM_ENTRY.equals(elementNode.getNodeName())) {
|
||||
ICLanguageSettingEntry entry = loadSettingEntry(elementNode);
|
||||
if (entry!=null) {
|
||||
settings.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set settings
|
||||
if (settings.size()>0) {
|
||||
setSettingEntries(rcProjectPath, langId, settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* Warning: but if you use it make sure you synchronize on it while traversing.
|
||||
*/
|
||||
Map<String, Map<String, List<ICLanguageSettingEntry>>> getMapInternal() {
|
||||
return fStorage;
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public LanguageSettingsStorage cloneStorage() {
|
||||
LanguageSettingsStorage storageClone = new LanguageSettingsStorage();
|
||||
synchronized (fStorage) {
|
||||
Set<Entry<String, Map<String, List<ICLanguageSettingEntry>>>> entrySetLang = fStorage.entrySet();
|
||||
for (Entry<String, Map<String, List<ICLanguageSettingEntry>>> entryLang : entrySetLang) {
|
||||
String langId = entryLang.getKey();
|
||||
Map<String, List<ICLanguageSettingEntry>> mapRc = entryLang.getValue();
|
||||
Map<String, List<ICLanguageSettingEntry>> mapRcClone = new HashMap<String, List<ICLanguageSettingEntry>>();
|
||||
Set<Entry<String, List<ICLanguageSettingEntry>>> entrySetRc = mapRc.entrySet();
|
||||
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 LSE pool
|
||||
mapRcClone.put(rcProjectPath, lsEntries);
|
||||
}
|
||||
storageClone.fStorage.put(langId, mapRcClone);
|
||||
}
|
||||
}
|
||||
return storageClone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((fStorage == null) ? 0 : fStorage.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LanguageSettingsStorage other = (LanguageSettingsStorage) obj;
|
||||
if (fStorage == null) {
|
||||
if (other.fStorage != null)
|
||||
return false;
|
||||
} else if (!fStorage.equals(other.fStorage))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,8 @@ import java.util.Set;
|
|||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable;
|
||||
import org.eclipse.cdt.core.settings.model.CExternalSetting;
|
||||
import org.eclipse.cdt.core.settings.model.ICBuildSetting;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
|
||||
|
@ -41,7 +43,9 @@ 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.LanguageSettingsDelta;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsStorage;
|
||||
import org.eclipse.cdt.utils.envvar.StorableEnvironment;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.QualifiedName;
|
||||
|
@ -94,6 +98,8 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{
|
|||
// private Map fExternalSettingsProviderMap;
|
||||
|
||||
private List<ILanguageSettingsProvider> fLanguageSettingsProviders = new ArrayList<ILanguageSettingsProvider>(0);
|
||||
private LinkedHashMap<String /*provider*/, LanguageSettingsStorage> lspPersistedState = new LinkedHashMap<String, LanguageSettingsStorage>();
|
||||
|
||||
|
||||
private class DeltaSet {
|
||||
public Set<ICConfigExtensionReference> extSet;
|
||||
|
@ -189,6 +195,10 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{
|
|||
copyExtensionInfo(base);
|
||||
|
||||
fLanguageSettingsProviders = LanguageSettingsProvidersSerializer.cloneProviders(base.getLanguageSettingProviders());
|
||||
for (String providerId : base.lspPersistedState.keySet()) {
|
||||
LanguageSettingsStorage clone = base.lspPersistedState.get(providerId).cloneStorage();
|
||||
lspPersistedState.put(providerId, clone);
|
||||
}
|
||||
}
|
||||
|
||||
// private void copyRefInfos(Map infosMap){
|
||||
|
@ -1011,4 +1021,40 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{
|
|||
public List<ILanguageSettingsProvider> getLanguageSettingProviders() {
|
||||
return Collections.unmodifiableList(fLanguageSettingsProviders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns delta and atomically updates last persisted state to the new state.
|
||||
* That implies that the delta needs to be used to fire an event of it will
|
||||
* be lost.
|
||||
*/
|
||||
public LanguageSettingsDelta dropDelta() {
|
||||
LanguageSettingsDelta languageSettingsDelta = null;
|
||||
// newState gets shallow map first
|
||||
LinkedHashMap<String, LanguageSettingsStorage> newStateShallow = new LinkedHashMap<String, LanguageSettingsStorage>();
|
||||
for (ILanguageSettingsProvider provider : fLanguageSettingsProviders) {
|
||||
if (LanguageSettingsManager.isWorkspaceProvider(provider)) {
|
||||
provider = LanguageSettingsManager.getRawProvider(provider);
|
||||
}
|
||||
if (provider instanceof LanguageSettingsSerializable) {
|
||||
LanguageSettingsStorage store = ((LanguageSettingsSerializable) provider).getStorageInternal();
|
||||
if (!store.isEmpty()) {
|
||||
newStateShallow.put(provider.getId(), store);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!newStateShallow.equals(lspPersistedState)) {
|
||||
// do deep copy if the state needs to be saved
|
||||
LinkedHashMap<String, LanguageSettingsStorage> newStateDeep = new LinkedHashMap<String, LanguageSettingsStorage>();
|
||||
for (Entry<String, LanguageSettingsStorage> entry : newStateShallow.entrySet()) {
|
||||
String providerId = entry.getKey();
|
||||
LanguageSettingsStorage store = entry.getValue();
|
||||
newStateDeep.put(providerId, store.cloneStorage());
|
||||
}
|
||||
languageSettingsDelta = new LanguageSettingsDelta(lspPersistedState, newStateDeep);
|
||||
lspPersistedState = newStateDeep;
|
||||
}
|
||||
|
||||
return languageSettingsDelta;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011, 2011 Andrew Gvozdev and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrew Gvozdev - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.ILanguageSettingsChangeEvent;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.ILanguageSettingsChangeListener;
|
||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* This class handles changes in language settings for the PDOM by reindexing the appropriate resources.
|
||||
*/
|
||||
public class LanguageSettingsChangeListener implements ILanguageSettingsChangeListener {
|
||||
|
||||
private IIndexManager fManager;
|
||||
|
||||
public LanguageSettingsChangeListener(IIndexManager manager) {
|
||||
fManager = manager;
|
||||
}
|
||||
|
||||
public void handleEvent(ILanguageSettingsChangeEvent event) {
|
||||
String projectName = event.getProjectName();
|
||||
IWorkspaceRoot wspRoot = ResourcesPlugin.getWorkspace().getRoot();
|
||||
IProject project = wspRoot.getProject(projectName);
|
||||
|
||||
ICProjectDescription prjDescription = CCorePlugin.getDefault().getProjectDescription(project);
|
||||
ICConfigurationDescription indexedCfgDescription = prjDescription.getDefaultSettingConfiguration();
|
||||
|
||||
CModelManager manager = CModelManager.getDefault();
|
||||
|
||||
IResource[] resources = event.getResources(indexedCfgDescription.getId());
|
||||
|
||||
if (resources.length > 0) {
|
||||
ICProject cProject = manager.getCModel().getCProject(project);
|
||||
List<ICElement> elements = new ArrayList<ICElement>();
|
||||
|
||||
for (IResource rc : resources) {
|
||||
// AG TODO - remove the log
|
||||
CCorePlugin.log(new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID,
|
||||
"LanguageSettingsChangeListener"+"["+System.identityHashCode(this)+"]"+".handleEvent() for " + rc, new Exception()));
|
||||
|
||||
elements.add(manager.create(rc, cProject));
|
||||
}
|
||||
|
||||
try {
|
||||
fManager.update(elements.toArray(new ICElement[elements.size()]), IIndexManager.UPDATE_ALL);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -60,6 +60,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
|
|||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
|
||||
import org.eclipse.cdt.core.settings.model.util.LanguageSettingEntriesSerializer;
|
||||
import org.eclipse.cdt.internal.core.CCoreInternals;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
|
@ -68,6 +69,7 @@ import org.eclipse.cdt.internal.core.index.IndexChangeEvent;
|
|||
import org.eclipse.cdt.internal.core.index.IndexFactory;
|
||||
import org.eclipse.cdt.internal.core.index.IndexerStateEvent;
|
||||
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
|
||||
|
@ -163,6 +165,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
|
|||
|
||||
private CModelListener fCModelListener= new CModelListener(this);
|
||||
private ILanguageMappingChangeListener fLanguageChangeListener = new LanguageMappingChangeListener(this);
|
||||
private LanguageSettingsChangeListener fLanguageSettingsChangeListener = new LanguageSettingsChangeListener(this);
|
||||
private final ICProjectDescriptionListener fProjectDescriptionListener;
|
||||
private final JobChangeListener fJobChangeListener;
|
||||
private final IPreferenceChangeListener fPreferenceChangeListener;
|
||||
|
@ -235,6 +238,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
|
|||
ResourcesPlugin.getWorkspace().addResourceChangeListener(fCModelListener, IResourceChangeEvent.POST_BUILD);
|
||||
model.addElementChangedListener(fCModelListener);
|
||||
LanguageManager.getInstance().registerLanguageChangeListener(fLanguageChangeListener);
|
||||
LanguageSettingsProvidersSerializer.registerLanguageSettingsChangeListener(fLanguageSettingsChangeListener);
|
||||
final int types= CProjectDescriptionEvent.DATA_APPLIED;
|
||||
CCorePlugin.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(fProjectDescriptionListener, types);
|
||||
|
||||
|
@ -255,6 +259,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
|
|||
final CoreModel model = CoreModel.getDefault();
|
||||
model.removeElementChangedListener(fCModelListener);
|
||||
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fCModelListener);
|
||||
LanguageSettingsProvidersSerializer.unregisterLanguageSettingsChangeListener(fLanguageSettingsChangeListener);
|
||||
LanguageManager.getInstance().unregisterLanguageChangeListener(fLanguageChangeListener);
|
||||
PDOMIndexerJob jobToCancel= null;
|
||||
synchronized (fTaskQueue) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.jface.viewers.IDecoration;
|
||||
|
@ -47,7 +46,6 @@ import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditabl
|
|||
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.LanguageSettingsManager_TBD;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
|
@ -1020,14 +1018,6 @@ providers: for (ILanguageSettingsProvider provider : providers) {
|
|||
enableProvidersCheckBox.setSelection(enabled);
|
||||
}
|
||||
|
||||
try {
|
||||
LanguageSettingsManager_TBD.serializeWorkspaceProviders();
|
||||
} catch (CoreException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
throw new UnsupportedOperationException("Internal Error");
|
||||
}
|
||||
|
||||
trackInitialSettings();
|
||||
updateData(getResDesc());
|
||||
}
|
||||
|
@ -1063,19 +1053,4 @@ providers: for (ILanguageSettingsProvider provider : providers) {
|
|||
provider.setSettingEntries(cfgDescription, rc, currentLanguageId, entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIndexerAffected() {
|
||||
// List<ILanguageSettingsProvider> newProvidersList = null;
|
||||
// ICConfigurationDescription cfgDescription = getConfigurationDescription();
|
||||
// if (cfgDescription!=null) {
|
||||
// newProvidersList = cfgDescription.getLanguageSettingProviders();
|
||||
// }
|
||||
// boolean newEnablement = LanguageSettingsManager.isLanguageSettingsProvidersEnabled(page.getProject());
|
||||
//
|
||||
// boolean isEqualList = (newProvidersList==initialProvidersList) || (newProvidersList!=null && newProvidersList.equals(initialProvidersList));
|
||||
// return newEnablement!=initialEnablement || (newEnablement==true && !isEqualList);
|
||||
// FIXME
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,14 +51,8 @@ import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
|||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager_TBD;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.model.ILanguageDescriptor;
|
||||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICFileDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICFolderDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSetting;
|
||||
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingBase;
|
||||
import org.eclipse.cdt.ui.CDTSharedImages;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.dialogs.ICOptionPage;
|
||||
|
@ -66,7 +60,6 @@ import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
|
|||
import org.eclipse.cdt.ui.newui.CDTPrefUtil;
|
||||
import org.eclipse.cdt.utils.ui.controls.TabFolderLayout;
|
||||
|
||||
|
||||
import org.eclipse.cdt.internal.ui.newui.Messages;
|
||||
import org.eclipse.cdt.internal.ui.newui.StatusMessageLine;
|
||||
|
||||
|
@ -983,13 +976,6 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
LanguageSettingsManager_TBD.serializeWorkspaceProviders();
|
||||
} catch (CoreException e) {
|
||||
CUIPlugin.log("Internal Error", e);
|
||||
throw new UnsupportedOperationException("Internal Error");
|
||||
}
|
||||
|
||||
trackInitialSettings();
|
||||
updateData(getResDesc());
|
||||
}
|
||||
|
@ -1002,21 +988,6 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
|
|||
return page.isForPrefs() || page.isForProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isIndexerAffected() {
|
||||
List<ILanguageSettingsProvider> newProvidersList = null;
|
||||
ICConfigurationDescription cfgDescription = getConfigurationDescription();
|
||||
if (cfgDescription!=null) {
|
||||
newProvidersList = cfgDescription.getLanguageSettingProviders();
|
||||
}
|
||||
boolean newEnablement = ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(page.getProject());
|
||||
|
||||
// TODO
|
||||
boolean isEqualList = false;
|
||||
// boolean isEqualList = (newProvidersList==initialProvidersMap) || (newProvidersList!=null && newProvidersList.equals(initialProvidersMap));
|
||||
return newEnablement!=initialEnablement || (newEnablement==true && !isEqualList);
|
||||
}
|
||||
|
||||
private ILanguageSettingsProvider findRawProvider(String id, List<ILanguageSettingsProvider> providers) {
|
||||
for (ILanguageSettingsProvider provider : providers) {
|
||||
if (provider.getId().equals(id)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue