diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/envvar/IEnvironmentVariableManagerTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/envvar/IEnvironmentVariableManagerTests.java index fd7535bf5e1..de9e26f3fcf 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/envvar/IEnvironmentVariableManagerTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/envvar/IEnvironmentVariableManagerTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Broadcom Corp. and others. + * Copyright (c) 2009, 2013 Broadcom Corp. 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 @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.envvar; import java.io.ByteArrayInputStream; +import java.util.Arrays; import junit.framework.Test; import junit.framework.TestCase; @@ -22,6 +23,9 @@ import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.core.testplugin.ResourceHelper; +import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; +import org.eclipse.cdt.utils.envvar.IEnvironmentChangeEvent; +import org.eclipse.cdt.utils.envvar.IEnvironmentChangeListener; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; @@ -31,6 +35,29 @@ import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; public class IEnvironmentVariableManagerTests extends TestCase { + /** + * Mock listener to listen to environment variable change events. + */ + private class MockEnvironmentListener implements IEnvironmentChangeListener { + private int count = 0; + private IEnvironmentChangeEvent lastEvent = null; + + public int getCount() { + return count; + } + public void resetCount() { + count = 0; + lastEvent = null; + } + public IEnvironmentChangeEvent getLastEvent() { + return lastEvent; + } + @Override + public void handleEvent(IEnvironmentChangeEvent event) { + count++; + lastEvent = event; + } + } @Override protected void setUp() throws Exception { @@ -639,4 +666,88 @@ public class IEnvironmentVariableManagerTests extends TestCase { assertEquals(varInvalidListValue,varInvalidList.getValue()); } + /** + * Test case to test environment variable change notifications + * + * @throws Exception + */ + public void testEnvironmentChangeListener() throws Exception { + // Register environment event listener + MockEnvironmentListener envListener = new MockEnvironmentListener(); + EnvironmentVariableManager.fUserSupplier.registerEnvironmentChangeListener(envListener); + assertEquals(0, envListener.getCount()); + + // Define sample environment variable name + String variableName = "VAR"; + + // Test adding a variable + IEnvironmentVariable[] varsAdded = { new EnvironmentVariable(variableName, "value") }; + { + // Reset the listener + envListener.resetCount(); + assertEquals(0, envListener.getCount()); + + // Add environment variable + EnvironmentVariableManager.fUserSupplier.setVariables(varsAdded, null); + EnvironmentVariableManager.fUserSupplier.storeWorkspaceEnvironment(true); + + // Doublecheck that variable added + IEnvironmentVariable[] actualVars = EnvironmentVariableManager.fUserSupplier.getVariables(null); + assertTrue(((Arrays.equals(varsAdded, actualVars)))); + + // Check event received by the listener + assertEquals(1, envListener.getCount()); + IEnvironmentChangeEvent event = envListener.getLastEvent(); + assertTrue(Arrays.equals(new IEnvironmentVariable[0], event.getOldVariables())); + assertTrue(Arrays.equals(varsAdded, event.getNewVariables())); + } + + // Test changing a variable + IEnvironmentVariable[] varsChanged = { new EnvironmentVariable(variableName, "value-changed") }; + { + // Reset the listener + envListener.resetCount(); + assertEquals(0, envListener.getCount()); + + // Add environment variable + EnvironmentVariableManager.fUserSupplier.setVariables(varsChanged, null); + EnvironmentVariableManager.fUserSupplier.storeWorkspaceEnvironment(true); + + // Doublecheck that variable added + IEnvironmentVariable[] actualVars = EnvironmentVariableManager.fUserSupplier.getVariables(null); + assertTrue(Arrays.equals(varsChanged, actualVars)); + + // Check event received by the listener + assertEquals(1, envListener.getCount()); + IEnvironmentChangeEvent event = envListener.getLastEvent(); + assertTrue(Arrays.equals(varsAdded, event.getOldVariables())); + assertTrue(Arrays.equals(varsChanged, event.getNewVariables())); + } + + // Test removing a variable + IEnvironmentVariable[] varsRemoved = {}; + { + // Reset the listener + envListener.resetCount(); + assertEquals(0, envListener.getCount()); + + // Add environment variable + EnvironmentVariableManager.fUserSupplier.setVariables(varsRemoved, null); + EnvironmentVariableManager.fUserSupplier.storeWorkspaceEnvironment(true); + + // Doublecheck that variable added + IEnvironmentVariable[] actualVars = EnvironmentVariableManager.fUserSupplier.getVariables(null); + assertTrue(Arrays.equals(varsRemoved, actualVars)); + + // Check event received by the listener + assertEquals(1, envListener.getCount()); + IEnvironmentChangeEvent event = envListener.getLastEvent(); + assertTrue(Arrays.equals(varsChanged, event.getOldVariables())); + assertTrue(Arrays.equals(varsRemoved, event.getNewVariables())); + } + + // Release environment event listener + EnvironmentVariableManager.fUserSupplier.unregisterEnvironmentChangeListener(envListener); + } + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/EnvironmentChangeEvent.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/EnvironmentChangeEvent.java index bb4dc6e1356..9592954a972 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/EnvironmentChangeEvent.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/EnvironmentChangeEvent.java @@ -1,37 +1,47 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 Intel Corporation and others. + * Copyright (c) 2005, 2013 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Intel Corporation - Initial API and implementation + * Intel Corporation - Initial API and implementation + * Andrew Gvozdev - Implementation of notification mechanism including changes to this API *******************************************************************************/ package org.eclipse.cdt.internal.core.envvar; +import java.util.Collection; + import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.utils.envvar.IEnvironmentChangeEvent; -public class EnvironmentChangeEvent { - private static final IEnvironmentVariable[] EMPTY_VAR_ARRAY = new IEnvironmentVariable[0]; - - private IEnvironmentVariable[] fAddedVars, fRemovedVars, fChangedVars; - - EnvironmentChangeEvent(IEnvironmentVariable[] addedVars, IEnvironmentVariable[] removedVars, IEnvironmentVariable[] changedVars){ - fAddedVars = addedVars != null ? (IEnvironmentVariable[])addedVars.clone() : null; - fRemovedVars = removedVars != null ? (IEnvironmentVariable[])removedVars.clone() : null; - fChangedVars = changedVars != null ? (IEnvironmentVariable[])changedVars.clone() : null; - } - public IEnvironmentVariable[] getAddedVariables(){ - return fAddedVars != null ? (IEnvironmentVariable[])fAddedVars.clone() : EMPTY_VAR_ARRAY; +/** + * Concrete implementation of event describing changes to environment variables defined by user + * on CDT Environment page in Preferences. + */ +public class EnvironmentChangeEvent implements IEnvironmentChangeEvent { + private IEnvironmentVariable[] oldVariables; + private IEnvironmentVariable[] newVariables; + + /** + * Constructor. + * + * @param oldVars - set of environment variables before the change. + * @param newVars - set of environment variables after the change. + */ + public EnvironmentChangeEvent(Collection oldVars, Collection newVars) { + oldVariables = oldVars.toArray(new IEnvironmentVariable[oldVars.size()]); + newVariables = newVars.toArray(new IEnvironmentVariable[newVars.size()]); } - public IEnvironmentVariable[] getRemovedVariables(){ - return fRemovedVars != null ? (IEnvironmentVariable[])fRemovedVars.clone() : EMPTY_VAR_ARRAY; + @Override + public IEnvironmentVariable[] getOldVariables() { + return oldVariables; } - public IEnvironmentVariable[] getChangedVariables(){ - return fChangedVars != null ? (IEnvironmentVariable[])fChangedVars.clone() : EMPTY_VAR_ARRAY; + @Override + public IEnvironmentVariable[] getNewVariables() { + return newVariables; } - } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/UserDefinedEnvironmentSupplier.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/UserDefinedEnvironmentSupplier.java index ae89d9ef715..b1ff1d23024 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/UserDefinedEnvironmentSupplier.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/envvar/UserDefinedEnvironmentSupplier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 Intel Corporation and others. + * Copyright (c) 2005, 2013 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,23 +9,23 @@ * Intel Corporation - Initial API and implementation * James Blackburn (Broadcom Corp.) * IBM Corporation + * Andrew Gvozdev - Notification mechanism for changes to environment variables *******************************************************************************/ package org.eclipse.cdt.internal.core.envvar; +import java.util.Arrays; 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.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; -import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.internal.core.settings.model.CConfigurationSpecSettings; import org.eclipse.cdt.internal.core.settings.model.IInternalCCfgInfo; import org.eclipse.cdt.utils.envvar.EnvVarOperationProcessor; +import org.eclipse.cdt.utils.envvar.IEnvironmentChangeListener; +import org.eclipse.cdt.utils.envvar.PrefsStorableEnvironment; import org.eclipse.cdt.utils.envvar.StorableEnvironment; import org.eclipse.cdt.utils.envvar.StorableEnvironmentLoader; import org.eclipse.core.resources.IProject; @@ -52,114 +52,26 @@ import org.osgi.service.prefs.Preferences; * * @since 3.0 */ -public class UserDefinedEnvironmentSupplier extends - StorableEnvironmentLoader - implements ICoreEnvironmentVariableSupplier{ - +public class UserDefinedEnvironmentSupplier extends StorableEnvironmentLoader implements ICoreEnvironmentVariableSupplier { public static final String NODENAME = "environment"; //$NON-NLS-1$ public static final String PREFNAME_WORKSPACE = "workspace"; //$NON-NLS-1$ public static final String PREFNAME_PROJECT = "project"; //$NON-NLS-1$ public static final String NODENAME_CFG = "project"; //$NON-NLS-1$ -/* private static final String fNonOverloadableVariables[] = new String[]{ - //users not allowed currently to override the "CWD" and "PWD" variables - EnvVarOperationProcessor.normalizeName("CWD"), //$NON-NLS-1$ - EnvVarOperationProcessor.normalizeName("PWD") //$NON-NLS-1$ - }; -*/ - private StorableEnvironment fWorkspaceVariables; + private PrefsStorableEnvironment fWorkspaceVariables; private StorableEnvironment fOverrideVariables = new StorableEnvironment(false); - static class VarKey { - private IEnvironmentVariable fVar; - private boolean fNameOnly; - private int fCode; - - VarKey(IEnvironmentVariable var, boolean nameOnly) { - fVar = var; - fNameOnly = nameOnly; - } - - public IEnvironmentVariable getVariable() { - return fVar; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - - if (!(obj instanceof VarKey)) - return false; - - VarKey other = (VarKey)obj; - - IEnvironmentVariable otherVar = other.fVar; - - if (fVar == otherVar) - return true; - - if (!CDataUtil.objectsEqual(fVar.getName(), otherVar.getName())) - return false; - - if (fNameOnly) - return true; - - if (fVar.getOperation() != otherVar.getOperation()) - return false; - - if (!CDataUtil.objectsEqual(fVar.getValue(), otherVar.getValue())) - return false; - - if (!CDataUtil.objectsEqual(fVar.getDelimiter(),otherVar.getDelimiter())) - return false; - - return true; - } - - @Override - public int hashCode() { - int code = fCode; - if (code == 0) { - code = 47; - - String tmp = fVar.getName(); - if (tmp != null) - code += tmp.hashCode(); - - if (fNameOnly) - return code; - - code += fVar.getOperation(); - - tmp = fVar.getValue(); - if (tmp != null) - code += tmp.hashCode(); - - tmp = fVar.getDelimiter(); - if (tmp != null) - code += tmp.hashCode(); - - fCode = code; - } - return code; - } - - } public StorableEnvironment getEnvironment(Object context) { - return getEnvironment(context,true); + return getEnvironment(context, false); } protected StorableEnvironment getEnvironment(Object context, boolean forceLoad) { -// if (context == null) -// return null; - StorableEnvironment env = null; if (context instanceof IInternalCCfgInfo) { try { CConfigurationSpecSettings settings = ((IInternalCCfgInfo)context).getSpecSettings(); env = settings.getEnvironment(); - if (env == null && forceLoad) { + if (env == null || forceLoad) { env = loadEnvironment(context, settings.isReadOnly()); settings.setEnvironment(env); } @@ -168,8 +80,8 @@ public class UserDefinedEnvironmentSupplier extends } } else if (context instanceof IWorkspace || context == null) { - if (fWorkspaceVariables == null && forceLoad) - fWorkspaceVariables = loadEnvironment(context, false); + if (fWorkspaceVariables == null || forceLoad) + fWorkspaceVariables = (PrefsStorableEnvironment) loadEnvironment(context, false); env = fWorkspaceVariables; } @@ -238,7 +150,7 @@ public class UserDefinedEnvironmentSupplier extends } private Preferences getWorkspaceNode() { - Preferences prefNode = new InstanceScope().getNode(CCorePlugin.PLUGIN_ID); + Preferences prefNode = InstanceScope.INSTANCE.getNode(CCorePlugin.PLUGIN_ID); if (prefNode == null) return null; @@ -291,81 +203,11 @@ public class UserDefinedEnvironmentSupplier extends fWorkspaceVariables.setAppendEnvironment(env.appendEnvironment()); fWorkspaceVariables.setAppendContributedEnvironment(env.appendContributedEnvironment()); - EnvironmentChangeEvent event = createEnvironmentChangeEvent(newVariables, oldVariables); - storeWorkspaceEnvironment(true); -// updateProjectInfo(null); - - return event != null; + return ! Arrays.equals(oldVariables, newVariables); } - static EnvironmentChangeEvent createEnvironmentChangeEvent(IEnvironmentVariable[] newVars, IEnvironmentVariable[] oldVars) { - IEnvironmentVariable[] addedVars = null, removedVars = null, changedVars = null; - - if (oldVars == null || oldVars.length == 0) { - if (newVars != null && newVars.length != 0) - addedVars = newVars.clone(); - } else if (newVars == null || newVars.length == 0) { - removedVars = oldVars.clone(); - } else { - HashSet newSet = new HashSet(newVars.length); - HashSet oldSet = new HashSet(oldVars.length); - - for (IEnvironmentVariable newVar : newVars) { - newSet.add(new VarKey(newVar, true)); - } - - for (IEnvironmentVariable oldVar : oldVars) { - oldSet.add(new VarKey(oldVar, true)); - } - - @SuppressWarnings("unchecked") - HashSet newSetCopy = (HashSet)newSet.clone(); - - newSet.removeAll(oldSet); - oldSet.removeAll(newSetCopy); - - if (newSet.size() != 0) { - addedVars = varsFromKeySet(newSet); - } - - if (oldSet.size() != 0) { - removedVars = varsFromKeySet(oldSet); - } - - newSetCopy.removeAll(newSet); - - HashSet modifiedSet = new HashSet(newSetCopy.size()); - for (VarKey key : newSetCopy) { - modifiedSet.add(new VarKey(key.getVariable(), false)); - } - - for (IEnvironmentVariable oldVar : oldVars) { - modifiedSet.remove(new VarKey(oldVar, false)); - } - - if (modifiedSet.size() != 0) - changedVars = varsFromKeySet(modifiedSet); - } - - if (addedVars != null || removedVars != null || changedVars != null) - return new EnvironmentChangeEvent(addedVars, removedVars, changedVars); - return null; - } - - static IEnvironmentVariable[] varsFromKeySet(Set set) { - IEnvironmentVariable vars[] = new IEnvironmentVariable[set.size()]; - int i = 0; - for(Iterator iter = set.iterator(); iter.hasNext(); i++) { - VarKey key = iter.next(); - vars[i] = key.getVariable(); - } - - return vars; - } - - public void storeProjectEnvironment(ICProjectDescription des, boolean force) { ICConfigurationDescription cfgs[] = des.getConfigurations(); for (ICConfigurationDescription cfg : cfgs) { @@ -448,7 +290,6 @@ public class UserDefinedEnvironmentSupplier extends return null; IEnvironmentVariable var = env.createVariable(name,value,op,delimiter); if (env.isChanged()) { -// updateProjectInfo(context); env.setChanged(false); } return var; @@ -459,9 +300,6 @@ public class UserDefinedEnvironmentSupplier extends if (env == null) return null; IEnvironmentVariable var = env.deleteVariable(name); - if (var != null) { -// updateProjectInfo(context); - } return var; } @@ -470,9 +308,7 @@ public class UserDefinedEnvironmentSupplier extends if (env == null) return; - if (env.deleteAll()) { -// updateProjectInfo(context); - } + env.deleteAll(); } public void setVariables(IEnvironmentVariable vars[], Object context) { @@ -482,28 +318,14 @@ public class UserDefinedEnvironmentSupplier extends env.setVariales(vars); if (env.isChanged()) { -// updateProjectInfo(context); env.setChanged(false); } } -// protected void updateProjectInfo(Object context) { -// } - -// protected void cfgVarsModified(ICConfigurationDescription cfg) { -// cfg.setRebuildState(true); -// EnvironmentVariableProvider.getDefault().checkBuildPathVariables(cfg); -// } - protected String getValidName(String name) { if (name == null || (name = name.trim()).length() == 0) return null; -// if (fNonOverloadableVariables != null) { -// for(int i = 0; i < fNonOverloadableVariables.length; i++) { -// if (fNonOverloadableVariables[i].equals(EnvVarOperationProcessor.normalizeName(name))) -// return null; -// } -// } + return name; } @@ -548,4 +370,30 @@ public class UserDefinedEnvironmentSupplier extends } } + /** + * Adds a listener that will be notified of changes in environment variables. + * + * @param listener - the listener to add + * @since 5.5 + */ + public void registerEnvironmentChangeListener(IEnvironmentChangeListener listener) { + if (fWorkspaceVariables == null) { + getEnvironment(null, false); + } + if (fWorkspaceVariables != null) { + fWorkspaceVariables.registerEnvironmentChangeListener(listener); + } + } + + /** + * Removes an environment variables change listener. + * + * @param listener - the listener to remove. + * @since 5.5 + */ + public void unregisterEnvironmentChangeListener(IEnvironmentChangeListener listener) { + if (fWorkspaceVariables != null) { + fWorkspaceVariables.unregisterEnvironmentChangeListener(listener); + } + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/IEnvironmentChangeEvent.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/IEnvironmentChangeEvent.java new file mode 100644 index 00000000000..9683e1d48a0 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/IEnvironmentChangeEvent.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013, 2013 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.utils.envvar; + +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; + +/** + * A class to describe changes to environment variables defined by user + * on CDT Environment page in Preferences. + * + * @since 5.5 + */ +public interface IEnvironmentChangeEvent { + /** + * @return an array of environment variables before the changes. If there are no variables, + * returns an empty array. + */ + public IEnvironmentVariable[] getOldVariables(); + + /** + * @return an array of environment variables after the changes. If there are no variables, + * returns an empty array. + */ + public IEnvironmentVariable[] getNewVariables(); + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/IEnvironmentChangeListener.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/IEnvironmentChangeListener.java new file mode 100644 index 00000000000..6adea60095c --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/IEnvironmentChangeListener.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013, 2013 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.utils.envvar; + + +/** + * Interface for listeners to changes in environment variables defined by user + * on CDT Environment page in Preferences. + * + * @since 5.5 + */ +public interface IEnvironmentChangeListener { + /** + * Indicates that environment variables have been changed. + * + * @param event - details of the event. + */ + public void handleEvent(IEnvironmentChangeEvent event); +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/PrefsStorableEnvironment.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/PrefsStorableEnvironment.java index 6742fa3df01..7bbe61d4345 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/PrefsStorableEnvironment.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/envvar/PrefsStorableEnvironment.java @@ -22,7 +22,9 @@ 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.internal.core.envvar.EnvironmentChangeEvent; import org.eclipse.cdt.utils.envvar.StorableEnvironmentLoader.ISerializeInfo; +import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener; import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; @@ -72,6 +74,8 @@ public class PrefsStorableEnvironment extends StorableEnvironment { private boolean fAppendChanged = false; private boolean fAppendContributedChanged = false; + private static ListenerList fEnvironmentChangeListeners = new ListenerList(ListenerList.IDENTITY); + /** A listener for changes in the backing store */ private static class PrefListener implements IPreferenceChangeListener, INodeChangeListener { @@ -401,6 +405,9 @@ public class PrefsStorableEnvironment extends StorableEnvironment { void serialize() { if (!isDirty()) return; + + HashMap oldEnv = new HashMap(fCachedSerialEnv); + Preferences element = fSerialEnv.getNode().node(fSerialEnv.getPrefName()); element.putBoolean(ATTRIBUTE_APPEND, fAppend); fAppendChanged = false; @@ -430,6 +437,11 @@ public class PrefsStorableEnvironment extends StorableEnvironment { } catch (BackingStoreException e) { CCorePlugin.log(e); } + + if (fAppendChanged || fAppendContributedChanged || !oldEnv.equals(fCachedSerialEnv)) { + IEnvironmentChangeEvent event = new EnvironmentChangeEvent(oldEnv.values(), fCachedSerialEnv.values()); + notifyLanguageSettingsChangeListeners(event); + } } @Override @@ -535,6 +547,37 @@ public class PrefsStorableEnvironment extends StorableEnvironment { (fDeletedVariables != null && !fDeletedVariables.isEmpty()); } + /** + * Adds a listener that will be notified of changes in environment variables. + * + * @param listener - the listener to add + * @since 5.5 + */ + public void registerEnvironmentChangeListener(IEnvironmentChangeListener listener) { + fEnvironmentChangeListeners.add(listener); + } + + /** + * Removes an environment variables change listener. + * + * @param listener - the listener to remove. + * @since 5.5 + */ + public void unregisterEnvironmentChangeListener(IEnvironmentChangeListener listener) { + fEnvironmentChangeListeners.remove(listener); + } + + /** + * Notifies all environment change listeners of a change in environment. + * + * @param event - the {@link IEnvironmentChangeEvent} event to be broadcast. + */ + private static void notifyLanguageSettingsChangeListeners(IEnvironmentChangeEvent event) { + for (Object listener : fEnvironmentChangeListeners.getListeners()) { + ((IEnvironmentChangeListener) listener).handleEvent(event); + } + } + @Override protected void finalize() throws Throwable { super.finalize();