/******************************************************************************* * Copyright (c) 2005, 2007 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.managedbuilder.internal.envvar; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.internal.core.envvar.EnvVarCollector; import org.eclipse.cdt.managedbuilder.core.IBuildPathResolver; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentBuildPathsChangeListener; import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableSupplier; import org.eclipse.cdt.utils.envvar.EnvVarOperationProcessor; /** * This class implements the IEnvironmentVariableProvider interface and provides all * build environment functionality to the MBS * * @since 3.0 * */ public class EnvironmentVariableProvider implements IEnvironmentVariableProvider { // private static final QualifiedName fBuildPathVarProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "buildPathVar"); //$NON-NLS-1$ // private static final String DELIMITER_WIN32 = ";"; //$NON-NLS-1$ // private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$ private static EnvironmentVariableProvider fInstance = null; private List<IEnvironmentBuildPathsChangeListener> fListeners = null; private IEnvironmentVariableManager fMngr; private boolean fBuildPathVarCheckAllowed; private StoredBuildPathEnvironmentContainer fIncludeStoredBuildPathVariables; private StoredBuildPathEnvironmentContainer fLibraryStoredBuildPathVariables; /** * This class is used by the EnvironmentVariableProvider to calculate the build paths * in case a tool-integrator did not provide the special logic for obtaining the build * paths from environment variable values * * @since 3.0 * */ static public class DefaultBuildPathResolver implements IBuildPathResolver { private String fDelimiter; public DefaultBuildPathResolver(String delimiter){ fDelimiter = delimiter; } public String[] resolveBuildPaths(int pathType, String variableName, String variableValue, IConfiguration configuration) { if(fDelimiter == null || "".equals(fDelimiter)) //$NON-NLS-1$ return new String[]{variableValue}; List<String> list = EnvVarOperationProcessor.convertToList(variableValue,fDelimiter); return list.toArray(new String[list.size()]); } } protected EnvironmentVariableProvider(IEnvironmentVariableManager mngr){ fMngr = mngr; } public static EnvironmentVariableProvider getDefault(){ if(fInstance == null){ fInstance = new EnvironmentVariableProvider(CCorePlugin.getDefault().getBuildEnvironmentManager()); fInstance.fBuildPathVarCheckAllowed = true; } return fInstance; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getVariable() */ public IBuildEnvironmentVariable getVariable(String variableName, Object level, boolean includeParentLevels, boolean resolveMacros) { if(variableName == null || "".equals(variableName)) //$NON-NLS-1$ return null; if(level instanceof IConfiguration){ return wrap(getVariable(variableName, (IConfiguration)level, resolveMacros)); } return null; } public IEnvironmentVariable getVariable(String variableName, IConfiguration cfg, boolean resolveMacros){ return getVariable(variableName, cfg, resolveMacros, true); } public IEnvironmentVariable getVariable(String variableName, IConfiguration cfg, boolean resolveMacros, boolean checkBuildPaths){ ICConfigurationDescription des = ManagedBuildManager.getDescriptionForConfiguration(cfg); if(des != null){ IEnvironmentVariable variable = fMngr.getVariable(variableName, des, resolveMacros); if(checkBuildPaths && resolveMacros && fBuildPathVarCheckAllowed) checkBuildPathVariable(cfg, variableName, variable); return variable; } return null; } public IEnvironmentVariable[] getVariables(IConfiguration cfg, boolean resolveMacros){ return getVariables(cfg, resolveMacros, true); } public IEnvironmentVariable[] getVariables(IConfiguration cfg, boolean resolveMacros, boolean checkBuildPaths){ ICConfigurationDescription des = ManagedBuildManager.getDescriptionForConfiguration(cfg); if(des != null){ IEnvironmentVariable vars[] = fMngr.getVariables(des, resolveMacros); if(checkBuildPaths && resolveMacros && fBuildPathVarCheckAllowed) checkBuildPathVariables(cfg,vars); return vars; } return new IBuildEnvironmentVariable[0]; } public static IBuildEnvironmentVariable wrap(IEnvironmentVariable var){ if(var == null) return null; if(var instanceof IBuildEnvironmentVariable) return (IBuildEnvironmentVariable)var; return new BuildEnvVar(var); } public static IBuildEnvironmentVariable[] wrap(IEnvironmentVariable vars[]){ if(vars == null) return null; if(vars instanceof IBuildEnvironmentVariable[]) return (IBuildEnvironmentVariable[])vars; IBuildEnvironmentVariable[] buildVars = new IBuildEnvironmentVariable[vars.length]; for(int i = 0; i < vars.length; i++){ buildVars[i] = wrap(vars[i]); } return buildVars; } /* protected ICConfigurationDescription getDescription(IConfiguration cfg){ IProject project = cfg.getOwner().getProject(); ICProjectDescription des = CoreModel.getDefault().getProjectDescription(project, false); if(des != null){ return des.getConfigurationById(cfg.getId()); } return null; } */ /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getVariables() */ public IBuildEnvironmentVariable[] getVariables(Object level, boolean includeParentLevels, boolean resolveMacros) { if(level instanceof IConfiguration){ return wrap(getVariables((IConfiguration)level, resolveMacros)); } return new IBuildEnvironmentVariable[0]; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getDefaultDelimiter() */ public String getDefaultDelimiter() { return fMngr.getDefaultDelimiter(); } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#isVariableCaseSensitive() */ public boolean isVariableCaseSensitive() { return fMngr.isVariableCaseSensitive(); } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getSuppliers() */ public IEnvironmentVariableSupplier[] getSuppliers(Object level) { return null; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getBuildPaths() */ public String[] getBuildPaths(IConfiguration configuration, int buildPathType) { ITool tools[] = configuration.getFilteredTools(); List<String> list = new ArrayList<String>(); for(int i = 0; i < tools.length; i++){ IEnvVarBuildPath pathDescriptors[] = tools[i].getEnvVarBuildPaths(); if(pathDescriptors == null || pathDescriptors.length == 0) continue; for(int j = 0; j < pathDescriptors.length; j++){ IEnvVarBuildPath curPathDes = pathDescriptors[j]; if(curPathDes.getType() != buildPathType) continue; String vars[] = curPathDes.getVariableNames(); if(vars == null || vars.length == 0) continue; IBuildPathResolver pathResolver = curPathDes.getBuildPathResolver(); if(pathResolver == null){ String delimiter = curPathDes.getPathDelimiter(); if(delimiter == null) delimiter = getDefaultDelimiter(); pathResolver = new DefaultBuildPathResolver(delimiter); } for(int k = 0; k < vars.length; k++){ String varName = vars[k]; IEnvironmentVariable var = getVariable(varName,configuration,true, false); if(var == null) continue; String varValue = var.getValue(); String paths[] = pathResolver.resolveBuildPaths(buildPathType,varName,varValue,configuration); if(paths != null && paths.length != 0) list.addAll(Arrays.asList(paths)); } } } return list.toArray(new String[list.size()]); } /* * returns a list of registered listeners */ private List<IEnvironmentBuildPathsChangeListener> getListeners(){ if(fListeners == null) fListeners = new ArrayList<IEnvironmentBuildPathsChangeListener>(); return fListeners; } /* * notifies registered listeners */ private void notifyListeners(IConfiguration configuration, int buildPathType){ List<IEnvironmentBuildPathsChangeListener> listeners = getListeners(); for (IEnvironmentBuildPathsChangeListener listener : listeners) { listener.buildPathsChanged(configuration,buildPathType); } } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#subscribe() */ public synchronized void subscribe(IEnvironmentBuildPathsChangeListener listener) { if(listener == null) return; List<IEnvironmentBuildPathsChangeListener> listeners = getListeners(); if(!listeners.contains(listener)) listeners.add(listener); } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#unsubscribe() */ public synchronized void unsubscribe(IEnvironmentBuildPathsChangeListener listener) { if(listener == null) return; List<IEnvironmentBuildPathsChangeListener> listeners = getListeners(); listeners.remove(listener); } /* * performs a check of the build path variables for the given configuration * If the build variables are changed, the notification is sent */ public void checkBuildPathVariables(IConfiguration configuration){ checkBuildPathVariables(configuration, getVariables(configuration ,true, false)); } /* * performs a check of the build path variables of the specified type * for the given configuration * If the build variables are changed, the notification is sent */ public void checkBuildPathVariables(IConfiguration configuration,int buildPathType){ EnvVarCollector cr = new EnvVarCollector(); cr.add(getVariables(configuration, true, false)); checkBuildPathVariables(configuration,buildPathType,cr); } /* * performs a check of the build path variables * for the given configuration given the set of the variables * defined for this configuration * If the build variables are changed, the notification is sent */ protected void checkBuildPathVariables(IConfiguration configuration, IEnvironmentVariable vars[]){ EnvVarCollector cr = new EnvVarCollector(); cr.add(vars); checkBuildPathVariables(configuration,IEnvVarBuildPath.BUILDPATH_INCLUDE,cr); checkBuildPathVariables(configuration,IEnvVarBuildPath.BUILDPATH_LIBRARY,cr); } /* * performs a check of whether the given variable is the build path variable * and if true checks whether it is changed. * In the case of it is changed all other build path variables are checked * and notification is sent. * If it is not changed, other build path variables are not checked * In the case of the given variable is not the build path one, this method does nothing */ protected void checkBuildPathVariable(IConfiguration configuration, String varName, IEnvironmentVariable var){ checkBuildPathVariable(configuration, IEnvVarBuildPath.BUILDPATH_INCLUDE, varName, var); checkBuildPathVariable(configuration, IEnvVarBuildPath.BUILDPATH_LIBRARY, varName, var); } /* * performs a check of whether the given variable is the build path variable * of the specified type and if true checks whether it is changed. * In the case of it is changed all other build path variables of that type are checked * and notification is sent. * If it is not changed, other build path variables are not checked * In the case of the given variable is not the build path one, this method does nothing */ protected void checkBuildPathVariable(IConfiguration configuration, int buildPathType, String varName, IEnvironmentVariable var){ StoredBuildPathEnvironmentContainer buildPathVars = getStoredBuildPathVariables(buildPathType); if(buildPathVars == null) return; if(buildPathVars.isVariableChanged(varName,var,configuration)){ EnvVarCollector cr = new EnvVarCollector(); cr.add(getVariables(configuration, true, false)); buildPathVars.synchronize(cr,configuration); notifyListeners(configuration, buildPathType); } } /* * performs a check of the build path variables of the specified type * for the given configuration given the set of the variables * defined for this configuration. * If the build variables are changed, the notification is sent */ protected void checkBuildPathVariables(IConfiguration configuration, int buildPathType, EnvVarCollector varSet){ StoredBuildPathEnvironmentContainer buildPathVars = getStoredBuildPathVariables(buildPathType); if(buildPathVars == null) return; if(buildPathVars.checkBuildPathChange(varSet,configuration)){ notifyListeners(configuration, buildPathType); } } /* * returns the container of the build variables of the specified type */ protected StoredBuildPathEnvironmentContainer getStoredBuildPathVariables(int buildPathType){ return buildPathType == IEnvVarBuildPath.BUILDPATH_LIBRARY ? getStoredLibraryBuildPathVariables() : getStoredIncludeBuildPathVariables(); } /* * returns the container of the Include path variables */ protected StoredBuildPathEnvironmentContainer getStoredIncludeBuildPathVariables(){ if(fIncludeStoredBuildPathVariables == null) fIncludeStoredBuildPathVariables = new StoredBuildPathEnvironmentContainer(IEnvVarBuildPath.BUILDPATH_INCLUDE); return fIncludeStoredBuildPathVariables; } /* * returns the container of the Library path variables */ protected StoredBuildPathEnvironmentContainer getStoredLibraryBuildPathVariables(){ if(fLibraryStoredBuildPathVariables == null) fLibraryStoredBuildPathVariables = new StoredBuildPathEnvironmentContainer(IEnvVarBuildPath.BUILDPATH_LIBRARY); return fLibraryStoredBuildPathVariables; } }