/******************************************************************************* * Copyright (c) 2005, 2009 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 * James Blackburn (Broadcom Corp.) *******************************************************************************/ package org.eclipse.cdt.utils.envvar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; import org.eclipse.cdt.internal.core.settings.model.ExceptionFactory; import org.eclipse.cdt.utils.envvar.StorableEnvironmentLoader.ISerializeInfo; /** * This class represents the set of environment variables that could be loaded * and stored in XML * * @since 3.0 */ public class StorableEnvironment { public static final String ENVIRONMENT_ELEMENT_NAME = "environment"; //$NON-NLS-1$ static final String ATTRIBUTE_APPEND = "append"; //$NON-NLS-1$ static final String ATTRIBUTE_APPEND_CONTRIBUTED = "appendContributed"; //$NON-NLS-1$ static final boolean DEFAULT_APPEND = true; /** The map of in-flight environment variables */ Map<String, IEnvironmentVariable> fVariables; private boolean fIsDirty = false; boolean fIsChanged = false; final boolean fIsReadOnly; boolean fAppend = DEFAULT_APPEND; boolean fAppendContributedEnv = DEFAULT_APPEND; /** * @return the live {@link IEnvironmentVariable} map */ Map<String, IEnvironmentVariable> getMap(){ if(fVariables == null) fVariables = new HashMap<String, IEnvironmentVariable>(); return fVariables; } /** * * @param variables * @param isReadOnly */ public StorableEnvironment(IEnvironmentVariable variables[], boolean isReadOnly) { setVariales(variables); fIsReadOnly = isReadOnly; } /** * Create new empty StorableEnvironment * @param isReadOnly */ public StorableEnvironment(boolean 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) { if(env.fVariables != null) fVariables = env.getAllVariablesMap(); fAppend = env.fAppend; fAppendContributedEnv = env.fAppendContributedEnv; fIsReadOnly = isReadOnly; fIsDirty = env.isDirty(); } /** * Initialize the StorableEnvironment from an ICStorageElement tree * @param element * @param isReadOnly */ public StorableEnvironment(ICStorageElement element, boolean isReadOnly) { load(element); fIsReadOnly = isReadOnly; } /** * Load the preferences from an {@link ICStorageElement} * @param element */ private void load(ICStorageElement element){ ICStorageElement children[] = element.getChildren(); for (int i = 0; i < children.length; ++i) { ICStorageElement node = children[i]; if (node.getName().equals(StorableEnvVar.VARIABLE_ELEMENT_NAME)) { addVariable(getMap(), new StorableEnvVar(node)); } } String append = element.getAttribute(ATTRIBUTE_APPEND); fAppend = append != null ? Boolean.valueOf(append).booleanValue() : DEFAULT_APPEND; append = element.getAttribute(ATTRIBUTE_APPEND_CONTRIBUTED); fAppendContributedEnv = append != null ? Boolean.valueOf(append).booleanValue() : DEFAULT_APPEND; fIsDirty = false; fIsChanged = false; } /** * Serialize the Storable enviornment into the ICStorageElement * * NB assumes that any variables part of the ISerializeInfo will continue to be serialized * @param element */ public void serialize(ICStorageElement element){ element.setAttribute(ATTRIBUTE_APPEND, Boolean.valueOf(fAppend).toString()); element.setAttribute(ATTRIBUTE_APPEND_CONTRIBUTED, Boolean.valueOf(fAppendContributedEnv).toString()); if(fVariables != null){ Iterator<IEnvironmentVariable> iter = fVariables.values().iterator(); while(iter.hasNext()){ StorableEnvVar var = (StorableEnvVar)iter.next(); ICStorageElement varEl = element.createChild(StorableEnvVar.VARIABLE_ELEMENT_NAME); var.serialize(varEl); } } fIsDirty = false; } /** * Add the environment variable to the map * @param map * @param var */ void addVariable(Map<String, IEnvironmentVariable> map, IEnvironmentVariable var){ String name = getNameForMap(var.getName()); if (name == null) return; map.put(name,var); } public IEnvironmentVariable createVariable(String name, String value, int op, String delimiter){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ return null; IEnvironmentVariable var = checkVariable(name,value,op,delimiter); if(var == null){ var = new StorableEnvVar(name, value, op, delimiter); addVariable(getMap(), var); fIsDirty = true; fIsChanged = true; } return var; } public IEnvironmentVariable createVariable(String name){ return createVariable(name,null,IEnvironmentVariable.ENVVAR_REPLACE,null); } public IEnvironmentVariable createVariable(String name, String value){ return createVariable(name,value,IEnvironmentVariable.ENVVAR_REPLACE,null); } public IEnvironmentVariable createVariable(String name, String value, String delimiter){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); return createVariable(name,value,IEnvironmentVariable.ENVVAR_REPLACE,delimiter); } public IEnvironmentVariable checkVariable(String name, String value, int op, String delimiter){ IEnvironmentVariable var = getVariable(name); if(var != null && checkStrings(var.getValue(),value) && var.getOperation() == op && checkStrings(var.getDelimiter(),delimiter)) return var; return null; } private boolean checkStrings(String str1, String str2){ if(str1 != null && str1.equals(str2)) return true; return str1 == str2; } /** * Returns the "dirty" state of the environment. * If the dirty state is <code>true</code>, that means that the environment * is out of synch with the repository and the environment needs to be serialized. * <br><br> * The dirty state is automatically set to <code>false</code> when the environment is serialized * by calling the serialize() method * @return boolean */ public boolean isDirty(){ return fIsDirty; } /** * sets the "dirty" state of the environment * @param dirty represents the new state */ public void setDirty(boolean dirty){ fIsDirty = dirty; } /** * Returns the "change" state of the environment. * The "change" state represents whether the environment was changed or not. * This state is not reset when the serialize() method is called * Users can use this state to monitor whether the environment was changed or not. * This state can be reset to <code>false</code> only by calling the setChanged(false) method * @return boolean */ public boolean isChanged(){ return fIsChanged; } /** * sets the "change" state of the environment * @param changed represents the new "change" state */ public void setChanged(boolean changed){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); fIsChanged = changed; } /** * @param name * @return the environment variable with the given name, or null */ public IEnvironmentVariable getVariable(String name){ name = getNameForMap(name); if (name == null) return null; return getMap().get(name); } /** * Set the enviornment variables in this {@link StorableEnvironment} * @param vars */ public void setVariales(IEnvironmentVariable vars[]){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); if(vars == null || vars.length == 0) deleteAll(); else{ if (getMap().size() != 0) { Iterator<IEnvironmentVariable> iter = getMap().values().iterator(); while(iter.hasNext()){ IEnvironmentVariable v = iter.next(); int i; for(i = 0 ; i < vars.length; i++){ if(v.getName().equals(vars[i].getName())) break; } if(i == vars.length) deleteVariable(v.getName()); } } createVriables(vars); } } public void createVriables(IEnvironmentVariable vars[]){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); for(int i = 0; i < vars.length; i++) createVariable(vars[i].getName(), vars[i].getValue(), vars[i].getOperation(), vars[i].getDelimiter()); } /** * @return cloned map of all variables set on this storable environment runtime variables + backing store vars */ Map<String, IEnvironmentVariable> getAllVariablesMap() { Map<String, IEnvironmentVariable> vars = new HashMap<String, IEnvironmentVariable>(); vars.putAll(getMap()); return vars; } public IEnvironmentVariable[] getVariables(){ Map<String, IEnvironmentVariable> vars = getAllVariablesMap(); 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){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); name = getNameForMap(name); if(name == null) return null; IEnvironmentVariable var = getMap().remove(name); if(var != null){ fIsDirty = true; fIsChanged = true; } return var; } public boolean deleteAll(){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); Map<String, IEnvironmentVariable> map = getMap(); if(map.size() > 0) { fIsDirty = true; fIsChanged = true; map.clear(); return true; } return false; } public boolean isReadOnly(){ return fIsReadOnly; } public boolean appendEnvironment(){ return fAppend; } public void setAppendEnvironment(boolean append){ if(fAppend == append) return; if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); fAppend = append; fIsDirty = true; } public boolean appendContributedEnvironment(){ return fAppendContributedEnv; } public void setAppendContributedEnvironment(boolean append){ if(fAppendContributedEnv == append) return; if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); fAppendContributedEnv = append; fIsDirty = true; } public void restoreDefaults(){ deleteAll(); fAppend = DEFAULT_APPEND; fAppendContributedEnv = DEFAULT_APPEND; } }