mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 265282 - Further issues with persistence issues
- Return StorableEnvironment to its former self - Add derived PrefsStorableEnviornment to persist and track environment changes in the eclipse preference store - Add tests and JavaDoc for issues discovered
This commit is contained in:
parent
68d9a584ff
commit
a50078bfdf
6 changed files with 886 additions and 190 deletions
|
@ -10,6 +10,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.envvar;
|
package org.eclipse.cdt.core.envvar;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
@ -68,9 +70,14 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
||||||
|
|
||||||
|
assertFalse(descs[0].isModified());
|
||||||
|
assertFalse(descs[1].isModified());
|
||||||
|
|
||||||
// Try setting an environment variable
|
// Try setting an environment variable
|
||||||
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
||||||
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
||||||
|
assertTrue(prjDesc.getConfigurationById(id1).isModified());
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id2).isModified());
|
||||||
|
|
||||||
// Check that the variable exists on the config1 & not in config2:
|
// Check that the variable exists on the config1 & not in config2:
|
||||||
IEnvironmentVariable var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
IEnvironmentVariable var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
|
@ -83,13 +90,100 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
// Close and reopen, variables should still exist
|
// Close and reopen, variables should still exist
|
||||||
project.close(null);
|
project.close(null);
|
||||||
project.open(null);
|
project.open(null);
|
||||||
descs = CoreModel.getDefault().getProjectDescription(project).getConfigurations();
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
assertEquals(var2, var);
|
assertEquals(var2, var);
|
||||||
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true);
|
var2 = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true);
|
||||||
assertNull(var2);
|
assertNull(var2);
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id1).isModified());
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id2).isModified());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that we can load the environment stored as a single (old-style) long XML string
|
||||||
|
* Also tests that an an external change to the settings file is correctly picked up.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void testOldStyleLoad() throws Exception {
|
||||||
|
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProjectOldStyleLoad");
|
||||||
|
|
||||||
|
// Add another, derived configuration
|
||||||
|
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
|
||||||
|
final String id1 = desc.getId(); // Config 1's ID
|
||||||
|
final String id2 = "712427638"; // Config 2's ID
|
||||||
|
prjDesc.createConfiguration(id2, "config2", desc);
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
|
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
||||||
|
final IEnvironmentVariable varOrig = new EnvironmentVariable("FOO", "ZOO");
|
||||||
|
contribEnv.addVariable(varOrig, prjDesc.getConfigurationById(id2));
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
final String env = "#Mon Nov 16 21:47:46 GMT 2009\n" +
|
||||||
|
"eclipse.preferences.version=1\n" +
|
||||||
|
"environment/project/712427638=<?xml version\\=\"1.0\" encoding\\=\"UTF-8\" standalone\\=\"no\"?>\\n" +
|
||||||
|
"<environment append\\=\"true\" appendContributed\\=\"true\">\\n" +
|
||||||
|
"<variable delimiter\\=\"\\:\" name\\=\"FOO1\" operation\\=\"replace\" value\\=\"BAR1\"/>\\n" +
|
||||||
|
"<variable delimiter\\=\"\\:\" name\\=\"FOO2\" operation\\=\"replace\" value\\=\"BAR2\"/>\\n" +
|
||||||
|
"<variable delimiter\\=\"\\;\" name\\=\"FOO\" operation\\=\"append\" value\\=\"BAR\"/>\\n</environment>\n";
|
||||||
|
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(new ByteArrayInputStream(env.getBytes("UTF-8")), true, false, null);
|
||||||
|
|
||||||
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR", IEnvironmentVariable.ENVVAR_APPEND, ";");
|
||||||
|
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
|
||||||
|
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
|
||||||
|
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true));
|
||||||
|
assertEquals(var1, envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id2), true));
|
||||||
|
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id2), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that an ovewrite of new style preferences is loaded correctly
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void testNewStyleOverwrite() throws Exception {
|
||||||
|
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProjectNewStyleLoad");
|
||||||
|
|
||||||
|
// Add another, derived configuration
|
||||||
|
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
|
||||||
|
final String id1 = desc.getId(); // Config 1's ID
|
||||||
|
final String id2 = "712427638"; // Config 2's ID
|
||||||
|
prjDesc.createConfiguration(id2, "config2", desc);
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
|
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
||||||
|
// Variable which will be overwritten
|
||||||
|
final IEnvironmentVariable varOrig = new EnvironmentVariable("FOO", "ZOO");
|
||||||
|
contribEnv.addVariable(varOrig, prjDesc.getConfigurationById(id2));
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
final String env = "environment/project/712427638/FOO/delimiter=;\n" +
|
||||||
|
"environment/project/712427638/FOO/operation=append\n" +
|
||||||
|
"environment/project/712427638/FOO/value=BAR\n" +
|
||||||
|
"environment/project/712427638/FOO1/delimiter=\\:\n" +
|
||||||
|
"environment/project/712427638/FOO1/operation=replace\n" +
|
||||||
|
"environment/project/712427638/FOO1/value=BAR1\n" +
|
||||||
|
"environment/project/712427638/FOO2/delimiter=\\:\n" +
|
||||||
|
"environment/project/712427638/FOO2/operation=replace\n" +
|
||||||
|
"environment/project/712427638/FOO2/value=BAR2\n" +
|
||||||
|
"environment/project/712427638/append=true\n" +
|
||||||
|
"environment/project/712427638/appendContributed=true\n";
|
||||||
|
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(new ByteArrayInputStream(env.getBytes("UTF-8")), true, false, null);
|
||||||
|
|
||||||
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR", IEnvironmentVariable.ENVVAR_APPEND, ";");
|
||||||
|
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
|
||||||
|
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
|
||||||
|
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id2), true));
|
||||||
|
assertEquals(var1, envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id2), true));
|
||||||
|
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id2), true));
|
||||||
|
}
|
||||||
|
|
||||||
public void testNoChangeToOneVariable() throws Exception {
|
public void testNoChangeToOneVariable() throws Exception {
|
||||||
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
|
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
|
||||||
|
@ -105,7 +199,7 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
// Try setting an environment variable
|
// Try setting an environment variable
|
||||||
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
||||||
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
|
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
|
||||||
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
|
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
|
||||||
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
||||||
contribEnv.addVariable(var1, prjDesc.getConfigurationById(id1));
|
contribEnv.addVariable(var1, prjDesc.getConfigurationById(id1));
|
||||||
contribEnv.addVariable(var2, prjDesc.getConfigurationById(id1));
|
contribEnv.addVariable(var2, prjDesc.getConfigurationById(id1));
|
||||||
|
@ -138,7 +232,7 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
project.close(null);
|
project.close(null);
|
||||||
project.open(null);
|
project.open(null);
|
||||||
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
|
||||||
readVar = envManager.getVariable(var3.getName(), prjDesc.getConfigurationById(id1), true);
|
readVar = envManager.getVariable(var3.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
assertEquals(var3, readVar);
|
assertEquals(var3, readVar);
|
||||||
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
|
readVar = envManager.getVariable(var1.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
|
@ -146,12 +240,141 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
|
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
assertEquals(var2, readVar);
|
assertEquals(var2, readVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests the get / set append persisting
|
||||||
|
*/
|
||||||
|
public void testGetSetAppend() throws Exception {
|
||||||
|
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
|
||||||
|
|
||||||
|
// Add another, derived configuration
|
||||||
|
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
|
||||||
|
final String id1 = desc.getId(); // Config 1's ID
|
||||||
|
final String id2 = CDataUtil.genId(id1); // Config 2's ID
|
||||||
|
prjDesc.createConfiguration(id2, "config2", desc);
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
// Get all the configurations
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription[] descs = prjDesc.getConfigurations();
|
||||||
|
assertEquals(2, descs.length);
|
||||||
|
|
||||||
|
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
|
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
||||||
|
|
||||||
|
assertFalse(descs[0].isModified());
|
||||||
|
assertFalse(descs[1].isModified());
|
||||||
|
|
||||||
|
// Set append & append contributed on the 2 configs respectively
|
||||||
|
final boolean append = contribEnv.appendEnvironment(prjDesc.getConfigurationById(id2));
|
||||||
|
contribEnv.setAppendEnvironment(!append, prjDesc.getConfigurationById(id2));
|
||||||
|
assertEquals(!append, contribEnv.appendEnvironment(prjDesc.getConfigurationById(id2)));
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id1).isModified());
|
||||||
|
assertTrue(prjDesc.getConfigurationById(id2).isModified());
|
||||||
|
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
// Close and reopen, variables should still exist
|
||||||
|
project.close(null);
|
||||||
|
project.open(null);
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
assertEquals(!append, contribEnv.appendEnvironment(prjDesc.getConfigurationById(id2)));
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id1).isModified());
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id2).isModified());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests file system change of the settings file
|
||||||
|
*/
|
||||||
|
public void testSettingsOverwrite() throws Exception {
|
||||||
|
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
|
||||||
|
|
||||||
|
// Add another, derived configuration
|
||||||
|
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
|
||||||
|
final String id1 = desc.getId(); // Config 1's ID
|
||||||
|
final String id2 = CDataUtil.genId(id1); // Config 2's ID
|
||||||
|
prjDesc.createConfiguration(id2, "config2", desc);
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
// Get all the configurations
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription[] descs = prjDesc.getConfigurations();
|
||||||
|
assertTrue(descs.length == 2);
|
||||||
|
|
||||||
|
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
|
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
||||||
|
|
||||||
|
assertFalse(descs[0].isModified());
|
||||||
|
assertFalse(descs[1].isModified());
|
||||||
|
|
||||||
|
// Try setting an environment variable
|
||||||
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
||||||
|
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
||||||
|
assertTrue(prjDesc.getConfigurationById(id1).isModified());
|
||||||
|
assertFalse(prjDesc.getConfigurationById(id2).isModified());
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
// Backup the settings file
|
||||||
|
project.getFile(".settings/org.eclipse.cdt.core.prefs.bak").create(
|
||||||
|
project.getFile(".settings/org.eclipse.cdt.core.prefs").getContents(), true, null);
|
||||||
|
|
||||||
|
// Change the environment variable
|
||||||
|
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO", "BOO");
|
||||||
|
contribEnv.addVariable(var2, prjDesc.getConfigurationById(id1));
|
||||||
|
assertEquals(var2, envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true));
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
// Replace the settings with it's backup
|
||||||
|
project.getFile(".settings/org.eclipse.cdt.core.prefs").setContents(
|
||||||
|
project.getFile(".settings/org.eclipse.cdt.core.prefs.bak").getContents(), true, false, null);
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
assertEquals(var, envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that on deleting and recreating the project variables haven't persisted
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void testBrokenCaching() throws Exception {
|
||||||
|
final IProject project = ResourceHelper.createCDTProjectWithConfig("envProject");
|
||||||
|
|
||||||
|
// Add another, derived configuration
|
||||||
|
ICProjectDescription prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
ICConfigurationDescription desc = prjDesc.getActiveConfiguration();
|
||||||
|
final String id1 = desc.getId();
|
||||||
|
|
||||||
|
IEnvironmentVariableManager envManager = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
|
IContributedEnvironment contribEnv = envManager.getContributedEnvironment();
|
||||||
|
// At the moment 0 variables are set
|
||||||
|
assertEquals(0, contribEnv.getVariables(desc).length);
|
||||||
|
|
||||||
|
// Try setting an environment variable
|
||||||
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
||||||
|
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
||||||
|
assertEquals(1, contribEnv.getVariables(desc).length);
|
||||||
|
// Check that the variable exists on config1
|
||||||
|
IEnvironmentVariable readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
|
assertEquals(var, readVar);
|
||||||
|
|
||||||
|
// Save the project description
|
||||||
|
CoreModel.getDefault().setProjectDescription(project, prjDesc);
|
||||||
|
|
||||||
|
ResourceHelper.cleanUp();
|
||||||
|
assertFalse(project.exists());
|
||||||
|
ResourceHelper.createCDTProjectWithConfig("envProject");
|
||||||
|
assertTrue(project.exists());
|
||||||
|
// Fetch the current configuration
|
||||||
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
|
desc = prjDesc.getActiveConfiguration();
|
||||||
|
assertEquals(0, contribEnv.getVariables(desc).length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This bug checks for an environment load race during project open / import.
|
* This bug checks for an environment load race during project open / import.
|
||||||
*
|
*
|
||||||
* This occurs because enviornment is stored using platform Preferences (persisted in
|
* This occurs because environment is stored using platform Preferences (persisted in
|
||||||
* the .settings directory) and, when background refresh is enabled this is loaded
|
* the .settings directory) and, when background refresh is enabled this is loaded
|
||||||
* asynchronously.
|
* asynchronously.
|
||||||
*
|
*
|
||||||
|
@ -172,7 +395,7 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
// Try setting an environment variable
|
// Try setting an environment variable
|
||||||
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
final IEnvironmentVariable var = new EnvironmentVariable("FOO", "BAR");
|
||||||
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
|
final IEnvironmentVariable var1 = new EnvironmentVariable("FOO1", "BAR1");
|
||||||
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
|
final IEnvironmentVariable var2 = new EnvironmentVariable("FOO2", "BAR2");
|
||||||
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
contribEnv.addVariable(var, prjDesc.getConfigurationById(id1));
|
||||||
|
|
||||||
// Check that the variable exists on config1
|
// Check that the variable exists on config1
|
||||||
|
@ -221,7 +444,7 @@ public class IEnvironmentVariableManagerTests extends TestCase {
|
||||||
assertNull(readVar);
|
assertNull(readVar);
|
||||||
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
|
readVar = envManager.getVariable(var2.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
assertEquals(var3, readVar);
|
assertEquals(var3, readVar);
|
||||||
|
|
||||||
// Get project description should only have the persisted envvar
|
// Get project description should only have the persisted envvar
|
||||||
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
prjDesc = CoreModel.getDefault().getProjectDescription(project);
|
||||||
readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
readVar = envManager.getVariable(var.getName(), prjDesc.getConfigurationById(id1), true);
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.eclipse.cdt.internal.core.CExtensionInfo;
|
||||||
import org.eclipse.cdt.internal.core.COwner;
|
import org.eclipse.cdt.internal.core.COwner;
|
||||||
import org.eclipse.cdt.internal.core.COwnerConfiguration;
|
import org.eclipse.cdt.internal.core.COwnerConfiguration;
|
||||||
import org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables;
|
import org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables;
|
||||||
|
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
|
||||||
import org.eclipse.cdt.utils.envvar.StorableEnvironment;
|
import org.eclipse.cdt.utils.envvar.StorableEnvironment;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.QualifiedName;
|
import org.eclipse.core.runtime.QualifiedName;
|
||||||
|
@ -161,7 +162,7 @@ public class CConfigurationSpecSettings implements ICSettingsStorage{
|
||||||
fSessionPropertiesMap = (HashMap<QualifiedName, Object>)base.fSessionPropertiesMap.clone();
|
fSessionPropertiesMap = (HashMap<QualifiedName, Object>)base.fSessionPropertiesMap.clone();
|
||||||
|
|
||||||
if(base.fEnvironment != null)
|
if(base.fEnvironment != null)
|
||||||
fEnvironment = new StorableEnvironment(base.fEnvironment, des.isReadOnly());
|
fEnvironment = EnvironmentVariableManager.fUserSupplier.cloneEnvironmentWithContext(fCfg, base.fEnvironment, des.isReadOnly());
|
||||||
|
|
||||||
fOwnerId = base.fOwnerId;
|
fOwnerId = base.fOwnerId;
|
||||||
fOwner = base.fOwner;
|
fOwner = base.fOwner;
|
||||||
|
|
|
@ -0,0 +1,507 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 Broadcom Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* James Blackburn (Broadcom Corp.)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.utils.envvar;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
||||||
|
import org.eclipse.cdt.utils.envvar.StorableEnvironmentLoader.ISerializeInfo;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
|
||||||
|
import org.osgi.service.prefs.BackingStoreException;
|
||||||
|
import org.osgi.service.prefs.Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the set of environment variables that could be loaded
|
||||||
|
* and stored from a IEclipsePreferences store. It acts like an OverlayStore caching
|
||||||
|
* outstanding changes while not yet serialized, as well as responding to change
|
||||||
|
* in the Preference store itself.
|
||||||
|
*
|
||||||
|
* fCachedSerialEnv is a cache of the contents of the preference store
|
||||||
|
* fVariables (in parent) contains runtime added / changed variables
|
||||||
|
* fDeleteVaraibles contains delete variable names
|
||||||
|
* When serialize is called, all changes in Variables / Delete are serialized to the
|
||||||
|
* ISerializeInfo store, Cached is updated, and fVariables and fDeletedVariables cleared.
|
||||||
|
*
|
||||||
|
* StorableEnvironment stores the Preferences in a single XML encoded String in
|
||||||
|
* ISerializeInfo.getNode().get(ISerializeInfo.getName())
|
||||||
|
* This class defaults to storing the environment as 'Raw' items in the Preferences
|
||||||
|
* under:
|
||||||
|
* ISerializeInfo.getNode().node(ISerializeInfo.getName())
|
||||||
|
*
|
||||||
|
* @since 5.2
|
||||||
|
* @noextend This class is not intended to be subclassed by clients.
|
||||||
|
* @noinstantiate This class is not intended to be instantiated by clients.
|
||||||
|
*/
|
||||||
|
public class PrefsStorableEnvironment extends StorableEnvironment {
|
||||||
|
|
||||||
|
/** Handle on the storage */
|
||||||
|
private ISerializeInfo fSerialEnv;
|
||||||
|
|
||||||
|
/** Set of 'deleted' variables (to be removed from the backing store) */
|
||||||
|
protected Set<String> fDeletedVariables;
|
||||||
|
|
||||||
|
// State to manage and handle external changes to the environment
|
||||||
|
|
||||||
|
/** Cache of Environment as loaded from the {@link ISerializeInfo}
|
||||||
|
* contains no non-persisted changes */
|
||||||
|
private Map<String, IEnvironmentVariable> fCachedSerialEnv = new HashMap<String, IEnvironmentVariable>();
|
||||||
|
|
||||||
|
// State to track whether API users have changed these boolean values
|
||||||
|
private boolean fAppendChanged = false;
|
||||||
|
private boolean fAppendContributedChanged = false;
|
||||||
|
|
||||||
|
/** A listener for changes in the backing store */
|
||||||
|
private static class PrefListener implements IPreferenceChangeListener, INodeChangeListener {
|
||||||
|
|
||||||
|
/** boolean indicating whether preferences have changed */
|
||||||
|
private volatile boolean prefsChanged = true;
|
||||||
|
|
||||||
|
/** The node we're registered on */
|
||||||
|
volatile IEclipsePreferences prefs;
|
||||||
|
|
||||||
|
public PrefListener(ISerializeInfo info) {
|
||||||
|
register (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the listener
|
||||||
|
*/
|
||||||
|
public void remove() {
|
||||||
|
if (prefs != null) {
|
||||||
|
try {
|
||||||
|
prefs.removePreferenceChangeListener(this);
|
||||||
|
prefs.removeNodeChangeListener(this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Catch all exceptions, this is called during parent finalization which we don't want to prevent...
|
||||||
|
// e.g. IllegalStateException may occur during de-register
|
||||||
|
}
|
||||||
|
prefs = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the Prefs change listener
|
||||||
|
*/
|
||||||
|
private void register(ISerializeInfo info) {
|
||||||
|
if (prefs != null)
|
||||||
|
return;
|
||||||
|
prefs = (IEclipsePreferences)info.getNode();
|
||||||
|
if (prefs != null) {
|
||||||
|
prefs.addPreferenceChangeListener(this);
|
||||||
|
prefs.addNodeChangeListener(this);
|
||||||
|
}
|
||||||
|
prefsChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return & unset flag indicating if there has been a change in the backing store
|
||||||
|
* @return whether there's been a change in the backing store
|
||||||
|
*/
|
||||||
|
public boolean preferencesChanged(ISerializeInfo info) {
|
||||||
|
if (prefs == null)
|
||||||
|
register(info);
|
||||||
|
|
||||||
|
boolean retVal = prefsChanged;
|
||||||
|
// If we're registered for change, then unset
|
||||||
|
if (prefs != null)
|
||||||
|
prefsChanged = false;
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preferenceChange(PreferenceChangeEvent event) {
|
||||||
|
prefsChanged = true;
|
||||||
|
}
|
||||||
|
public void added(NodeChangeEvent event) {
|
||||||
|
prefsChanged = true;
|
||||||
|
}
|
||||||
|
public void removed(NodeChangeEvent event) {
|
||||||
|
prefsChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private PrefListener fPrefsChangedListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The set of variables which have been 'deleted' by the user.
|
||||||
|
* @return the live removed {@link IEnvironmentVariable} map
|
||||||
|
*/
|
||||||
|
private Set<String> getDeletedSet(){
|
||||||
|
if(fDeletedVariables == null)
|
||||||
|
fDeletedVariables = new HashSet<String>();
|
||||||
|
return fDeletedVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*
|
||||||
|
* Creates a new StorableEnvironment from an existing StorableEnvironment. Settings
|
||||||
|
* are copied wholesale from the previous enviornment.
|
||||||
|
*
|
||||||
|
* Note that the previous environment's {@link ISerializeInfo} isn't copied
|
||||||
|
* over, as it's expected this environment's settings will be stored elsewhere
|
||||||
|
*
|
||||||
|
* @param env
|
||||||
|
* @param isReadOnly
|
||||||
|
*/
|
||||||
|
PrefsStorableEnvironment(StorableEnvironment env, ISerializeInfo serializeInfo, boolean isReadOnly) {
|
||||||
|
super(isReadOnly);
|
||||||
|
|
||||||
|
// Copy shared mutable state
|
||||||
|
fAppend = env.fAppend;
|
||||||
|
fAppendContributedEnv = env.fAppendContributedEnv;
|
||||||
|
|
||||||
|
// If base is a PrefsStorableEnv, add other internal data
|
||||||
|
if (env instanceof PrefsStorableEnvironment) {
|
||||||
|
PrefsStorableEnvironment other = (PrefsStorableEnvironment)env;
|
||||||
|
fAppendChanged = other.fAppendChanged;
|
||||||
|
fAppendContributedChanged = other.fAppendContributedChanged;
|
||||||
|
|
||||||
|
// If this environemnt is a *copy* of another environment
|
||||||
|
// then copy over *all* variables into our live variable map
|
||||||
|
if (serializeInfo == null || other.fSerialEnv == null ||
|
||||||
|
!serializeInfo.getPrefName().equals(other.fSerialEnv.getPrefName()))
|
||||||
|
fVariables = env.getAllVariablesMap();
|
||||||
|
else {
|
||||||
|
// Just a runtime copy using existing ISerializeInfo Store, just clone runtime
|
||||||
|
// runtime changed state
|
||||||
|
if (other.fVariables != null)
|
||||||
|
getMap().putAll(other.fVariables);
|
||||||
|
if (other.fDeletedVariables != null)
|
||||||
|
getDeletedSet().addAll(other.fDeletedVariables);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// add all variables
|
||||||
|
if(env.fVariables != null)
|
||||||
|
fVariables = env.getAllVariablesMap();
|
||||||
|
// Assume the append & appendContributed are changed
|
||||||
|
fAppendChanged = true;
|
||||||
|
fAppendContributedChanged = true;
|
||||||
|
}
|
||||||
|
// Set the serializeInfo on this env
|
||||||
|
setSerializeInfo(serializeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a StorableEnvironment backed by this ISerializeInfo.
|
||||||
|
*
|
||||||
|
* This StorabelEnvironment will respond to changes in the backing store
|
||||||
|
*
|
||||||
|
* @param serializeInfo
|
||||||
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
PrefsStorableEnvironment(ISerializeInfo serializeInfo, boolean isReadOnly) {
|
||||||
|
super(isReadOnly);
|
||||||
|
setSerializeInfo(serializeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link ISerializeInfo} which persists this environment
|
||||||
|
* @param serializeInfo
|
||||||
|
*/
|
||||||
|
private void setSerializeInfo(ISerializeInfo serializeInfo) {
|
||||||
|
if (fPrefsChangedListener != null)
|
||||||
|
fPrefsChangedListener.remove();
|
||||||
|
fSerialEnv = serializeInfo;
|
||||||
|
fPrefsChangedListener = new PrefListener(fSerialEnv);
|
||||||
|
|
||||||
|
// Update the cached state
|
||||||
|
checkBackingSerializeInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and update the state of the backing {@link ISerializeInfo} cache
|
||||||
|
* Acts as a reconciler, keeping the environment up to date as it's updated externally
|
||||||
|
*/
|
||||||
|
private void checkBackingSerializeInfo() {
|
||||||
|
// Any change?
|
||||||
|
if (!fPrefsChangedListener.preferencesChanged(fSerialEnv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Preferences topNode = fSerialEnv.getNode();
|
||||||
|
if (topNode == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (topNode.get(fSerialEnv.getPrefName(), "").length() != 0) //$NON-NLS-1$
|
||||||
|
migrateOldStylePrefs();
|
||||||
|
|
||||||
|
// Does our storage node exist?
|
||||||
|
if (topNode.nodeExists(fSerialEnv.getPrefName())) {
|
||||||
|
// Clear the cache
|
||||||
|
fCachedSerialEnv.clear();
|
||||||
|
// new style preferences are stored individually in the node
|
||||||
|
Preferences prefs = topNode.node(fSerialEnv.getPrefName());
|
||||||
|
try {
|
||||||
|
for (String child : prefs.childrenNames()) {
|
||||||
|
String name = getNameForMap(child);
|
||||||
|
IEnvironmentVariable env = new StorableEnvVar(child, prefs.node(child));
|
||||||
|
addVariable(fCachedSerialEnv, env);
|
||||||
|
if (env.equals(getMap().get(name)))
|
||||||
|
getMap().remove(name);
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
// Remove deleted items no longer in the map
|
||||||
|
if (fDeletedVariables != null) {
|
||||||
|
Iterator<String> it = fDeletedVariables.iterator();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
String name = it.next();
|
||||||
|
if (!fCachedSerialEnv.containsKey(name))
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
if (fDeletedVariables.isEmpty())
|
||||||
|
fDeletedVariables = null;
|
||||||
|
}
|
||||||
|
// Update flag variables
|
||||||
|
boolean append = prefs.getBoolean(ATTRIBUTE_APPEND, DEFAULT_APPEND);
|
||||||
|
if (!fAppendChanged || fAppend == append) {
|
||||||
|
fAppend = append;
|
||||||
|
fAppendChanged = false;
|
||||||
|
}
|
||||||
|
append = prefs.getBoolean(ATTRIBUTE_APPEND_CONTRIBUTED, DEFAULT_APPEND);
|
||||||
|
if (!fAppendContributedChanged || fAppendContributedEnv == append) {
|
||||||
|
fAppendContributedEnv = append;
|
||||||
|
fAppendContributedChanged = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
// Unexpected...
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates an old style preference storage.
|
||||||
|
* - Previously preferences were encoded in an ICStorageElement XML string in a text element under key {@link ISerializeInfo#getPrefName()}
|
||||||
|
* in {@link ISerializeInfo#getNode()}
|
||||||
|
* - Now they're stored directly in the preference Node ISerializeInfo#getNode()#node(ISerializeInfo#getPrefName())
|
||||||
|
*/
|
||||||
|
private void migrateOldStylePrefs() {
|
||||||
|
// Fall-back to loading Preferences from the old style encoded XML String
|
||||||
|
// topNode.get(fSerialEnv.getPrefName(), def)
|
||||||
|
String envString = StorableEnvironmentLoader.loadPreferenceNode(fSerialEnv);
|
||||||
|
ICStorageElement element = StorableEnvironmentLoader.environmentStorageFromString(envString);
|
||||||
|
try {
|
||||||
|
if (element != null) {
|
||||||
|
Preferences oldNode = fSerialEnv.getNode();
|
||||||
|
oldNode.put(fSerialEnv.getPrefName(), ""); //$NON-NLS-1$
|
||||||
|
oldNode.flush();
|
||||||
|
|
||||||
|
// New Preferences node
|
||||||
|
Preferences newNode = fSerialEnv.getNode().node(fSerialEnv.getPrefName());
|
||||||
|
StorableEnvironment oldEnv = new StorableEnvironment(element, false);
|
||||||
|
for (Map.Entry<String, IEnvironmentVariable> e : oldEnv.getMap().entrySet())
|
||||||
|
((StorableEnvVar)e.getValue()).serialize(newNode.node(e.getKey()));
|
||||||
|
fCachedSerialEnv.putAll(oldEnv.getMap());
|
||||||
|
if (!fAppendChanged)
|
||||||
|
fAppend = oldEnv.fAppend;
|
||||||
|
newNode.putBoolean(ATTRIBUTE_APPEND, fAppend);
|
||||||
|
if (!fAppendContributedChanged)
|
||||||
|
fAppendContributedEnv = oldEnv.fAppendContributedEnv;
|
||||||
|
newNode.putBoolean(ATTRIBUTE_APPEND_CONTRIBUTED, fAppendContributedEnv);
|
||||||
|
// flush
|
||||||
|
fSerialEnv.getNode().flush();
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize the Storable environment into the ICStorageElement
|
||||||
|
*
|
||||||
|
* NB assumes that any variables part of the ISerializeInfo will continue to be serialized
|
||||||
|
* Use #serialize instead for persisting into the Preference store
|
||||||
|
* @param element
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void serialize(ICStorageElement element){
|
||||||
|
checkBackingSerializeInfo();
|
||||||
|
Map<String, IEnvironmentVariable> map = getAllVariablesMap();
|
||||||
|
|
||||||
|
element.setAttribute(ATTRIBUTE_APPEND, Boolean.valueOf(fAppend).toString());
|
||||||
|
element.setAttribute(ATTRIBUTE_APPEND_CONTRIBUTED, Boolean.valueOf(fAppendContributedEnv).toString());
|
||||||
|
if(!map.isEmpty()){
|
||||||
|
Iterator<IEnvironmentVariable> iter = map.values().iterator();
|
||||||
|
while(iter.hasNext()){
|
||||||
|
StorableEnvVar var = (StorableEnvVar)iter.next();
|
||||||
|
ICStorageElement varEl = element.createChild(StorableEnvVar.VARIABLE_ELEMENT_NAME);
|
||||||
|
var.serialize(varEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize the element into the current Preference node
|
||||||
|
*
|
||||||
|
* At the end of this fCacheSerialEnv represents the state of the world
|
||||||
|
* and the runtime state {@link #fDeletedVariables} && {@link #fVariables}
|
||||||
|
* are empty
|
||||||
|
*/
|
||||||
|
void serialize() {
|
||||||
|
if (!isDirty())
|
||||||
|
return;
|
||||||
|
Preferences element = fSerialEnv.getNode().node(fSerialEnv.getPrefName());
|
||||||
|
element.putBoolean(ATTRIBUTE_APPEND, fAppend);
|
||||||
|
fAppendChanged = false;
|
||||||
|
element.putBoolean(ATTRIBUTE_APPEND_CONTRIBUTED, fAppendContributedEnv);
|
||||||
|
fAppendContributedChanged = false;
|
||||||
|
// Need to remove the delete elements
|
||||||
|
try {
|
||||||
|
if (fDeletedVariables != null) {
|
||||||
|
for (String delete : fDeletedVariables) {
|
||||||
|
element.node(delete).removeNode();
|
||||||
|
fCachedSerialEnv.remove(delete);
|
||||||
|
}
|
||||||
|
fDeletedVariables.clear();
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
// Only need to serialize the 'changed' elements
|
||||||
|
if(fVariables != null) {
|
||||||
|
for (Map.Entry<String, IEnvironmentVariable> e : fVariables.entrySet())
|
||||||
|
((StorableEnvVar)e.getValue()).serialize(element.node(e.getKey()));
|
||||||
|
fCachedSerialEnv.putAll(fVariables);
|
||||||
|
fVariables.clear();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
element.flush();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEnvironmentVariable createVariable(String name, String value, int op, String delimiter){
|
||||||
|
IEnvironmentVariable var = super.createVariable(name, value, op, delimiter);
|
||||||
|
if (var != null) {
|
||||||
|
if (fDeletedVariables != null)
|
||||||
|
fDeletedVariables.remove(getNameForMap(name));
|
||||||
|
// If this variable is identical to one in the map, then no change...
|
||||||
|
if (var.equals(fCachedSerialEnv.get(getNameForMap(name))))
|
||||||
|
getMap().remove(getNameForMap(name));
|
||||||
|
}
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @return the environment variable with the given name, or null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IEnvironmentVariable getVariable(String name){
|
||||||
|
name = getNameForMap(name);
|
||||||
|
IEnvironmentVariable var = super.getVariable(name);
|
||||||
|
if (var != null)
|
||||||
|
return var;
|
||||||
|
|
||||||
|
if (fDeletedVariables != null && fDeletedVariables.contains(name))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
checkBackingSerializeInfo();
|
||||||
|
return fCachedSerialEnv.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return cloned map of all variables set on this storable environment runtime variables + backing store vars
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
Map<String, IEnvironmentVariable> getAllVariablesMap() {
|
||||||
|
checkBackingSerializeInfo();
|
||||||
|
// Get all the environment from the backing store first
|
||||||
|
Map<String, IEnvironmentVariable> vars = new HashMap<String, IEnvironmentVariable>();
|
||||||
|
if (fCachedSerialEnv != null)
|
||||||
|
vars.putAll(fCachedSerialEnv);
|
||||||
|
if (fDeletedVariables != null)
|
||||||
|
for (String name : fDeletedVariables)
|
||||||
|
vars.remove(name);
|
||||||
|
|
||||||
|
// Now overwrite with the live variables set, and return
|
||||||
|
vars.putAll(getMap());
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEnvironmentVariable deleteVariable(String name) {
|
||||||
|
name = getNameForMap(name);
|
||||||
|
IEnvironmentVariable var = super.deleteVariable(name);
|
||||||
|
if (name == null)
|
||||||
|
return null;
|
||||||
|
getDeletedSet().add(name);
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteAll(){
|
||||||
|
boolean change = super.deleteAll();
|
||||||
|
|
||||||
|
// Change should include any cached variables we're overwriting
|
||||||
|
change = change || !getDeletedSet().equals(fCachedSerialEnv.keySet());
|
||||||
|
getDeletedSet().addAll(fCachedSerialEnv.keySet());
|
||||||
|
if (change) {
|
||||||
|
fIsChanged = true;
|
||||||
|
}
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAppendEnvironment(boolean append){
|
||||||
|
boolean prevVal = fAppend;
|
||||||
|
super.setAppendEnvironment(append);
|
||||||
|
if (prevVal != fAppend)
|
||||||
|
fAppendChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAppendContributedEnvironment(boolean append){
|
||||||
|
boolean prevVal = fAppendContributedEnv;
|
||||||
|
super.setAppendContributedEnvironment(append);
|
||||||
|
if (prevVal != fAppendContributedEnv)
|
||||||
|
fAppendContributedChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreDefaults(){
|
||||||
|
super.restoreDefaults();
|
||||||
|
fAppendChanged = false;
|
||||||
|
fAppendContributedChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirty() {
|
||||||
|
return fAppendChanged || fAppendContributedChanged ||
|
||||||
|
(fVariables != null && !fVariables.isEmpty()) ||
|
||||||
|
(fDeletedVariables != null && !fDeletedVariables.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
super.finalize();
|
||||||
|
// Remove the preference change listener when this Storable Environment
|
||||||
|
// is no longer referenced...
|
||||||
|
if (fPrefsChangedListener != null)
|
||||||
|
fPrefsChangedListener.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,24 +1,25 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2007 Intel Corporation and others.
|
* Copyright (c) 2005, 2009 Intel Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Intel Corporation - Initial API and implementation
|
* Intel Corporation - Initial API and implementation
|
||||||
|
* James Blackburn (Broadcom Corp.)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.utils.envvar;
|
package org.eclipse.cdt.utils.envvar;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.envvar.EnvironmentVariable;
|
import org.eclipse.cdt.core.envvar.EnvironmentVariable;
|
||||||
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
||||||
|
import org.osgi.service.prefs.Preferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents the Environment variable that could be loaded
|
* This class represents the Environment variable that could be loaded
|
||||||
* and stored in XML
|
* and stored in XML
|
||||||
*
|
*
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class StorableEnvVar extends EnvironmentVariable {
|
public class StorableEnvVar extends EnvironmentVariable {
|
||||||
public static final String VARIABLE_ELEMENT_NAME = "variable"; //$NON-NLS-1$
|
public static final String VARIABLE_ELEMENT_NAME = "variable"; //$NON-NLS-1$
|
||||||
|
@ -47,12 +48,12 @@ public class StorableEnvVar extends EnvironmentVariable {
|
||||||
public StorableEnvVar(String name, String value, String delimiter){
|
public StorableEnvVar(String name, String value, String delimiter){
|
||||||
this(name,value,ENVVAR_REPLACE,delimiter);
|
this(name,value,ENVVAR_REPLACE,delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the environment variable from the ICStorageElement
|
||||||
|
* @param element
|
||||||
|
*/
|
||||||
public StorableEnvVar(ICStorageElement element){
|
public StorableEnvVar(ICStorageElement element){
|
||||||
load(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load(ICStorageElement element){
|
|
||||||
fName = element.getAttribute(NAME);
|
fName = element.getAttribute(NAME);
|
||||||
|
|
||||||
fValue = element.getAttribute(VALUE);
|
fValue = element.getAttribute(VALUE);
|
||||||
|
@ -63,6 +64,20 @@ public class StorableEnvVar extends EnvironmentVariable {
|
||||||
if("".equals(fDelimiter)) //$NON-NLS-1$
|
if("".equals(fDelimiter)) //$NON-NLS-1$
|
||||||
fDelimiter = null;
|
fDelimiter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the Environment Variable directly from a Preference element
|
||||||
|
* @param name
|
||||||
|
* @param element
|
||||||
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
public StorableEnvVar(String name, Preferences element){
|
||||||
|
fName = name;
|
||||||
|
fValue = element.get(VALUE, null);
|
||||||
|
fOperation = opStringToInt(element.get(OPERATION, null));
|
||||||
|
fDelimiter = element.get(DELIMITER, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private int opStringToInt(String op){
|
private int opStringToInt(String op){
|
||||||
int operation;
|
int operation;
|
||||||
|
@ -106,4 +121,20 @@ public class StorableEnvVar extends EnvironmentVariable {
|
||||||
if(fDelimiter != null)
|
if(fDelimiter != null)
|
||||||
element.setAttribute(DELIMITER,fDelimiter);
|
element.setAttribute(DELIMITER,fDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize this Preference straight into the Preferences element.
|
||||||
|
* It's assumed that the Preference node represents this StorableEnvVar's name
|
||||||
|
* @param element
|
||||||
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
public void serialize(Preferences element) {
|
||||||
|
if(fValue != null)
|
||||||
|
element.put(VALUE, fValue);
|
||||||
|
|
||||||
|
element.put(OPERATION, opIntToString(fOperation));
|
||||||
|
|
||||||
|
if(fDelimiter != null)
|
||||||
|
element.put(DELIMITER, fDelimiter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
|
|
||||||
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
||||||
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
|
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
|
||||||
import org.eclipse.cdt.internal.core.settings.model.ExceptionFactory;
|
import org.eclipse.cdt.internal.core.settings.model.ExceptionFactory;
|
||||||
|
@ -28,136 +27,81 @@ import org.eclipse.cdt.utils.envvar.StorableEnvironmentLoader.ISerializeInfo;
|
||||||
*
|
*
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class StorableEnvironment /*implements Cloneable*/{
|
public class StorableEnvironment {
|
||||||
public static final String ENVIRONMENT_ELEMENT_NAME = "environment"; //$NON-NLS-1$
|
public static final String ENVIRONMENT_ELEMENT_NAME = "environment"; //$NON-NLS-1$
|
||||||
private static final String ATTRIBUTE_APPEND = "append"; //$NON-NLS-1$
|
static final String ATTRIBUTE_APPEND = "append"; //$NON-NLS-1$
|
||||||
private static final String ATTRIBUTE_APPEND_CONTRIBUTED = "appendContributed"; //$NON-NLS-1$
|
static final String ATTRIBUTE_APPEND_CONTRIBUTED = "appendContributed"; //$NON-NLS-1$
|
||||||
private static final boolean DEFAULT_APPEND = true;
|
static final boolean DEFAULT_APPEND = true;
|
||||||
/** The map of in-flight environment variables */
|
/** The map of in-flight environment variables */
|
||||||
private HashMap<String, IEnvironmentVariable> fVariables;
|
Map<String, IEnvironmentVariable> fVariables;
|
||||||
/** Map of 'deleted' variables (which shouldn't be updated by a backing store change) */
|
|
||||||
private HashMap<String, IEnvironmentVariable> fDeletedVariables;
|
|
||||||
private boolean fIsDirty = false;
|
private boolean fIsDirty = false;
|
||||||
private boolean fIsChanged = false;
|
boolean fIsChanged = false;
|
||||||
private final boolean fIsReadOnly;
|
final boolean fIsReadOnly;
|
||||||
private boolean fAppend = DEFAULT_APPEND;
|
boolean fAppend = DEFAULT_APPEND;
|
||||||
private boolean fAppendContributedEnv = DEFAULT_APPEND;
|
boolean fAppendContributedEnv = DEFAULT_APPEND;
|
||||||
|
|
||||||
|
|
||||||
// State to manage and handle external changes to the environment
|
|
||||||
|
|
||||||
/** A cache copy of the environment as stored in the {@link ISerializeInfo}
|
|
||||||
* used to work-out whether the cachedStorableEnvironment map needs refreshing */
|
|
||||||
private String fCachedSerialEnvString;
|
|
||||||
/** Map of Environment as loaded from the {@link ISerializeInfo} */
|
|
||||||
private HashMap<String, IEnvironmentVariable> fCachedSerialEnv;
|
|
||||||
private ISerializeInfo fSerialEnv;
|
|
||||||
// State to track whether API users have changed these boolean values
|
|
||||||
private boolean fAppendChanged = false;
|
|
||||||
private boolean fAppendContributedChanged = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the live {@link IEnvironmentVariable} map
|
* @return the live {@link IEnvironmentVariable} map
|
||||||
*/
|
*/
|
||||||
private Map<String, IEnvironmentVariable> getMap(){
|
Map<String, IEnvironmentVariable> getMap(){
|
||||||
if(fVariables == null)
|
if(fVariables == null)
|
||||||
fVariables = new HashMap<String, IEnvironmentVariable>();
|
fVariables = new HashMap<String, IEnvironmentVariable>();
|
||||||
return fVariables;
|
return fVariables;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @return the live removed {@link IEnvironmentVariable} map
|
|
||||||
*/
|
|
||||||
private Map<String, IEnvironmentVariable> getDeletedMap(){
|
|
||||||
if(fDeletedVariables == null)
|
|
||||||
fDeletedVariables = new HashMap<String, IEnvironmentVariable>();
|
|
||||||
return fDeletedVariables;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param variables
|
||||||
|
* @param isReadOnly
|
||||||
|
*/
|
||||||
public StorableEnvironment(IEnvironmentVariable variables[], boolean isReadOnly) {
|
public StorableEnvironment(IEnvironmentVariable variables[], boolean isReadOnly) {
|
||||||
setVariales(variables);
|
setVariales(variables);
|
||||||
fIsReadOnly = isReadOnly;
|
fIsReadOnly = isReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new empty StorableEnvironment
|
||||||
|
* @param isReadOnly
|
||||||
|
*/
|
||||||
public StorableEnvironment(boolean isReadOnly) {
|
public StorableEnvironment(boolean isReadOnly) {
|
||||||
fIsReadOnly = isReadOnly;
|
fIsReadOnly = isReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*
|
||||||
|
* Creates a new StorableEnvironment from an existing StorableEnvironment. Settings
|
||||||
|
* are copied wholesale from the previous enviornment.
|
||||||
|
*
|
||||||
|
* Note that the previous environment's {@link ISerializeInfo} isn't copied
|
||||||
|
* over, as it's expected this environment's settings will be stored elsewhere
|
||||||
|
*
|
||||||
|
* @param env
|
||||||
|
* @param isReadOnly
|
||||||
|
*/
|
||||||
public StorableEnvironment(StorableEnvironment env, boolean isReadOnly) {
|
public StorableEnvironment(StorableEnvironment env, boolean isReadOnly) {
|
||||||
if(env.fVariables != null) {
|
if(env.fVariables != null)
|
||||||
@SuppressWarnings("unchecked")
|
fVariables = env.getAllVariablesMap();
|
||||||
final HashMap<String, IEnvironmentVariable> clone = (HashMap<String, IEnvironmentVariable>)env.fVariables.clone();
|
|
||||||
fVariables = clone;
|
|
||||||
}
|
|
||||||
if(env.fDeletedVariables != null) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final HashMap<String, IEnvironmentVariable> clone = (HashMap<String, IEnvironmentVariable>)env.fDeletedVariables.clone();
|
|
||||||
fDeletedVariables = clone;
|
|
||||||
}
|
|
||||||
fSerialEnv = env.fSerialEnv;
|
|
||||||
fAppend = env.fAppend;
|
fAppend = env.fAppend;
|
||||||
fAppendChanged = env.fAppendChanged;
|
|
||||||
fAppendContributedEnv = env.fAppendContributedEnv;
|
fAppendContributedEnv = env.fAppendContributedEnv;
|
||||||
fAppendContributedChanged = env.fAppendContributedChanged;
|
|
||||||
fIsReadOnly = isReadOnly;
|
fIsReadOnly = isReadOnly;
|
||||||
fIsDirty = env.isDirty();
|
fIsDirty = env.isDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the StorableEnvironment from an ICStorageElement tree
|
||||||
|
* @param element
|
||||||
|
* @param isReadOnly
|
||||||
|
*/
|
||||||
public StorableEnvironment(ICStorageElement element, boolean isReadOnly) {
|
public StorableEnvironment(ICStorageElement element, boolean isReadOnly) {
|
||||||
load(element);
|
load(element);
|
||||||
fIsReadOnly = isReadOnly;
|
fIsReadOnly = isReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a StorableEnvironment backed by this ISerializeInfo.
|
* Load the preferences from an {@link ICStorageElement}
|
||||||
*
|
* @param element
|
||||||
* @param serializeInfo
|
|
||||||
* @since 5.2
|
|
||||||
*/
|
*/
|
||||||
StorableEnvironment(ISerializeInfo serializeInfo, boolean isReadOnly) {
|
|
||||||
fIsReadOnly = isReadOnly;
|
|
||||||
fSerialEnv = serializeInfo;
|
|
||||||
|
|
||||||
// Update the cached state
|
|
||||||
checkBackingSerializeInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check and update the state of the backing {@link ISerializeInfo} cache
|
|
||||||
*/
|
|
||||||
private void checkBackingSerializeInfo() {
|
|
||||||
String envString = StorableEnvironmentLoader.loadPreferenceNode(fSerialEnv);
|
|
||||||
|
|
||||||
// Has anything changed?
|
|
||||||
if (envString == null || envString.equals(fCachedSerialEnvString))
|
|
||||||
return;
|
|
||||||
fCachedSerialEnvString = envString;
|
|
||||||
|
|
||||||
ICStorageElement element = StorableEnvironmentLoader.environmentStorageFromString(fCachedSerialEnvString);
|
|
||||||
if (element == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Now update the cached environment
|
|
||||||
if (fCachedSerialEnv == null)
|
|
||||||
fCachedSerialEnv = new HashMap<String, IEnvironmentVariable>();
|
|
||||||
else
|
|
||||||
fCachedSerialEnv.clear();
|
|
||||||
|
|
||||||
for (ICStorageElement child : element.getChildren())
|
|
||||||
if (child.getName().equals(StorableEnvVar.VARIABLE_ELEMENT_NAME))
|
|
||||||
addVariable(fCachedSerialEnv, new StorableEnvVar(child));
|
|
||||||
|
|
||||||
// If user hasn't changed fAppend or fAppend Contributed, then update
|
|
||||||
if (!fAppendChanged) {
|
|
||||||
String append = element.getAttribute(ATTRIBUTE_APPEND);
|
|
||||||
fAppend = append != null ? Boolean.valueOf(append).booleanValue() : DEFAULT_APPEND;
|
|
||||||
}
|
|
||||||
if (!fAppendContributedChanged) {
|
|
||||||
String append = element.getAttribute(ATTRIBUTE_APPEND_CONTRIBUTED);
|
|
||||||
fAppendContributedEnv = append != null ? Boolean.valueOf(append).booleanValue() : DEFAULT_APPEND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load(ICStorageElement element){
|
private void load(ICStorageElement element){
|
||||||
ICStorageElement children[] = element.getChildren();
|
ICStorageElement children[] = element.getChildren();
|
||||||
for (int i = 0; i < children.length; ++i) {
|
for (int i = 0; i < children.length; ++i) {
|
||||||
|
@ -186,22 +130,10 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
* @param element
|
* @param element
|
||||||
*/
|
*/
|
||||||
public void serialize(ICStorageElement element){
|
public void serialize(ICStorageElement element){
|
||||||
checkBackingSerializeInfo();
|
|
||||||
Map<String, IEnvironmentVariable> map = new HashMap<String, IEnvironmentVariable>();
|
|
||||||
if (fCachedSerialEnv != null)
|
|
||||||
map.putAll(fCachedSerialEnv);
|
|
||||||
if (fDeletedVariables != null) {
|
|
||||||
for (String rem : fDeletedVariables.keySet())
|
|
||||||
map.remove(rem);
|
|
||||||
fDeletedVariables.clear();
|
|
||||||
}
|
|
||||||
if (fVariables != null)
|
|
||||||
map.putAll(fVariables);
|
|
||||||
|
|
||||||
element.setAttribute(ATTRIBUTE_APPEND, Boolean.valueOf(fAppend).toString());
|
element.setAttribute(ATTRIBUTE_APPEND, Boolean.valueOf(fAppend).toString());
|
||||||
element.setAttribute(ATTRIBUTE_APPEND_CONTRIBUTED, Boolean.valueOf(fAppendContributedEnv).toString());
|
element.setAttribute(ATTRIBUTE_APPEND_CONTRIBUTED, Boolean.valueOf(fAppendContributedEnv).toString());
|
||||||
if(!map.isEmpty()){
|
if(fVariables != null){
|
||||||
Iterator<IEnvironmentVariable> iter = map.values().iterator();
|
Iterator<IEnvironmentVariable> iter = fVariables.values().iterator();
|
||||||
while(iter.hasNext()){
|
while(iter.hasNext()){
|
||||||
StorableEnvVar var = (StorableEnvVar)iter.next();
|
StorableEnvVar var = (StorableEnvVar)iter.next();
|
||||||
ICStorageElement varEl = element.createChild(StorableEnvVar.VARIABLE_ELEMENT_NAME);
|
ICStorageElement varEl = element.createChild(StorableEnvVar.VARIABLE_ELEMENT_NAME);
|
||||||
|
@ -217,14 +149,10 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
* @param map
|
* @param map
|
||||||
* @param var
|
* @param var
|
||||||
*/
|
*/
|
||||||
private void addVariable(Map<String, IEnvironmentVariable> map, IEnvironmentVariable var){
|
void addVariable(Map<String, IEnvironmentVariable> map, IEnvironmentVariable var){
|
||||||
String name = var.getName();
|
String name = getNameForMap(var.getName());
|
||||||
if(name == null)
|
if (name == null)
|
||||||
return;
|
return;
|
||||||
IEnvironmentVariableManager provider = EnvironmentVariableManager.getDefault();
|
|
||||||
if(!provider.isVariableCaseSensitive())
|
|
||||||
name = name.toUpperCase();
|
|
||||||
|
|
||||||
map.put(name,var);
|
map.put(name,var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,9 +167,6 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
if(var == null){
|
if(var == null){
|
||||||
var = new StorableEnvVar(name, value, op, delimiter);
|
var = new StorableEnvVar(name, value, op, delimiter);
|
||||||
addVariable(getMap(), var);
|
addVariable(getMap(), var);
|
||||||
// Variable added, ensure it's not in the removed set
|
|
||||||
if (fDeletedVariables != null)
|
|
||||||
fDeletedVariables.remove(EnvironmentVariableManager.getDefault().isVariableCaseSensitive() ? name : name.toUpperCase());
|
|
||||||
fIsDirty = true;
|
fIsDirty = true;
|
||||||
fIsChanged = true;
|
fIsChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -327,23 +252,10 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
* @return the environment variable with the given name, or null
|
* @return the environment variable with the given name, or null
|
||||||
*/
|
*/
|
||||||
public IEnvironmentVariable getVariable(String name){
|
public IEnvironmentVariable getVariable(String name){
|
||||||
if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$
|
name = getNameForMap(name);
|
||||||
|
if (name == null)
|
||||||
return null;
|
return null;
|
||||||
IEnvironmentVariableManager provider = EnvironmentVariableManager.getDefault();
|
return getMap().get(name);
|
||||||
if(!provider.isVariableCaseSensitive())
|
|
||||||
name = name.toUpperCase();
|
|
||||||
|
|
||||||
IEnvironmentVariable var = getMap().get(name);
|
|
||||||
if (var != null)
|
|
||||||
return var;
|
|
||||||
|
|
||||||
if (fDeletedVariables != null && fDeletedVariables.containsKey(name))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
checkBackingSerializeInfo();
|
|
||||||
if (fCachedSerialEnv != null)
|
|
||||||
return fCachedSerialEnv.get(name);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -383,33 +295,44 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
vars[i].getDelimiter());
|
vars[i].getDelimiter());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnvironmentVariable[] getVariables(){
|
/**
|
||||||
checkBackingSerializeInfo();
|
* @return cloned map of all variables set on this storable environment runtime variables + backing store vars
|
||||||
// Get all the environment from the backing store first
|
*/
|
||||||
|
Map<String, IEnvironmentVariable> getAllVariablesMap() {
|
||||||
Map<String, IEnvironmentVariable> vars = new HashMap<String, IEnvironmentVariable>();
|
Map<String, IEnvironmentVariable> vars = new HashMap<String, IEnvironmentVariable>();
|
||||||
if (fCachedSerialEnv != null)
|
|
||||||
vars.putAll(fCachedSerialEnv);
|
|
||||||
if (fDeletedVariables != null)
|
|
||||||
for (String name : fDeletedVariables.keySet())
|
|
||||||
vars.remove(name);
|
|
||||||
|
|
||||||
// Now overwrite with the live variables set, and return
|
|
||||||
vars.putAll(getMap());
|
vars.putAll(getMap());
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnvironmentVariable[] getVariables(){
|
||||||
|
Map<String, IEnvironmentVariable> vars = getAllVariablesMap();
|
||||||
return vars.values().toArray(new IEnvironmentVariable[vars.size()]);
|
return vars.values().toArray(new IEnvironmentVariable[vars.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique canonical form of the variable name for storage in the Maps.
|
||||||
|
*
|
||||||
|
* The name will be trimmed, and, if the var manager isn't case sensitive, made upper case
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @return canonical name, or null
|
||||||
|
*/
|
||||||
|
String getNameForMap(String name) {
|
||||||
|
if (name == null || (name = name.trim()).length() == 0)
|
||||||
|
return null;
|
||||||
|
if (!EnvironmentVariableManager.getDefault().isVariableCaseSensitive())
|
||||||
|
return name.toUpperCase();
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public IEnvironmentVariable deleteVariable(String name){
|
public IEnvironmentVariable deleteVariable(String name){
|
||||||
if(fIsReadOnly)
|
if(fIsReadOnly)
|
||||||
throw ExceptionFactory.createIsReadOnlyException();
|
throw ExceptionFactory.createIsReadOnlyException();
|
||||||
if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$
|
name = getNameForMap(name);
|
||||||
|
if(name == null)
|
||||||
return null;
|
return null;
|
||||||
IEnvironmentVariableManager provider = EnvironmentVariableManager.getDefault();
|
|
||||||
if(!provider.isVariableCaseSensitive())
|
|
||||||
name = name.toUpperCase();
|
|
||||||
|
|
||||||
IEnvironmentVariable var = getMap().remove(name);
|
IEnvironmentVariable var = getMap().remove(name);
|
||||||
getDeletedMap().put(name, var);
|
|
||||||
if(var != null){
|
if(var != null){
|
||||||
fIsDirty = true;
|
fIsDirty = true;
|
||||||
fIsChanged = true;
|
fIsChanged = true;
|
||||||
|
@ -422,10 +345,9 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
if(fIsReadOnly)
|
if(fIsReadOnly)
|
||||||
throw ExceptionFactory.createIsReadOnlyException();
|
throw ExceptionFactory.createIsReadOnlyException();
|
||||||
Map<String, IEnvironmentVariable> map = getMap();
|
Map<String, IEnvironmentVariable> map = getMap();
|
||||||
if(map.size() > 0){
|
if(map.size() > 0) {
|
||||||
fIsDirty = true;
|
fIsDirty = true;
|
||||||
fIsChanged = true;
|
fIsChanged = true;
|
||||||
getDeletedMap().putAll(map);
|
|
||||||
map.clear();
|
map.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -449,7 +371,6 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
throw ExceptionFactory.createIsReadOnlyException();
|
throw ExceptionFactory.createIsReadOnlyException();
|
||||||
|
|
||||||
fAppend = append;
|
fAppend = append;
|
||||||
fAppendChanged = true;
|
|
||||||
fIsDirty = true;
|
fIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +386,6 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
throw ExceptionFactory.createIsReadOnlyException();
|
throw ExceptionFactory.createIsReadOnlyException();
|
||||||
|
|
||||||
fAppendContributedEnv = append;
|
fAppendContributedEnv = append;
|
||||||
fAppendContributedChanged = true;
|
|
||||||
fIsDirty = true;
|
fIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,13 +395,4 @@ public class StorableEnvironment /*implements Cloneable*/{
|
||||||
fAppendContributedEnv = DEFAULT_APPEND;
|
fAppendContributedEnv = DEFAULT_APPEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public Object clone(){
|
|
||||||
try {
|
|
||||||
StorableEnvironment env = (StorableEnvironment)super.clone();
|
|
||||||
env.fVariables = (HashMap)fVariables.clone();
|
|
||||||
} catch (CloneNotSupportedException e) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.internal.core.settings.model.xml.XmlStorageElement;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
import org.osgi.service.prefs.BackingStoreException;
|
import org.osgi.service.prefs.BackingStoreException;
|
||||||
import org.osgi.service.prefs.Preferences;
|
import org.osgi.service.prefs.Preferences;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
@ -45,7 +46,6 @@ import org.xml.sax.SAXException;
|
||||||
* storing and loading environment variable settings from eclipse properties
|
* storing and loading environment variable settings from eclipse properties
|
||||||
*
|
*
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract class StorableEnvironmentLoader {
|
public abstract class StorableEnvironmentLoader {
|
||||||
|
|
||||||
|
@ -56,17 +56,34 @@ public abstract class StorableEnvironmentLoader {
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface ISerializeInfo{
|
public interface ISerializeInfo{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* {@link IEclipsePreferences} root node in the Preference store
|
||||||
* @return the Preferences Node into which environment should be (de) serialized
|
* @return the Preferences Node into which environment should be (de) serialized
|
||||||
*/
|
*/
|
||||||
Preferences getNode();
|
Preferences getNode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Name in the preference store
|
||||||
* @return the key in the preference node to use for loading preferences
|
* @return the key in the preference node to use for loading preferences
|
||||||
*/
|
*/
|
||||||
String getPrefName();
|
String getPrefName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the StorableEnvironment clone for a new configuration, say,
|
||||||
|
* based on an existing configuration
|
||||||
|
*
|
||||||
|
* @param context the configuration / workspace context the configuration is to be cloned for
|
||||||
|
* @param base the base environment to copy
|
||||||
|
* @return a StorableEnvironment clone of the configuration's environment
|
||||||
|
* @since 5.2
|
||||||
|
*/
|
||||||
|
public StorableEnvironment cloneEnvironmentWithContext(Object context, StorableEnvironment base, boolean isReadOnly) {
|
||||||
|
PrefsStorableEnvironment env = new PrefsStorableEnvironment(base, getSerializeInfo(context), isReadOnly);
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this method should return the ISerializeInfo representing the information
|
* this method should return the ISerializeInfo representing the information
|
||||||
* of where the variable should be stored and loaded
|
* of where the variable should be stored and loaded
|
||||||
|
@ -85,12 +102,12 @@ public abstract class StorableEnvironmentLoader {
|
||||||
* @param readOnly
|
* @param readOnly
|
||||||
* @return StorableEnvironment
|
* @return StorableEnvironment
|
||||||
*/
|
*/
|
||||||
protected StorableEnvironment loadEnvironment(Object context, boolean readOnly){
|
protected StorableEnvironment loadEnvironment(Object context, boolean readOnly) {
|
||||||
ISerializeInfo serializeInfo = getSerializeInfo(context);
|
ISerializeInfo serializeInfo = getSerializeInfo(context);
|
||||||
if(serializeInfo == null)
|
if(serializeInfo == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new StorableEnvironment(serializeInfo, readOnly);
|
return new PrefsStorableEnvironment(serializeInfo, readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -103,13 +120,18 @@ public abstract class StorableEnvironmentLoader {
|
||||||
ISerializeInfo serializeInfo = getSerializeInfo(context);
|
ISerializeInfo serializeInfo = getSerializeInfo(context);
|
||||||
if(serializeInfo == null)
|
if(serializeInfo == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ByteArrayOutputStream stream = storeEnvironmentToStream(env);
|
if (env instanceof PrefsStorableEnvironment) {
|
||||||
if(stream == null)
|
((PrefsStorableEnvironment)env).serialize();
|
||||||
return;
|
} else {
|
||||||
storeOutputStream(stream,serializeInfo.getNode(), serializeInfo.getPrefName(), flush);
|
// Backwards compatibility
|
||||||
|
ByteArrayOutputStream stream = storeEnvironmentToStream(env);
|
||||||
env.setDirty(false);
|
if(stream == null)
|
||||||
|
return;
|
||||||
|
storeOutputStream(stream,serializeInfo.getNode(), serializeInfo.getPrefName(), flush);
|
||||||
|
|
||||||
|
env.setDirty(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,6 +211,7 @@ public abstract class StorableEnvironmentLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Preferences can be encoded as a single long ICStorageElement String
|
||||||
* @return String value stored in the node or null if no such value exists.
|
* @return String value stored in the node or null if no such value exists.
|
||||||
*/
|
*/
|
||||||
static String loadPreferenceNode(ISerializeInfo serializeInfo) {
|
static String loadPreferenceNode(ISerializeInfo serializeInfo) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue