/******************************************************************************* * Copyright (c) 2005, 2008 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 *******************************************************************************/ package org.eclipse.cdt.internal.core.cdtvariables; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.IStorableCdtVariables; import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.internal.core.cdtvariables.UserDefinedVariableSupplier.VarKey; import org.eclipse.cdt.internal.core.settings.model.ExceptionFactory; import org.eclipse.cdt.utils.cdtvariables.CdtVariableResolver; /** * This class represents the set of Build Macros that could be loaded * and stored in XML * * @since 3.0 * */ public class StorableCdtVariables implements IStorableCdtVariables { public static final String MACROS_ELEMENT_NAME = "macros"; //$NON-NLS-1$ private HashMap<String, ICdtVariable> fMacros; private boolean fIsDirty = false; private boolean fIsChanged = false; private boolean fIsReadOnly; private HashMap<String, ICdtVariable> getMap(){ if(fMacros == null) fMacros = new HashMap<String, ICdtVariable>(); return fMacros; } public StorableCdtVariables(boolean readOnly) { fIsReadOnly = readOnly; } @SuppressWarnings("unchecked") public StorableCdtVariables(StorableCdtVariables base, boolean readOnly) { fMacros = (HashMap<String, ICdtVariable>)base.getMap().clone(); fIsReadOnly = readOnly; } public StorableCdtVariables(ICdtVariable vars[], boolean readOnly) { fMacros = new HashMap<String, ICdtVariable>(vars.length); for (ICdtVariable var : vars) { addMacro(var); } fIsReadOnly = readOnly; } public StorableCdtVariables(ICStorageElement element, boolean readOnly) { load(element); fIsReadOnly = readOnly; } private void load(ICStorageElement element){ // fExpandInMakefile = TRUE.equals(element.getAttribute(EXPAND_ENVIRONMENT_MACROS)); ICStorageElement nodeList[] = element.getChildren(); for (int i = 0; i < nodeList.length; ++i) { ICStorageElement node = nodeList[i]; String name = node.getName(); if (StorableCdtVariable.STRING_MACRO_ELEMENT_NAME.equals(name)) { addMacro(new StorableCdtVariable(node)); } else if (StorableCdtVariable.STRINGLIST_MACRO_ELEMENT_NAME.equals(name)) { addMacro(new StorableCdtVariable(node)); } } fIsDirty = false; fIsChanged = false; } public void serialize(ICStorageElement element){ if(fMacros != null){ for (ICdtVariable v : fMacros.values()){ StorableCdtVariable macro = (StorableCdtVariable)v; ICStorageElement macroEl; if(CdtVariableResolver.isStringListVariable(macro.getValueType())) macroEl = element.createChild(StorableCdtVariable.STRINGLIST_MACRO_ELEMENT_NAME); else macroEl = element.createChild(StorableCdtVariable.STRING_MACRO_ELEMENT_NAME); macro.serialize(macroEl); } } fIsDirty = false; } private void addMacro(ICdtVariable macro){ String name = macro.getName(); if(name == null) return; getMap().put(name,macro); } public ICdtVariable createMacro(String name, int type, String value){ if(name == null || "".equals(name = name.trim()) || CdtVariableResolver.isStringListVariable(type)) //$NON-NLS-1$ return null; ICdtVariable macro = checkMacro(name, type, value); if(macro == null){ macro = new StorableCdtVariable(name, type, value); addMacro(macro); fIsDirty = true; fIsChanged = true; } return macro; } public ICdtVariable checkMacro(String name, int type, String value){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); ICdtVariable macro = getMacro(name); if(macro != null){ if(macro.getName().equals(name) && macro.getValueType() == type){ try { String val = macro.getStringValue(); if((val != null && val.equals(value)) || val == value){ return macro; } } catch (CdtVariableException e) { } } } return null; } public ICdtVariable checkMacro(String name, int type, String value[]){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); ICdtVariable macro = getMacro(name); if(macro != null){ if(macro.getName().equals(name) && macro.getValueType() == type){ try { String val[] = macro.getStringListValue(); if(val != null){ if(value != null && value.length == val.length){ int i; for(i = 0; i < val.length; i++){ if(!value[i].equals(val[i])) break; } if(i == value.length) return macro; } } else if (value == val){ return macro; } } catch (CdtVariableException e) { } } } return null; } /* * sets the storable macros to hold the geven number of macros * all macros that are present in the store but not included in the given array * will be removed */ public void setMacros(ICdtVariable macros[]){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); if(macros == null || macros.length == 0) deleteAll(); else{ if (getMap().size() != 0) { for (ICdtVariable m : getMap().values()){ int i; for(i = 0 ; i < macros.length; i++){ if(m.getName().equals(macros[i].getName())) break; } if(i == macros.length) deleteMacro(m.getName()); } } createMacros(macros); } } public void createMacros(ICdtVariable macros[]){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); for (ICdtVariable macro : macros) { createMacro(macro); } } public boolean isEmpty(){ return fMacros == null || fMacros.isEmpty(); } public ICdtVariable createMacro(ICdtVariable copy){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); String name = copy.getName(); if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ return null; int type = copy.getValueType(); ICdtVariable macro = null; try{ if(CdtVariableResolver.isStringListVariable(type)){ String value[] = copy.getStringListValue(); macro = checkMacro(name, type, value); if(macro == null){ macro = new StorableCdtVariable(name, type, value); addMacro(macro); fIsDirty = true; fIsChanged = true; } } else { String value = copy.getStringValue(); macro = checkMacro(name, type, value); if(macro == null){ macro = new StorableCdtVariable(name, type, value); addMacro(macro); fIsDirty = true; fIsChanged = true; } } }catch(CdtVariableException e){ } return macro; } public ICdtVariable createMacro(String name, int type, String value[]){ if(name == null || "".equals(name = name.trim()) || !CdtVariableResolver.isStringListVariable(type)) //$NON-NLS-1$ return null; ICdtVariable macro = checkMacro(name, type, value); if(macro == null){ macro = new StorableCdtVariable(name, type, value); addMacro(macro); fIsDirty = true; fIsChanged = true; } return macro; } /** * Returns the "dirty" state for this set of macros. * If the dirty state is <code>true</code>, that means that the macros * is out of synch with the repository and the macros need to be serialized. * <br><br> * The dirty state is automatically set to <code>false</code> when the macros are serialized * by calling the serialize() method * @return boolean */ public boolean isDirty(){ return fIsDirty; } /** * sets the "dirty" state for this set of macros. * @see org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables#isDirty() * @param dirty represents the new state */ public void setDirty(boolean dirty){ fIsDirty = dirty; } /** * Returns the "change" state for this set of macros. * The "change" state represents whether the macros were changed or not. * This state is not reset when the serialize() method is called * Users can use this state to monitor whether the macros were changed or not. * The "change" state can be reset only by calling the setChanged(false) method * @return boolean */ public boolean isChanged(){ return fIsChanged; } /* public boolean isExpanded(){ return fExpandInMakefile; } */ /* public void setExpanded(boolean expand){ if(fExpandInMakefile != expand){ fExpandInMakefile = expand; fIsDirty = true; //should we set the change state here? fIsChanged = true; } } */ /** * sets the "change" state for this set of macros. * @see org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables#isChanged() * @param changed represents the new "change" state */ public void setChanged(boolean changed){ fIsChanged = changed; } public ICdtVariable getMacro(String name){ if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ return null; ICdtVariable var = getMap().get(name); if(var == null){ int indx = name.indexOf(':'); if(indx != -1){ String baseName = name.substring(0, indx); ICdtVariable tmp = getMap().get(baseName); if(tmp != null && CdtVariableManager.getDefault().toEclipseVariable(tmp, null) != null){ var = EclipseVariablesVariableSupplier.getInstance().getVariable(name); } } } return var; } public ICdtVariable[] getMacros(){ Collection<ICdtVariable> macros = getMap().values(); return macros.toArray(new ICdtVariable[macros.size()]); } public ICdtVariable deleteMacro(String name){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ return null; ICdtVariable macro = getMap().remove(name); if(macro != null){ fIsDirty = true; fIsChanged = true; } return macro; } public boolean deleteAll(){ if(fIsReadOnly) throw ExceptionFactory.createIsReadOnlyException(); Map<String, ICdtVariable> map = getMap(); if(map.size() > 0){ fIsDirty = true; fIsChanged = true; map.clear(); return true; } return false; } public boolean contains(ICdtVariable var){ ICdtVariable curVar = getMacro(var.getName()); if(curVar == null) return false; if(new VarKey(curVar, false).equals(new VarKey(var, false))) return true; return false; } }