/******************************************************************************* * Copyright (c) 2007, 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; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; import org.eclipse.cdt.core.resources.IPathEntryVariableChangeListener; import org.eclipse.cdt.core.resources.IPathEntryVariableManager; import org.eclipse.cdt.core.resources.PathEntryVariableChangeEvent; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.internal.core.cdtvariables.ICdtVariableChangeListener; import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo; import org.eclipse.cdt.internal.core.cdtvariables.UserDefinedVariableSupplier; import org.eclipse.cdt.internal.core.cdtvariables.VariableChangeEvent; import org.eclipse.cdt.utils.cdtvariables.CdtVariableResolver; import org.eclipse.cdt.utils.cdtvariables.ICdtVariableSupplier; import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo; import org.eclipse.cdt.utils.cdtvariables.SupplierBasedCdtVariableSubstitutor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SafeRunner; /** * the path entry variable manager is kept for the backward compatibility purposes * currently it presents workspace Cdt variables that hold either a file or folder value * */ public class CdtVarPathEntryVariableManager implements IPathEntryVariableManager, ICdtVariableChangeListener { private UserDefinedVariableSupplier fUserVarSupplier = UserDefinedVariableSupplier.getInstance(); private VarSubstitutor fSubstitutor = new VarSubstitutor(); private VarSupplier fVarSupplier = new VarSupplier(); private Set<IPathEntryVariableChangeListener> fListeners; private class VarSubstitutor extends SupplierBasedCdtVariableSubstitutor { public VarSubstitutor() { super(new VarContextInfo(), "", " "); //$NON-NLS-1$ //$NON-NLS-2$ } } private class VarContextInfo implements IVariableContextInfo { public IVariableContextInfo getNext() { return null; } public ICdtVariableSupplier[] getSuppliers() { return new ICdtVariableSupplier[]{fVarSupplier}; } @Override public boolean equals(Object obj) { if(obj == this) return true; if(!(obj instanceof VarContextInfo)) return false; return true; } } private class VarSupplier implements ICdtVariableSupplier { public ICdtVariable getVariable(String macroName, IVariableContextInfo context) { ICdtVariable var = fUserVarSupplier.getMacro(macroName, ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); if(var != null && getVariablePath(var) != null) return var; return null; } public ICdtVariable[] getVariables(IVariableContextInfo context) { ICdtVariable vars[] = fUserVarSupplier.getMacros(ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); List<ICdtVariable> list = new ArrayList<ICdtVariable>(); for (ICdtVariable var : vars) { if(getVariablePath(var) != null) list.add(var); } return list.toArray(new ICdtVariable[list.size()]); } } public CdtVarPathEntryVariableManager(){ fListeners = Collections.synchronizedSet(new HashSet<IPathEntryVariableChangeListener>()); fUserVarSupplier.addListener(this); } public IPath getValue(String name) { ICdtVariable var = fUserVarSupplier.getMacro(name, ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); return getVariablePath(var); } public static IPath getVariablePath(ICdtVariable var){ if(var != null){ switch(var.getValueType()){ case ICdtVariable.VALUE_PATH_ANY: case ICdtVariable.VALUE_PATH_DIR: case ICdtVariable.VALUE_PATH_FILE: try { String value = var.getStringValue(); if(value != null) return new Path(value); return Path.EMPTY; } catch (CdtVariableException e) { CCorePlugin.log(e); } } } return null; } public static boolean isPathEntryVariable(ICdtVariable var, ICConfigurationDescription cfg){ return isPathEntryVariable(var, cfg, CCorePlugin.getDefault().getCdtVariableManager()); } public static boolean isPathEntryVariable(ICdtVariable var, ICConfigurationDescription cfg, ICdtVariableManager mngr){ if(mngr.isUserVariable(var, cfg)) return false; if(!mngr.isUserVariable(var, null)) return false; if(getVariablePath(var) == null) return false; return true; } public String[] getVariableNames() { ICdtVariable[] vars = fUserVarSupplier.getMacros(ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); ArrayList<String> list = new ArrayList<String>(); for(int i = 0; i > vars.length; i++){ if(getVariablePath(vars[i]) != null) list.add(vars[i].getName()); } return list.toArray(new String[list.size()]); } public boolean isDefined(String name) { return getValue(name) != null; } public IPath resolvePath(IPath path) { if(path == null) return null; String str = path.toPortableString(); try { str = CdtVariableResolver.resolveToString(str, fSubstitutor); } catch (CdtVariableException e) { CCorePlugin.log(e); } return new Path(str); } public void setValue(String name, IPath value) throws CoreException { if(value != null) fUserVarSupplier.createMacro(name, ICdtVariable.VALUE_PATH_ANY, value.toString(), ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); else fUserVarSupplier.deleteMacro(name, ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); fUserVarSupplier.storeWorkspaceVariables(false); } /** * Fires a property change event corresponding to a change to the * current value of the variable with the given name. * * @param name the name of the variable, to be used as the variable * in the event object * @param value the current value of the path variable or <code>null</code> if * the variable was deleted * @param type one of <code>IPathVariableChangeEvent.VARIABLE_CREATED</code>, * <code>PathEntryVariableChangeEvent.VARIABLE_CHANGED</code>, or * <code>PathEntryVariableChangeEvent.VARIABLE_DELETED</code> * @see PathEntryVariableChangeEvent * @see PathEntryVariableChangeEvent#VARIABLE_CREATED * @see PathEntryVariableChangeEvent#VARIABLE_CHANGED * @see PathEntryVariableChangeEvent#VARIABLE_DELETED */ private void fireVariableChangeEvent(String name, IPath value, int type) { if (this.fListeners.size() == 0) return; // use a separate collection to avoid interference of simultaneous additions/removals Object[] listenerArray = this.fListeners.toArray(); final PathEntryVariableChangeEvent pve = new PathEntryVariableChangeEvent(this, name, value, type); for (int i = 0; i < listenerArray.length; ++i) { final IPathEntryVariableChangeListener l = (IPathEntryVariableChangeListener) listenerArray[i]; ISafeRunnable job = new ISafeRunnable() { public void handleException(Throwable exception) { // already being logged in Platform#run() } public void run() throws Exception { l.pathVariableChanged(pve); } }; SafeRunner.run(job); } } /** * @see org.eclipse.cdt.core.resources.IPathEntryVariableManager#addChangeListener(IPathEntryVariableChangeListener) */ public void addChangeListener(IPathEntryVariableChangeListener listener) { fListeners.add(listener); } /** * @see org.eclipse.cdt.core.resources. * IPathEntryVariableManager#removeChangeListener(IPathEntryVariableChangeListener) */ public void removeChangeListener(IPathEntryVariableChangeListener listener) { fListeners.remove(listener); } public void variablesChanged(VariableChangeEvent event) { ICdtVariable[] added = event.getAddedVariables(); ICdtVariable[] removed = event.getRemovedVariables(); ICdtVariable[] changed = event.getChangedVariables(); if(added.length != 0){ fireEvent(added, PathEntryVariableChangeEvent.VARIABLE_CREATED); } if(removed.length != 0){ fireEvent(removed, PathEntryVariableChangeEvent.VARIABLE_DELETED); } if(changed.length != 0){ fireEvent(changed, PathEntryVariableChangeEvent.VARIABLE_CHANGED); } } private void fireEvent(ICdtVariable vars[], int type){ for (ICdtVariable var : vars) { IPath path = getVariablePath(var); if(path != null) fireVariableChangeEvent(var.getName(), path, type); } } public void startup(){ } public void shutdown(){ } }