/******************************************************************************* * Copyright (c) 2000, 2016 IBM 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.dltk.core; import java.util.HashMap; import java.util.Iterator; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.dltk.internal.core.ChangeBuildpathOperation; import org.eclipse.dltk.internal.core.ModelManager; import org.eclipse.dltk.internal.core.ScriptProject; public class SetVariablesOperation extends ChangeBuildpathOperation { String[] variableNames; IPath[] variablePaths; boolean updatePreferences; /* * Creates a new SetVariablesOperation for the given variable values (null * path meaning removal), allowing to change multiple variable values at * once. */ public SetVariablesOperation(String[] variableNames, IPath[] variablePaths, boolean updatePreferences) { super( new IModelElement[] { ModelManager.getModelManager().getModel() }, !ResourcesPlugin.getWorkspace().isTreeLocked()); this.variableNames = variableNames; this.variablePaths = variablePaths; this.updatePreferences = updatePreferences; } @Override protected void executeOperation() throws ModelException { checkCanceled(); try { beginTask("", 1); //$NON-NLS-1$ ModelManager manager = ModelManager.getModelManager(); if (manager.variablePutIfInitializingWithSameValue( this.variableNames, this.variablePaths)) return; int varLength = this.variableNames.length; // gather Buildpath information for updating final HashMap affectedProjectBuildpaths = new HashMap(5); IScriptModel model = getModel(); // filter out unmodified variables int discardCount = 0; for (int i = 0; i < varLength; i++) { String variableName = this.variableNames[i]; IPath oldPath = manager.variableGet(variableName); // if // reentering // will // provide // previous // session // value if (oldPath == ModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS) { oldPath = null; // 33695 - cannot filter out restored // variable, must update affected project to // reset cached CP } if (oldPath != null && oldPath.equals(this.variablePaths[i])) { this.variableNames[i] = null; discardCount++; } } if (discardCount > 0) { if (discardCount == varLength) return; int changedLength = varLength - discardCount; String[] changedVariableNames = new String[changedLength]; IPath[] changedVariablePaths = new IPath[changedLength]; for (int i = 0, index = 0; i < varLength; i++) { if (this.variableNames[i] != null) { changedVariableNames[index] = this.variableNames[i]; changedVariablePaths[index] = this.variablePaths[i]; index++; } } this.variableNames = changedVariableNames; this.variablePaths = changedVariablePaths; varLength = changedLength; } if (isCanceled()) return; IScriptProject[] projects = model.getScriptProjects(); nextProject: for (int i = 0, projectLength = projects.length; i < projectLength; i++) { ScriptProject project = (ScriptProject) projects[i]; // check to see if any of the modified variables is present on // the Buildpath IBuildpathEntry[] Buildpath = project.getRawBuildpath(); for (int j = 0, cpLength = Buildpath.length; j < cpLength; j++) { IBuildpathEntry entry = Buildpath[j]; for (int k = 0; k < varLength; k++) { String variableName = this.variableNames[k]; if (entry.getEntryKind() == IBuildpathEntry.BPE_VARIABLE) { if (variableName.equals(entry.getPath().segment(0))) { affectedProjectBuildpaths.put(project, project .getResolvedBuildpath()); continue nextProject; } IPath sourcePath, sourceRootPath; if (((sourcePath = entry.getPath()) != null && variableName .equals(sourcePath.segment(0))) || ((sourceRootPath = entry.getPath()) != null && variableName .equals(sourceRootPath.segment(0)))) { affectedProjectBuildpaths.put(project, project .getResolvedBuildpath()); continue nextProject; } } } } } // update variables for (int i = 0; i < varLength; i++) { manager.variablePut(this.variableNames[i], this.variablePaths[i]); if (this.updatePreferences) manager.variablePreferencesPut(this.variableNames[i], this.variablePaths[i]); } // update affected project Buildpaths if (!affectedProjectBuildpaths.isEmpty()) { try { // propagate Buildpath change Iterator projectsToUpdate = affectedProjectBuildpaths .keySet().iterator(); while (projectsToUpdate.hasNext()) { if (this.progressMonitor != null && this.progressMonitor.isCanceled()) return; ScriptProject affectedProject = (ScriptProject) projectsToUpdate .next(); if (this.canChangeResources) { // touch project to force a build if needed affectedProject.getProject().touch( this.progressMonitor); } } } catch (CoreException e) { if (ModelManager.BP_RESOLVE_VERBOSE /* * ||ModelManager. * CP_RESOLVE_VERBOSE_FAILURE */) { e.printStackTrace(); } if (e instanceof ModelException) { throw (ModelException) e; } else { throw new ModelException(e); } } } } finally { done(); } } }