blob: 22c3059d5dda97b298ef2917d76992c9d70ba80c [file] [log] [blame]
/*******************************************************************************
* 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();
}
}
}