blob: 7b862f22239fc34d842c5a122f428508a645771d [file] [log] [blame]
/*
* Copyright (c) 2014-2016 Eike Stepper (Berlin, Germany) 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:
* Eike Stepper - initial API and implementation
* Ericsson AB (Julian Enoch) - Bug 425815 - Add support for secure context variables
* Ericsson AB (Julian Enoch) - Bug 434525 - Allow prompted variables to be pre-populated
*/
package org.eclipse.oomph.setup.internal.core;
import org.eclipse.oomph.base.Annotation;
import org.eclipse.oomph.base.BaseFactory;
import org.eclipse.oomph.base.ModelElement;
import org.eclipse.oomph.base.provider.BaseEditUtil;
import org.eclipse.oomph.base.util.BaseUtil;
import org.eclipse.oomph.internal.setup.SetupPrompter;
import org.eclipse.oomph.internal.setup.SetupProperties;
import org.eclipse.oomph.p2.P2Factory;
import org.eclipse.oomph.p2.Repository;
import org.eclipse.oomph.p2.Requirement;
import org.eclipse.oomph.p2.core.Profile;
import org.eclipse.oomph.p2.internal.core.CacheUsageConfirmer;
import org.eclipse.oomph.preferences.util.PreferencesUtil;
import org.eclipse.oomph.setup.AnnotationConstants;
import org.eclipse.oomph.setup.AttributeRule;
import org.eclipse.oomph.setup.CompoundTask;
import org.eclipse.oomph.setup.EAnnotationConstants;
import org.eclipse.oomph.setup.EclipseIniTask;
import org.eclipse.oomph.setup.Installation;
import org.eclipse.oomph.setup.InstallationTask;
import org.eclipse.oomph.setup.PreferenceTask;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.ProductCatalog;
import org.eclipse.oomph.setup.ProductVersion;
import org.eclipse.oomph.setup.Project;
import org.eclipse.oomph.setup.ProjectCatalog;
import org.eclipse.oomph.setup.RedirectionTask;
import org.eclipse.oomph.setup.ResourceCopyTask;
import org.eclipse.oomph.setup.Scope;
import org.eclipse.oomph.setup.ScopeType;
import org.eclipse.oomph.setup.SetupFactory;
import org.eclipse.oomph.setup.SetupPackage;
import org.eclipse.oomph.setup.SetupTask;
import org.eclipse.oomph.setup.SetupTaskContainer;
import org.eclipse.oomph.setup.SetupTaskContext;
import org.eclipse.oomph.setup.Stream;
import org.eclipse.oomph.setup.Trigger;
import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.VariableChoice;
import org.eclipse.oomph.setup.VariableTask;
import org.eclipse.oomph.setup.VariableType;
import org.eclipse.oomph.setup.Workspace;
import org.eclipse.oomph.setup.WorkspaceTask;
import org.eclipse.oomph.setup.impl.SetupTaskImpl;
import org.eclipse.oomph.setup.internal.core.util.Authenticator;
import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil;
import org.eclipse.oomph.setup.log.ProgressLog;
import org.eclipse.oomph.setup.log.ProgressLogFilter;
import org.eclipse.oomph.setup.log.ProgressLogMonitor;
import org.eclipse.oomph.setup.p2.P2Task;
import org.eclipse.oomph.setup.p2.SetupP2Factory;
import org.eclipse.oomph.setup.p2.impl.P2TaskImpl;
import org.eclipse.oomph.setup.util.StringExpander;
import org.eclipse.oomph.util.CollectionUtil;
import org.eclipse.oomph.util.IOUtil;
import org.eclipse.oomph.util.MonitorUtil;
import org.eclipse.oomph.util.OS;
import org.eclipse.oomph.util.ObjectUtil;
import org.eclipse.oomph.util.Pair;
import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.oomph.util.ReflectUtil;
import org.eclipse.oomph.util.StringUtil;
import org.eclipse.oomph.util.UserCallback;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.SegmentSequence;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Factory.Registry;
import org.eclipse.emf.ecore.resource.Resource.Internal;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.metadata.expression.LDAPFilter;
import org.eclipse.equinox.internal.p2.metadata.expression.Member;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
import org.eclipse.equinox.p2.metadata.expression.IExpressionVisitor;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Eike Stepper
*/
public class SetupTaskPerformer extends AbstractSetupTaskContext
{
public static final boolean REMOTE_DEBUG = PropertiesUtil.isProperty(SetupProperties.PROP_SETUP_REMOTE_DEBUG);
public static final boolean USER_HOME_REDIRECT = PropertiesUtil.isProperty(SetupProperties.PROP_SETUP_USER_HOME_REDIRECT);
public static final Adapter RULE_VARIABLE_ADAPTER = new AdapterImpl();
private static final Map<String, ValueConverter> CONVERTERS = new HashMap<String, ValueConverter>();
static
{
CONVERTERS.put("java.lang.String", new ValueConverter());
CONVERTERS.put("org.eclipse.emf.common.util.URI", new URIValueConverter());
}
private static final SimpleDateFormat DATE_TIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final Pattern INSTALLABLE_UNIT_WITH_RANGE_PATTERN = Pattern.compile("([^\\[\\(]*)(.*)");
private static final Pattern ATTRIBUTE_REFERENCE_PATTERN = Pattern.compile("@[\\p{Alpha}_][\\p{Alnum}_]*");
private static final ThreadLocal<IProgressMonitor> CREATION_MONITOR = new ThreadLocal<IProgressMonitor>();
private final Set<String> filterProperties = new LinkedHashSet<String>();
private ProgressLog progress;
private boolean canceled;
private boolean skipConfirmation;
private EList<SetupTask> triggeredSetupTasks;
private Map<EObject, EObject> copyMap;
private EList<SetupTask> neededSetupTasks;
private final Set<Bundle> bundles = new HashSet<Bundle>();
/**
* A list that contains instances of String and/or Pair<String, ProgressLog.Severity>.
*/
private List<Object> logMessageBuffer;
private PrintStream logStream;
private boolean logStreamError;
private final ProgressLogFilter logFilter = new ProgressLogFilter();
private IProgressMonitor progressMonitor;
private final List<EStructuralFeature.Setting> unresolvedSettings = new ArrayList<EStructuralFeature.Setting>();
private final List<VariableTask> passwordVariables = new ArrayList<VariableTask>();
private final Map<URI, String> passwords = new LinkedHashMap<URI, String>();
private final List<VariableTask> unresolvedVariables = new UniqueEList<VariableTask>();
private final List<VariableTask> resolvedVariables = new UniqueEList<VariableTask>();
private final List<VariableTask> appliedRuleVariables = new UniqueEList<VariableTask>();
private final Map<String, VariableTask> allVariables = new LinkedHashMap<String, VariableTask>();
private final Set<String> undeclaredVariables = new LinkedHashSet<String>();
private final Map<VariableTask, EAttribute> ruleAttributes = new LinkedHashMap<VariableTask, EAttribute>();
private final Map<VariableTask, EAttribute> ruleBasedAttributes = new LinkedHashMap<VariableTask, EAttribute>();
private final List<AttributeRule> attributeRules = new UniqueEList<AttributeRule>();
private final ComposedAdapterFactory adapterFactory = BaseEditUtil.createAdapterFactory();
private boolean hasSuccessfullyPerformed;
private File logFile;
public SetupTaskPerformer(URIConverter uriConverter, SetupPrompter prompter, Trigger trigger, SetupContext setupContext, Stream stream)
{
super(uriConverter, prompter, trigger, setupContext);
initTriggeredSetupTasks(stream, true);
}
public SetupTaskPerformer(URIConverter uriConverter, SetupPrompter prompter, Trigger trigger, SetupContext setupContext, EList<SetupTask> triggeredSetupTasks)
{
super(uriConverter, prompter, trigger, setupContext);
this.triggeredSetupTasks = triggeredSetupTasks;
initTriggeredSetupTasks(null, false);
}
public String getVMPath()
{
return getPrompter().getVMPath();
}
public boolean hasSuccessfullyPerformed()
{
return hasSuccessfullyPerformed;
}
/**
* @author Ed Merks
*/
private static enum Phase
{
FILTER_PHASE, GATHER_PHASE, COMPOSE_PHASE
}
private void initTriggeredSetupTasks(Stream stream, boolean firstPhase)
{
initTriggeredSetupTasks(stream, firstPhase ? Phase.FILTER_PHASE : Phase.COMPOSE_PHASE);
}
private void initTriggeredSetupTasks(Stream stream, Phase phase)
{
Trigger trigger = getTrigger();
User user = getUser();
Map<Object, Object> originalMap = new LinkedHashMap<Object, Object>(getMap());
SetupContext originalSetupContext = getSetupContext();
// Gather all possible tasks.
// Later this will be filtered to only the triggered tasks.
// This approach ensures that implicit variables for all tasks (even for untriggered tasks) are created with the right values.
if (phase != Phase.COMPOSE_PHASE)
{
triggeredSetupTasks = new BasicEList<SetupTask>(getSetupTasks(stream));
bundles.add(SetupCorePlugin.INSTANCE.getBundle());
// 1. Collect and flatten all tasks
Set<EClass> eClasses = new LinkedHashSet<EClass>();
Map<EClass, Set<SetupTask>> instances = new LinkedHashMap<EClass, Set<SetupTask>>();
Set<String> keys = new LinkedHashSet<String>();
for (SetupTask setupTask : triggeredSetupTasks)
{
try
{
Bundle bundle = FrameworkUtil.getBundle(setupTask.getClass());
if (bundle != null)
{
bundles.add(bundle);
}
}
catch (Throwable ex)
{
//$FALL-THROUGH$
}
EClass eClass = setupTask.eClass();
CollectionUtil.add(instances, eClass, setupTask);
eClasses.add(eClass);
for (EClass eSuperType : eClass.getEAllSuperTypes())
{
if (SetupPackage.Literals.SETUP_TASK.isSuperTypeOf(eSuperType))
{
eClasses.add(eSuperType);
CollectionUtil.add(instances, eSuperType, setupTask);
}
}
if (setupTask instanceof InstallationTask)
{
Resource resource = getInstallation().eResource();
if (resource != null)
{
URI uri = resource.getURI();
if (!SetupContext.INSTALLATION_SETUP_FILE_NAME_URI.equals(uri))
{
InstallationTask installationTask = (InstallationTask)setupTask;
installationTask.setLocation(uri.trimSegments(OS.INSTANCE.isMac() ? 6 : 4).toFileString());
}
}
}
else if (setupTask instanceof WorkspaceTask)
{
Resource resource = getWorkspace().eResource();
if (resource != null)
{
URI uri = resource.getURI();
if (!SetupContext.WORKSPACE_SETUP_FILE_NAME_URI.equals(uri))
{
WorkspaceTask workspaceTask = (WorkspaceTask)setupTask;
workspaceTask.setLocation(uri.trimSegments(4).toFileString());
}
}
}
else if (setupTask instanceof VariableTask)
{
VariableTask variable = (VariableTask)setupTask;
keys.add(variable.getName());
}
}
for (EClass eClass : eClasses)
{
// 1.1. Collect enablement info to synthesize P2Tasks that are placed at the head of the task list
EList<SetupTask> enablementTasks = createEnablementTasks(eClass, true);
if (enablementTasks != null)
{
triggeredSetupTasks.addAll(0, enablementTasks);
}
for (EAnnotation eAnnotation : eClass.getEAnnotations())
{
String source = eAnnotation.getSource();
if (EAnnotationConstants.ANNOTATION_VARIABLE.equals(source))
{
triggeredSetupTasks.add(0, createImpliedVariable(eAnnotation));
}
}
if (user.eResource() != null)
{
// 1.2. Determine whether new rules need to be created
for (EAttribute eAttribute : eClass.getEAttributes())
{
if (eAttribute.getEType().getInstanceClass() == String.class)
{
EAnnotation eAnnotation = eAttribute.getEAnnotation(EAnnotationConstants.ANNOTATION_VARIABLE);
if (eAnnotation != null && eAttribute.getEAnnotation(EAnnotationConstants.ANNOTATION_RULE_VARIABLE) != null)
{
AttributeRule attributeRule = getAttributeRule(eAttribute, true);
if (attributeRule == null)
{
// Determine if there exists an actual instance that really needs the rule.
String attributeName = ExtendedMetaData.INSTANCE.getName(eAttribute);
for (SetupTask setupTask : instances.get(eAttribute.getEContainingClass()))
{
// If there is an instance with an empty value.
Object value = setupTask.eGet(eAttribute);
if (value == null || "".equals(value))
{
// If that instance has an ID and hence will create an implied variable and that variable name isn't already defined by an existing
// context variable.
String id = setupTask.getID();
if (!StringUtil.isEmpty(id) && !keys.contains(id + "." + attributeName))
{
EMap<String, String> details = eAnnotation.getDetails();
// TODO class name/attribute name pairs might not be unique.
String variableName = getAttributeRuleVariableName(eAttribute);
VariableTask variable = SetupFactory.eINSTANCE.createVariableTask();
annotateAttributeRuleVariable(variable, eAttribute);
variable.setName(variableName);
variable.setType(VariableType.get(details.get("type")));
variable.setLabel(details.get("label"));
variable.setDescription(details.get("description"));
variable.eAdapters().add(RULE_VARIABLE_ADAPTER);
for (EAnnotation subAnnotation : eAnnotation.getEAnnotations())
{
if ("Choice".equals(subAnnotation.getSource()))
{
EMap<String, String> subDetails = subAnnotation.getDetails();
VariableChoice choice = SetupFactory.eINSTANCE.createVariableChoice();
choice.setValue(subDetails.get("value"));
choice.setLabel(subDetails.get("label"));
variable.getChoices().add(choice);
}
}
unresolvedVariables.add(variable);
ruleAttributes.put(variable, eAttribute);
}
}
break;
}
}
}
}
}
}
}
// 1.2.1. Prompt new rules and store them in User scope
SetupPrompter prompter = getPrompter();
prompter.promptVariables(Collections.singletonList(this));
recordRules(attributeRules, false);
}
if (!triggeredSetupTasks.isEmpty())
{
Map<SetupTask, SetupTask> substitutions = getSubstitutions(triggeredSetupTasks);
// Shorten the paths through the substitutions map
Map<SetupTask, SetupTask> directSubstitutions = new HashMap<SetupTask, SetupTask>(substitutions);
for (Map.Entry<SetupTask, SetupTask> entry : directSubstitutions.entrySet())
{
SetupTask task = entry.getValue();
for (;;)
{
SetupTask overridingTask = directSubstitutions.get(task);
if (overridingTask == null)
{
break;
}
entry.setValue(overridingTask);
task = overridingTask;
}
}
if (phase == Phase.COMPOSE_PHASE)
{
// Perform override merging.
Map<SetupTask, SetupTask> overrides = new HashMap<SetupTask, SetupTask>();
for (Map.Entry<SetupTask, SetupTask> entry : substitutions.entrySet())
{
SetupTask overriddenSetupTask = entry.getKey();
SetupTask overridingSetupTask = entry.getValue();
overrides.put(overriddenSetupTask, overridingSetupTask);
overridingSetupTask.overrideFor(overriddenSetupTask);
}
// Compute a hash code for each triggered task to avoid equality checking for tasks that definitely aren't equal.
int size = triggeredSetupTasks.size();
int[] hashCodes = new int[size];
for (int i = 0; i < size; ++i)
{
SetupTask setupTask = triggeredSetupTasks.get(i);
EClass eClass = setupTask.eClass();
int hashCode = eClass.hashCode();
for (EAttribute eAttribute : eClass.getEAllAttributes())
{
if (!eAttribute.isMany() && !eAttribute.isDerived())
{
Object value = setupTask.eGet(eAttribute);
if (value != null)
{
hashCode ^= value.hashCode();
}
}
}
hashCodes[i] = hashCode;
}
for (int i = size; --i >= 0;)
{
SetupTask setupTask = triggeredSetupTasks.get(i);
if (!directSubstitutions.containsKey(setupTask))
{
for (int j = i; --j >= 0;)
{
SetupTask otherSetupTask = triggeredSetupTasks.get(j);
// Only check equality if the rough hash codes are the same.
if (hashCodes[i] == hashCodes[j] && directSubstitutions.get(otherSetupTask) != setupTask)
{
// We must ignore specific references that are bound to be different, but don't affect what the task actually does.
EcoreUtil.EqualityHelper equalityHelper = new EcoreUtil.EqualityHelper()
{
private static final long serialVersionUID = 1L;
@Override
protected boolean haveEqualReference(EObject eObject1, EObject eObject2, EReference reference)
{
if (reference == SetupPackage.Literals.SETUP_TASK__PREDECESSORS || reference == SetupPackage.Literals.SETUP_TASK__SUCCESSORS
|| reference == SetupPackage.Literals.SETUP_TASK__RESTRICTIONS)
{
return true;
}
return super.haveEqualReference(eObject1, eObject2, reference);
}
};
if (equalityHelper.equals(setupTask, otherSetupTask))
{
directSubstitutions.put(otherSetupTask, setupTask);
overrides.put(setupTask, otherSetupTask);
setupTask.overrideFor(otherSetupTask);
}
}
}
}
}
EList<SetupTask> remainingSetupTasks = new UniqueEList.FastCompare<SetupTask>();
for (SetupTask setupTask : triggeredSetupTasks)
{
SetupTask overridingSetupTask = directSubstitutions.get(setupTask);
if (overridingSetupTask != null)
{
remainingSetupTasks.add(overridingSetupTask);
}
else
{
remainingSetupTasks.add(setupTask);
}
}
// Modify all predecessors to refer to the direct substitution.
for (SetupTask setupTask : remainingSetupTasks)
{
checkCancel();
EList<SetupTask> predecessors = setupTask.getPredecessors();
for (ListIterator<SetupTask> it = predecessors.listIterator(); it.hasNext();)
{
SetupTask predecessor = it.next();
SetupTask overridingSetupTask = directSubstitutions.get(predecessor);
if (overridingSetupTask != null)
{
if (predecessors.contains(overridingSetupTask))
{
it.remove();
}
else
{
it.set(overridingSetupTask);
}
}
}
}
// Modify all the predecessors to remove any that result in circularity.
for (SetupTask setupTask : remainingSetupTasks)
{
checkCancel();
EList<SetupTask> predecessors = setupTask.getPredecessors();
for (ListIterator<SetupTask> it = predecessors.listIterator(); it.hasNext();)
{
SetupTask predecessor = it.next();
if (((SetupTaskImpl)predecessor).requiresFast(setupTask))
{
it.remove();
}
}
}
triggeredSetupTasks = remainingSetupTasks;
}
else
{
// 2.2. Create copy based on overrides
copySetup(stream, triggeredSetupTasks, substitutions, directSubstitutions);
// 2.4. Build variable map in the context
Map<String, VariableTask> explicitKeys = new HashMap<String, VariableTask>();
for (SetupTask setupTask : triggeredSetupTasks)
{
if (setupTask instanceof VariableTask)
{
VariableTask variableTask = (VariableTask)setupTask;
String name = variableTask.getName();
explicitKeys.put(name, variableTask);
}
}
// 2.3. Create implied variables for annotated task attributes
for (ListIterator<SetupTask> it = triggeredSetupTasks.listIterator(); it.hasNext();)
{
SetupTask setupTask = it.next();
String id = setupTask.getID();
if (!StringUtil.isEmpty(id))
{
EClass eClass = setupTask.eClass();
for (EAttribute eAttribute : eClass.getEAllAttributes())
{
if (eAttribute != SetupPackage.Literals.SETUP_TASK__ID && !eAttribute.isMany() && eAttribute.getEType().getInstanceClass() == String.class)
{
String variableName = id + "." + ExtendedMetaData.INSTANCE.getName(eAttribute);
String value = (String)setupTask.eGet(eAttribute);
EAnnotation variableAnnotation = eAttribute.getEAnnotation(EAnnotationConstants.ANNOTATION_VARIABLE);
String variableReference = getVariableReference(variableName, variableAnnotation);
if (explicitKeys.containsKey(variableName))
{
if (StringUtil.isEmpty(value) || setupTask instanceof WorkspaceTask)
{
if (variableAnnotation != null)
{
setupTask.eSet(eAttribute, variableReference);
}
}
}
else
{
VariableTask variable = SetupFactory.eINSTANCE.createVariableTask();
annotateImpliedVariable(variable, setupTask, eAttribute);
variable.setName(variableName);
EObject eContainer = setupTask.eContainer();
EReference eContainmentFeature = setupTask.eContainmentFeature();
@SuppressWarnings("unchecked")
EList<SetupTask> list = (EList<SetupTask>)eContainer.eGet(eContainmentFeature);
list.add(variable);
if (StringUtil.isEmpty(value))
{
if (variableAnnotation != null)
{
ruleBasedAttributes.put(variable, eAttribute);
populateImpliedVariable(setupTask, eAttribute, variableAnnotation, variable);
setupTask.eSet(eAttribute, variableReference);
}
else if (eAttribute == SetupPackage.Literals.INSTALLATION_TASK__RELATIVE_PRODUCT_FOLDER)
{
value = getRelativeProductFolder();
variable.setValue(value);
}
}
else
{
if (variableAnnotation != null)
{
populateImpliedVariable(setupTask, null, variableAnnotation, variable);
setupTask.eSet(eAttribute, variableReference);
}
variable.setValue(value);
}
it.add(variable);
explicitKeys.put(variableName, variable);
for (EAnnotation ruleVariableAnnotation : eAttribute.getEAnnotations())
{
if (EAnnotationConstants.ANNOTATION_RULE_VARIABLE.equals(ruleVariableAnnotation.getSource()))
{
EMap<String, String> details = ruleVariableAnnotation.getDetails();
VariableTask ruleVariable = SetupFactory.eINSTANCE.createVariableTask();
annotateRuleVariable(ruleVariable, variable);
String ruleVariableName = details.get(EAnnotationConstants.KEY_NAME);
ruleVariable.setName(ruleVariableName);
ruleVariable.setStorageURI(BaseFactory.eINSTANCE.createURI(details.get(EAnnotationConstants.KEY_STORAGE_URI)));
populateImpliedVariable(setupTask, null, ruleVariableAnnotation, ruleVariable);
it.add(ruleVariable);
explicitKeys.put(ruleVariableName, ruleVariable);
}
}
// If the variable is a self reference.
if (variableAnnotation != null)
{
String variableValue = variable.getValue();
if (variableReference.equals(variableValue) || getVariableReference(variableName, null).equals(variableValue))
{
EMap<String, String> details = variableAnnotation.getDetails();
VariableTask explicitVariable = SetupFactory.eINSTANCE.createVariableTask();
String explicitVariableName = variableName + ".explicit";
explicitVariable.setName(explicitVariableName);
explicitVariable.setStorageURI(null);
explicitVariable.setType(VariableType.get(details.get(EAnnotationConstants.KEY_EXPLICIT_TYPE)));
explicitVariable.setLabel(expandAttributeReferences(setupTask, details.get(EAnnotationConstants.KEY_EXPLICIT_LABEL)));
explicitVariable.setDescription(expandAttributeReferences(setupTask, details.get(EAnnotationConstants.KEY_EXPLICIT_DESCRIPTION)));
it.add(explicitVariable);
explicitKeys.put(explicitVariableName, explicitVariable);
annotateRuleVariable(explicitVariable, variable);
variable.setValue(getVariableReference(explicitVariableName, variableAnnotation));
}
}
}
}
}
}
}
for (SetupTask setupTask : triggeredSetupTasks)
{
handleActiveAnnotations(setupTask, explicitKeys);
}
// 2.4. Build variable map in the context
Set<String> keys = new LinkedHashSet<String>();
boolean fullPromptUser = isFullPromptUser(user);
VariableAdapter variableAdapter = new VariableAdapter(this);
for (SetupTask setupTask : triggeredSetupTasks)
{
if (setupTask instanceof VariableTask)
{
VariableTask variable = (VariableTask)setupTask;
variable.eAdapters().add(variableAdapter);
String name = variable.getName();
keys.add(name);
String value = variable.getValue();
if (isFilterProperty(variable) && StringUtil.isEmpty(value))
{
unresolvedVariables.add(variable);
}
// If it's not a full prompt user, we want to be sure we get the value from the variable page.
if (!fullPromptUser)
{
// But don't do that for implied variables.
if (variable.getAnnotation("ImpliedVariable") == null)
{
String promptedValue = getPrompter().getValue(variable);
if (promptedValue != null)
{
variable.setValue(promptedValue);
value = null;
}
}
}
if (variable.getType() == VariableType.PASSWORD)
{
passwordVariables.add(variable);
if (StringUtil.isEmpty(value) && !fullPromptUser)
{
URI storageURI = getEffectiveStorage(variable);
if (storageURI != null && PreferencesUtil.PREFERENCE_SCHEME.equals(storageURI.scheme()))
{
URIConverter uriConverter = getURIConverter();
if (uriConverter.exists(storageURI, null))
{
try
{
Reader reader = ((URIConverter.ReadableInputStream)uriConverter.createInputStream(storageURI)).asReader();
StringBuilder result = new StringBuilder();
for (int character = reader.read(); character != -1; character = reader.read())
{
result.append((char)character);
}
reader.close();
value = PreferencesUtil.encrypt(result.toString());
}
catch (IOException ex)
{
SetupCorePlugin.INSTANCE.log(ex);
}
}
}
}
}
put(name, value);
allVariables.put(name, variable);
}
}
expandVariableKeys(keys, true);
// 2.8. Expand task attributes in situ
expandStrings(triggeredSetupTasks);
flattenPredecessorsAndSuccessors(triggeredSetupTasks);
propagateRestrictionsPredecessorsAndSuccessors(triggeredSetupTasks);
}
reorderSetupTasks(triggeredSetupTasks);
// Filter out the tasks that aren't triggered.
if (trigger != null)
{
for (Iterator<SetupTask> it = triggeredSetupTasks.iterator(); it.hasNext();)
{
if (!it.next().getTriggers().contains(trigger))
{
it.remove();
}
}
}
boolean hasFilterProperty = false;
for (Iterator<SetupTask> it = triggeredSetupTasks.iterator(); it.hasNext();)
{
SetupTask setupTask = it.next();
setupTask.consolidate();
if (setupTask instanceof VariableTask)
{
VariableTask variable = (VariableTask)setupTask;
if (phase == Phase.FILTER_PHASE)
{
if (isFilterProperty(variable))
{
String value = variable.getValue();
if (!StringUtil.isEmpty(value))
{
putFilterProperty(variable.getName(), value);
}
hasFilterProperty = true;
}
}
if (!unresolvedVariables.contains(variable))
{
resolvedVariables.add(variable);
}
it.remove();
}
}
if (hasFilterProperty)
{
allVariables.clear();
appliedRuleVariables.clear();
attributeRules.clear();
bundles.clear();
copyMap = null;
originalMap.keySet().retainAll(originalMap.keySet());
originalMap.putAll(originalMap);
passwords.clear();
passwordVariables.clear();
resolvedVariables.clear();
ruleAttributes.clear();
ruleBasedAttributes.clear();
undeclaredVariables.clear();
unresolvedSettings.clear();
unresolvedVariables.clear();
setSetupContext(originalSetupContext);
initTriggeredSetupTasks(stream, Phase.GATHER_PHASE);
}
}
}
private String getAttributeRuleVariableName(EAttribute eAttribute)
{
String attributeName = ExtendedMetaData.INSTANCE.getName(eAttribute);
String variableName = "@<id>." + eAttribute.getEContainingClass() + "." + attributeName;
return variableName;
}
private void handleActiveAnnotations(SetupTask setupTask, Map<String, VariableTask> explicitKeys)
{
for (Annotation annotation : setupTask.getAnnotations())
{
String source = annotation.getSource();
if (AnnotationConstants.ANNOTATION_INHERITED_CHOICES.equals(source) && setupTask instanceof VariableTask)
{
VariableTask variableTask = (VariableTask)setupTask;
EList<VariableChoice> choices = variableTask.getChoices();
EMap<String, String> details = annotation.getDetails();
String inherit = details.get(AnnotationConstants.KEY_INHERIT);
if (inherit != null)
{
for (String variableName : inherit.trim().split("\\s"))
{
VariableTask referencedVariableTask = explicitKeys.get(variableName);
if (referencedVariableTask != null)
{
for (VariableChoice variableChoice : referencedVariableTask.getChoices())
{
String value = variableChoice.getValue();
String label = variableChoice.getLabel();
for (Map.Entry<String, String> detail : annotation.getDetails().entrySet())
{
String detailKey = detail.getKey();
String detailValue = detail.getValue();
if (detailKey != null && !AnnotationConstants.KEY_INHERIT.equals(detailKey) && detailValue != null)
{
String target = "@{" + detailKey + "}";
if (value != null)
{
value = value.replace(target, detailValue);
}
if (label != null)
{
label = label.replace(target, detailValue);
}
}
}
VariableChoice choice = SetupFactory.eINSTANCE.createVariableChoice();
choice.setValue(value);
choice.setLabel(label);
choice.getAnnotations().addAll(EcoreUtil.copyAll(variableChoice.getAnnotations()));
choices.add(choice);
}
}
}
}
}
else if (AnnotationConstants.ANNOTATION_INDUCED_CHOICES.equals(source))
{
String id = setupTask.getID();
if (id != null)
{
EMap<String, String> details = annotation.getDetails();
String inherit = details.get(AnnotationConstants.KEY_INHERIT);
String target = details.get(AnnotationConstants.KEY_TARGET);
if (target != null && inherit != null)
{
EStructuralFeature eStructuralFeature = BaseUtil.getFeature(setupTask.eClass(), target);
if (eStructuralFeature != null && eStructuralFeature.getEType().getInstanceClass() == String.class)
{
VariableTask variableTask = explicitKeys.get(id + "." + target);
if (variableTask != null)
{
EList<VariableChoice> targetChoices = variableTask.getChoices();
if (!targetChoices.isEmpty())
{
if (!StringUtil.isEmpty(variableTask.getValue()))
{
setupTask.eSet(eStructuralFeature, getVariableReference(variableTask.getName(), null));
}
}
else
{
EList<VariableChoice> choices = targetChoices;
Map<String, String> substitutions = new LinkedHashMap<String, String>();
for (Map.Entry<String, String> detail : annotation.getDetails().entrySet())
{
String detailKey = detail.getKey();
String detailValue = detail.getValue();
if (detailKey != null && !AnnotationConstants.KEY_INHERIT.equals(detailKey) && !AnnotationConstants.KEY_TARGET.equals(detailKey)
&& !AnnotationConstants.KEY_LABEL.equals(detailKey) && !AnnotationConstants.KEY_DESCRIPTION.equals(detailKey) && detailValue != null)
{
if (detailValue.startsWith("@"))
{
String featureName = detailValue.substring(1);
EStructuralFeature referencedEStructuralFeature = BaseUtil.getFeature(setupTask.eClass(), featureName);
if (referencedEStructuralFeature != null && referencedEStructuralFeature.getEType().getInstanceClass() == String.class
&& !referencedEStructuralFeature.isMany())
{
Object value = setupTask.eGet(referencedEStructuralFeature);
if (value != null)
{
detailValue = value.toString();
}
}
}
substitutions.put("@{" + detailKey + "}", detailValue);
}
}
for (EAttribute eAttribute : setupTask.eClass().getEAllAttributes())
{
if (eAttribute.getEType().getInstanceClass() == String.class && !eAttribute.isMany())
{
String value = (String)setupTask.eGet(eAttribute);
if (!StringUtil.isEmpty(value))
{
substitutions.put("@{" + ExtendedMetaData.INSTANCE.getName(eAttribute) + "}", value);
}
}
}
String inheritedLabel = null;
String inheritedDescription = null;
for (String variableName : inherit.trim().split("\\s"))
{
VariableTask referencedVariableTask = explicitKeys.get(variableName);
if (referencedVariableTask != null)
{
if (inheritedLabel == null)
{
inheritedLabel = referencedVariableTask.getLabel();
}
if (inheritedDescription == null)
{
inheritedDescription = referencedVariableTask.getDescription();
}
for (VariableChoice variableChoice : referencedVariableTask.getChoices())
{
String value = variableChoice.getValue();
String label = variableChoice.getLabel();
for (Map.Entry<String, String> detail : substitutions.entrySet())
{
String detailKey = detail.getKey();
String detailValue = detail.getValue();
if (value != null)
{
value = value.replace(detailKey, detailValue);
}
if (label != null)
{
label = label.replace(detailKey, detailValue);
}
}
VariableChoice choice = SetupFactory.eINSTANCE.createVariableChoice();
choice.setValue(value);
choice.setLabel(label);
choice.getAnnotations().addAll(EcoreUtil.copyAll(variableChoice.getAnnotations()));
choices.add(choice);
}
}
}
if (ObjectUtil.equals(setupTask.eGet(eStructuralFeature), variableTask.getValue()))
{
String explicitLabel = details.get(AnnotationConstants.KEY_LABEL);
if (explicitLabel == null)
{
explicitLabel = inheritedLabel;
}
String explicitDescription = details.get(AnnotationConstants.KEY_DESCRIPTION);
if (explicitDescription == null)
{
explicitDescription = inheritedDescription;
}
variableTask.setValue(null);
variableTask.setLabel(explicitLabel);
variableTask.setDescription(explicitDescription);
}
setupTask.eSet(eStructuralFeature, getVariableReference(variableTask.getName(), null));
}
}
}
}
}
}
}
}
private void recordRules(List<AttributeRule> attributeRules, boolean remove)
{
for (Iterator<VariableTask> it = unresolvedVariables.iterator(); it.hasNext();)
{
VariableTask variable = it.next();
String value = variable.getValue();
if (value != null)
{
String variableName = variable.getName();
for (Map.Entry<VariableTask, EAttribute> entry : ruleAttributes.entrySet())
{
if (variableName.equals(entry.getKey().getName()))
{
URI uri = getAttributeURI(entry.getValue());
AttributeRule attributeRule = null;
for (AttributeRule existingAttributeRule : attributeRules)
{
if (uri.equals(existingAttributeRule.getAttributeURI()))
{
attributeRule = existingAttributeRule;
break;
}
}
if (attributeRule == null)
{
attributeRule = SetupFactory.eINSTANCE.createAttributeRule();
attributeRule.setAttributeURI(uri);
}
attributeRule.setValue(value);
attributeRules.add(attributeRule);
if (remove)
{
it.remove();
}
break;
}
}
}
}
}
private void annotateAttributeRuleVariable(VariableTask variable, EAttribute eAttribute)
{
annotate(variable, "AttributeRuleVariable", eAttribute);
}
public EAttribute getAttributeRuleVariableData(VariableTask variable)
{
Annotation annotation = variable.getAnnotation("AttributeRuleVariable");
if (annotation != null)
{
return (EAttribute)annotation.getReferences().get(0);
}
return null;
}
private void annotateImpliedVariable(VariableTask variable, SetupTask setupTask, EAttribute eAttribute)
{
annotate(variable, "ImpliedVariable", setupTask, eAttribute);
}
public EStructuralFeature.Setting getImpliedVariableData(VariableTask variable)
{
Annotation annotation = variable.getAnnotation("ImpliedVariable");
if (annotation != null)
{
EList<EObject> references = annotation.getReferences();
InternalEObject setupTask = (InternalEObject)references.get(0);
return setupTask.eSetting((EStructuralFeature)references.get(1));
}
return null;
}
private void annotateRuleVariable(VariableTask variable, VariableTask dependentVariable)
{
annotate(variable, "RuleVariable", dependentVariable);
}
public VariableTask getRuleVariableData(VariableTask variable)
{
Annotation annotation = variable.getAnnotation("RuleVariable");
if (annotation != null)
{
return (VariableTask)annotation.getReferences().get(0);
}
return null;
}
private void annotate(ModelElement modelElement, String source, EObject... references)
{
Annotation annotation = BaseFactory.eINSTANCE.createAnnotation();
annotation.setSource(source);
annotation.getReferences().addAll(Arrays.asList(references));
modelElement.getAnnotations().add(annotation);
}
private VariableTask createImpliedVariable(EAnnotation eAnnotation)
{
EMap<String, String> details = eAnnotation.getDetails();
VariableTask variable = SetupFactory.eINSTANCE.createVariableTask();
variable.setName(details.get(EAnnotationConstants.KEY_NAME));
populateImpliedVariable(null, null, eAnnotation, variable);
return variable;
}
private void populateImpliedVariable(SetupTask setupTask, EAttribute eAttribute, EAnnotation eAnnotation, VariableTask variable)
{
EMap<String, String> details = eAnnotation.getDetails();
variable.setType(VariableType.get(details.get(EAnnotationConstants.KEY_TYPE)));
variable.setLabel(expandAttributeReferences(setupTask, details.get(EAnnotationConstants.KEY_LABEL)));
variable.setDescription(expandAttributeReferences(setupTask, details.get(EAnnotationConstants.KEY_DESCRIPTION)));
variable.setDefaultValue(expandAttributeReferences(setupTask, details.get(EAnnotationConstants.KEY_DEFAULT_VALUE)));
// The storageURI remains the default unless there is an explicit key to specify it be null or whatever else is specified.
if (details.containsKey(EAnnotationConstants.KEY_STORAGE_URI))
{
String storageURIValue = expandAttributeReferences(setupTask, details.get(EAnnotationConstants.KEY_STORAGE_URI));
variable.setStorageURI(StringUtil.isEmpty(storageURIValue) ? null : URI.createURI(storageURIValue));
}
if (eAttribute != null)
{
AttributeRule attributeRule = getAttributeRule(eAttribute, false);
if (attributeRule != null)
{
String value = attributeRule.getValue();
VariableTask ruleVariable = getRuleVariable(variable);
if (ruleVariable == null)
{
ruleVariable = SetupFactory.eINSTANCE.createVariableTask();
ruleVariable.setName(getAttributeRuleVariableName(eAttribute));
}
VariableType explicitVariableType = VariableType.get(details.get(EAnnotationConstants.KEY_EXPLICIT_TYPE));
if (explicitVariableType != null)
{
variable.setType(explicitVariableType);
}
String explicitLabel = details.get(EAnnotationConstants.KEY_EXPLICIT_LABEL);
variable.setLabel(expandAttributeReferences(setupTask, explicitLabel));
String explicitDescription = details.get(EAnnotationConstants.KEY_EXPLICIT_DESCRIPTION);
variable.setDescription(expandAttributeReferences(setupTask, explicitDescription));
String promptedValue = getPrompter().getValue(ruleVariable);
if (promptedValue != null)
{
value = promptedValue;
}
String attributeExpandedValue = expandAttributeReferences(setupTask, value);
variable.setValue(attributeExpandedValue);
// We must remember this applied rule in the preferences restricted to this workspace.
appliedRuleVariables.add(variable);
return;
}
}
// Handle variable choices
for (EAnnotation subAnnotation : eAnnotation.getEAnnotations())
{
if (EAnnotationConstants.NESTED_ANNOTATION_CHOICE.equals(subAnnotation.getSource()))
{
EMap<String, String> subDetails = subAnnotation.getDetails();
VariableChoice choice = SetupFactory.eINSTANCE.createVariableChoice();
String subValue = expandAttributeReferences(setupTask, subDetails.get(EAnnotationConstants.KEY_VALUE));
choice.setValue(subValue);
choice.setLabel(subDetails.get(EAnnotationConstants.KEY_LABEL));
variable.getChoices().add(choice);
}
}
}
private String expandAttributeReferences(SetupTask setupTask, String value)
{
if (setupTask == null || value == null)
{
return value;
}
EClass eClass = setupTask.eClass();
Matcher matcher = ATTRIBUTE_REFERENCE_PATTERN.matcher(value);
StringBuilder builder = new StringBuilder();
int index = 0;
for (; matcher.find(); index = matcher.end())
{
builder.append(value, index, matcher.start());
String key = matcher.group().substring(1);
EStructuralFeature feature = eClass.getEStructuralFeature(key);
if (feature == null)
{
feature = BaseUtil.getFeature(eClass, key);
if (feature == null)
{
builder.append('@');
builder.append(key);
continue;
}
}
Object featureValue = setupTask.eGet(feature);
builder.append(featureValue);
}
builder.append(value, index, value.length());
return builder.toString();
}
private AttributeRule getAttributeRule(EAttribute eAttribute, boolean userOnly)
{
URI attributeURI = getAttributeURI(eAttribute);
User user = getUser();
AttributeRule attributeRule = userOnly ? null : getAttributeRule(attributeURI, attributeRules);
if (attributeRule == null)
{
attributeRule = getAttributeRule(attributeURI, user.getAttributeRules());
}
return attributeRule;
}
private AttributeRule getAttributeRule(URI attributeURI, List<AttributeRule> attributeRules)
{
for (AttributeRule attributeRule : attributeRules)
{
if (attributeURI.equals(attributeRule.getAttributeURI()))
{
return attributeRule;
}
}
return null;
}
public static URI getAttributeURI(EAttribute eAttribute)
{
EClass eClass = eAttribute.getEContainingClass();
EPackage ePackage = eClass.getEPackage();
URI uri = URI.createURI(ePackage.getNsURI()).appendFragment("//" + eClass.getName() + "/" + eAttribute.getName());
return uri;
}
public Set<Bundle> getBundles()
{
return bundles;
}
public EList<SetupTask> getTriggeredSetupTasks()
{
return triggeredSetupTasks;
}
public ExecutableInfo getExecutableInfo()
{
return new ExecutableInfo(this);
}
public File getLogFile()
{
return logFile;
}
public File getInstallationLocation()
{
for (SetupTask setupTask : triggeredSetupTasks)
{
if (setupTask instanceof InstallationTask)
{
return new File(((InstallationTask)setupTask).getLocation());
}
}
return null;
}
public File getWorkspaceLocation()
{
for (SetupTask setupTask : triggeredSetupTasks)
{
if (setupTask instanceof WorkspaceTask)
{
return new File(((WorkspaceTask)setupTask).getLocation());
}
}
if (getTrigger() != Trigger.BOOTSTRAP && EMFPlugin.IS_RESOURCES_BUNDLE_AVAILABLE)
{
IWorkspace workspace = ResourcesPlugin.getWorkspace();
if (workspace != null)
{
IWorkspaceRoot root = workspace.getRoot();
if (root != null)
{
IPath location = root.getLocation();
if (location != null)
{
return location.toFile();
}
}
}
}
return null;
}
public EList<SetupTask> getSetupTasks(Stream stream)
{
EList<SetupTask> result = new BasicEList<SetupTask>();
addBootstrapTasks(result);
User user = getUser();
Installation installation = getInstallation();
Workspace workspace = getWorkspace();
ProductVersion productVersion = installation.getProductVersion();
if (productVersion != null && !productVersion.eIsProxy())
{
List<Scope> configurableItems = new ArrayList<Scope>();
List<Scope> scopes = new ArrayList<Scope>();
Product product = productVersion.getProduct();
configurableItems.add(product);
scopes.add(product);
ProductCatalog productCatalog = product.getProductCatalog();
configurableItems.add(productCatalog);
scopes.add(0, productCatalog);
configurableItems.add(productVersion);
scopes.add(productVersion);
if (stream != null)
{
Project project = stream.getProject();
ProjectCatalog projectCatalog = project.getProjectCatalog();
for (; project != null; project = project.getParentProject())
{
configurableItems.add(project);
scopes.add(3, project);
}
if (projectCatalog != null)
{
configurableItems.add(projectCatalog);
scopes.add(3, projectCatalog);
}
configurableItems.add(stream);
scopes.add(stream);
}
scopes.add(user);
configurableItems.add(installation);
scopes.add(installation);
if (workspace != null)
{
configurableItems.add(workspace);
scopes.add(workspace);
}
String qualifier = null;
Scope rootProject = null;
for (Scope scope : scopes)
{
gatherFilters(configurableItems, scope);
}
for (Scope scope : scopes)
{
ScopeType type = scope.getType();
String name = scope.getName();
String label = scope.getLabel();
if (label == null)
{
label = name;
}
String description = scope.getDescription();
if (description == null)
{
description = label;
}
switch (type)
{
case PRODUCT_CATALOG:
{
generateScopeVariables(result, "product.catalog", qualifier, name, label, description);
qualifier = name;
break;
}
case PRODUCT:
{
generateScopeVariables(result, "product", qualifier, name, label, description);
qualifier += "." + name;
break;
}
case PRODUCT_VERSION:
{
generateScopeVariables(result, "product.version", qualifier, name, label, description);
qualifier = null;
break;
}
case PROJECT_CATALOG:
{
generateScopeVariables(result, "project.catalog", qualifier, name, label, description);
qualifier = name;
break;
}
case PROJECT:
{
generateScopeVariables(result, "project", qualifier, name, label, description);
if (rootProject == null && scope.eResource() == stream.eResource())
{
rootProject = scope;
generateScopeVariables(result, "project.root", qualifier, name, label, description);
}
qualifier += "." + name;
break;
}
case STREAM:
{
generateScopeVariables(result, "project.stream", qualifier, name, label, description);
qualifier = null;
break;
}
case INSTALLATION:
{
generateScopeVariables(result, "installation", qualifier, name, label, description);
break;
}
case WORKSPACE:
{
generateScopeVariables(result, "workspace", qualifier, name, label, description);
break;
}
case USER:
{
generateScopeVariables(result, "user", qualifier, name, label, description);
break;
}
}
getSetupTasks(result, configurableItems, scope, false);
}
}
return result;
}
private void addBootstrapTasks(EList<SetupTask> result)
{
addEclipseIniTask(result, false, "--launcher.appendVmargs", null);
String vmPath = getVMPath();
if (vmPath != null)
{
addEclipseIniTask(result, false, "-vm", vmPath);
}
String maxThreads = PropertiesUtil.getProperty(SimpleArtifactRepository.PROP_MAX_THREADS);
if (maxThreads != null)
{
addEclipseIniTask(result, true, "-D" + SimpleArtifactRepository.PROP_MAX_THREADS, "=" + maxThreads);
}
addEclipseIniTask(result, true, "-D" + SetupProperties.PROP_UPDATE_URL, "=" + redirect(URI.createURI((String)get(SetupProperties.PROP_UPDATE_URL))));
addIndexRedirection(result, SetupContext.INDEX_SETUP_URI, "");
addIndexRedirection(result, SetupContext.INDEX_SETUP_LOCATION_URI, ".location");
addIndexRedirection(result, SetupContext.INDEX_SETUP_ARCHIVE_LOCATION_URI, ".archive.location");
if (REMOTE_DEBUG)
{
addEclipseIniTask(result, true, "-D" + SetupProperties.PROP_SETUP_REMOTE_DEBUG, "=true");
addEclipseIniTask(result, true, "-Xdebug", "");
addEclipseIniTask(result, true, "-Xrunjdwp:transport", "=dt_socket,server=y,suspend=n,address=8123");
}
if (USER_HOME_REDIRECT)
{
addEclipseIniTask(result, true, "-Duser.home", "=" + PropertiesUtil.getUserHome());
}
}
private void addIndexRedirection(EList<SetupTask> result, URI indexURI, String name)
{
URI redirectedURI = redirect(indexURI);
if (!redirectedURI.equals(indexURI))
{
URI baseURI = indexURI.trimSegments(1).appendSegment("");
URI redirectedBaseURI = redirect(baseURI);
if (!redirectedBaseURI.equals(baseURI))
{
URI baseBaseURI = baseURI.trimSegments(1).appendSegment("");
URI redirectedBaseBaseURI = redirect(baseBaseURI);
if (!redirectedBaseBaseURI.equals(baseBaseURI))
{
addEclipseIniTask(result, true, "-D" + SetupProperties.PROP_REDIRECTION_BASE + "index" + name + ".redirection",
"=" + baseBaseURI + "->" + redirectedBaseBaseURI);
}
else
{
addEclipseIniTask(result, true, "-D" + SetupProperties.PROP_REDIRECTION_BASE + "index" + name + ".redirection",
"=" + baseURI + "->" + redirectedBaseURI);
}
}
// Don't add -D if we're redirecting into the default archive.
else if (!redirectedURI.isArchive() || !(SetupContext.INDEX_SETUP_ARCHIVE_LOCATION_URI + "!").equals(redirectedURI.authority()))
{
addEclipseIniTask(result, true, "-D" + SetupProperties.PROP_REDIRECTION_BASE + "index" + name + ".redirection", "=" + indexURI + "->" + redirectedURI);
}
}
}
private void addEclipseIniTask(EList<SetupTask> result, boolean vm, String option, String value)
{
EclipseIniTask task = SetupFactory.eINSTANCE.createEclipseIniTask();
task.setVm(vm);
task.setOption(option);
task.setValue(value);
task.setExcludedTriggers(new HashSet<Trigger>(Arrays.asList(new Trigger[] { Trigger.STARTUP, Trigger.MANUAL })));
result.add(task);
}
private void generateScopeVariables(EList<SetupTask> setupTasks, String type, String qualifier, String name, String label, String description)
{
setupTasks.add(createVariable(setupTasks, "scope." + type + ".name", name, null));
if (qualifier != null)
{
setupTasks.add(createVariable(setupTasks, "scope." + type + ".name.qualified", qualifier + "." + name, null));
}
setupTasks.add(createVariable(setupTasks, "scope." + type + ".label", label, null));
setupTasks.add(createVariable(setupTasks, "scope." + type + ".description", description, null));
}
private VariableTask createVariable(EList<SetupTask> setupTasks, String name, String value, String description)
{
VariableTask variable = SetupFactory.eINSTANCE.createVariableTask();
variable.setName(name);
variable.setValue(value);
variable.setDescription(description);
return variable;
}
private void getSetupTasks(EList<SetupTask> setupTasks, List<Scope> configurableItems, SetupTaskContainer setupTaskContainer, boolean isFiltered)
{
for (SetupTask setupTask : setupTaskContainer.getSetupTasks())
{
if (setupTask.isDisabled())
{
continue;
}
EList<Scope> restrictions = setupTask.getRestrictions();
if (!configurableItems.containsAll(restrictions))
{
continue;
}
if (setupTask instanceof VariableTask)
{
VariableTask variable = (VariableTask)setupTask;
if (isFilterProperty(variable))
{
setupTasks.add(variable);
continue;
}
}
boolean effectiveIsFiltered = isFiltered || !matchesFilterContext(setupTask.getFilter());
if (setupTask instanceof SetupTaskContainer)
{
SetupTaskContainer container = (SetupTaskContainer)setupTask;
getSetupTasks(setupTasks, configurableItems, container, effectiveIsFiltered);
}
else if (!effectiveIsFiltered)
{
setupTasks.add(setupTask);
}
}
}
private void gatherFilters(List<Scope> configurableItems, SetupTaskContainer setupTaskContainer)
{
for (SetupTask setupTask : setupTaskContainer.getSetupTasks())
{
if (setupTask.isDisabled())
{
continue;
}
EList<Scope> restrictions = setupTask.getRestrictions();
if (!configurableItems.containsAll(restrictions))
{
continue;
}
filterProperties.addAll(getFilterProperties(setupTask));
if (setupTask instanceof SetupTaskContainer)
{
SetupTaskContainer container = (SetupTaskContainer)setupTask;
gatherFilters(configurableItems, container);
}
}
}
private Set<String> getFilterProperties(SetupTask setupTask)
{
final Set<String> filterProperties = new LinkedHashSet<String>();
String filter = setupTask.getFilter();
if (!StringUtil.isEmpty(filter))
{
try
{
IMatchExpression<IInstallableUnit> matchExpression = InstallableUnit.parseFilter(filter);
Object[] parameters = matchExpression.getParameters();
if (parameters.length == 1 && parameters[0] instanceof LDAPFilter)
{
LDAPFilter ldapFilter = (LDAPFilter)parameters[0];
ldapFilter.accept(new IExpressionVisitor()
{
public boolean visit(IExpression expression)
{
if (expression.getExpressionType() == IExpression.TYPE_MEMBER)
{
Member member = (Member)expression;
String name = member.getName();
filterProperties.add(name);
}
return true;
}
});
}
}
catch (Exception ex)
{
// Ignore.
}
}
return filterProperties;
}
public EList<SetupTask> initNeededSetupTasks(IProgressMonitor monitor) throws Exception
{
if (neededSetupTasks == null)
{
neededSetupTasks = new BasicEList<SetupTask>();
if (!undeclaredVariables.isEmpty())
{
throw new RuntimeException("Missing variables for " + undeclaredVariables);
}
if (!unresolvedVariables.isEmpty())
{
throw new RuntimeException("Unresolved variables for " + unresolvedVariables);
}
if (triggeredSetupTasks != null)
{
monitor.beginTask("", triggeredSetupTasks.size());
try
{
for (Iterator<SetupTask> it = triggeredSetupTasks.iterator(); it.hasNext();)
{
SetupTask setupTask = it.next();
checkCancelation();
progressMonitor = MonitorUtil.create(monitor, 1);
try
{
if (setupTask.isNeeded(this))
{
neededSetupTasks.add(setupTask);
}
}
catch (NoClassDefFoundError ex)
{
// Don't perform tasks that can't load their enabling dependencies
SetupCorePlugin.INSTANCE.log(ex);
}
finally
{
progressMonitor.done();
progressMonitor = null;
}
}
}
finally
{
monitor.done();
}
}
}
return neededSetupTasks;
}
public EList<SetupTask> getNeededTasks()
{
return neededSetupTasks;
}
public Map<EObject, EObject> getCopyMap()
{
return copyMap;
}
public IProgressMonitor getProgressMonitor(boolean working)
{
if (!working || progressMonitor == null)
{
return new ProgressLogMonitor(this);
}
return progressMonitor;
}
public boolean isCanceled()
{
if (canceled)
{
return true;
}
if (progress != null)
{
return progress.isCanceled();
}
return false;
}
public void setCanceled(boolean canceled)
{
this.canceled = canceled;
}
public boolean isSkipConfirmation()
{
return skipConfirmation;
}
public void setSkipConfirmation(boolean skipConfirmation)
{
this.skipConfirmation = skipConfirmation;
}
public void setTerminating()
{
if (progress != null)
{
progress.setTerminating();
}
}
public void task(SetupTask setupTask)
{
progress.task(setupTask);
log("Performing " + getLabel(setupTask), false, Severity.INFO);
}
public void log(Throwable t)
{
log(SetupCorePlugin.toString(t), false, Severity.ERROR);
}
public void log(IStatus status)
{
log(SetupCorePlugin.toString(status), false, Severity.fromStatus(status));
}
public void log(String line)
{
log(line, true, Severity.OK);
}
public void log(String line, Severity severity)
{
log(line, true, severity);
}
public void log(String line, boolean filter)
{
log(line, filter, Severity.OK);
}
public void log(String line, boolean filter, Severity severity)
{
if (progress != null)
{
if (logMessageBuffer != null)
{
for (Object value : logMessageBuffer)
{
String bufferedLine;
Severity bufferedSeverity;
if (value instanceof String)
{
bufferedLine = (String)value;
bufferedSeverity = Severity.OK;
}
else
{
@SuppressWarnings("unchecked")
Pair<String, Severity> pair = (Pair<String, Severity>)value;
bufferedLine = pair.getElement1();
bufferedSeverity = pair.getElement2();
}
doLog(bufferedLine, filter, bufferedSeverity);
}
logMessageBuffer = null;
}
doLog(line, filter, severity);
}
else
{
if (logMessageBuffer == null)
{
logMessageBuffer = new ArrayList<Object>();
}
if (severity == Severity.OK)
{
logMessageBuffer.add(line);
}
else
{
logMessageBuffer.add(Pair.create(line, severity));
}
}
}
private void doLog(String line, boolean filter, Severity severity)
{
if (filter)
{
line = logFilter.filter(line);
}
if (line == null)
{
return;
}
if (!logStreamError)
{
try
{
PrintStream logStream = getLogStream(true);
logStream.println("[" + DATE_TIME.format(new Date()) + "] " + line);
logStream.flush();
}
catch (Exception ex)
{
SetupCorePlugin.INSTANCE.log(ex, IStatus.WARNING);
logStreamError = true;
}
}
progress.log(line, filter, severity);
}
public PrintStream getLogStream()
{
return logStream;
}
private PrintStream getLogStream(boolean demandCreate)
{
if (logStream == null && demandCreate)
{
try
{
File location = getProductConfigurationLocation();
String path = SetupContext.OOMPH_NODE + "/" + SetupContext.LOG_FILE_NAME;
logFile = new File(location, path);
logFile.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(logFile, true);
logStream = new PrintStream(out);
}
catch (FileNotFoundException ex)
{
try
{
logFile = File.createTempFile("OomphSetup", ".log");
FileOutputStream out = new FileOutputStream(logFile, true);
logStream = new PrintStream(out);
return logStream;
}
catch (IOException ex1)
{
// Throw original exception.
}
throw new RuntimeException(ex);
}
}
return logStream;
}
public VariableTask getRuleVariable(VariableTask variable)
{
EAttribute eAttribute = ruleBasedAttributes.get(variable);
if (eAttribute != null)
{
for (Map.Entry<VariableTask, EAttribute> entry : ruleAttributes.entrySet())
{
if (entry.getValue() == eAttribute)
{
return entry.getKey();
}
}
}
return null;
}
public boolean isRuleBased(VariableTask variable)
{
return ruleBasedAttributes.containsKey(variable);
}
public boolean isFilterProperty(VariableTask variable)
{
return filterProperties.contains(variable.getName());
}
public List<VariableTask> getUnresolvedVariables()
{
return unresolvedVariables;
}
public List<VariableTask> getPasswordVariables()
{
return passwordVariables;
}
public Map<VariableTask, EAttribute> getRuleAttributes()
{
return ruleAttributes;
}
public List<VariableTask> getAppliedRuleVariables()
{
return appliedRuleVariables;
}
public List<VariableTask> getResolvedVariables()
{
return resolvedVariables;
}
public Set<String> getUndeclaredVariables()
{
return undeclaredVariables;
}
public void redirectTriggeredSetupTasks()
{
Map<URI, URI> uriMap = getURIConverter().getURIMap();
for (Iterator<SetupTask> it = triggeredSetupTasks.iterator(); it.hasNext();)
{
SetupTask setupTask = it.next();
if (setupTask instanceof RedirectionTask)
{
RedirectionTask redirectionTask = (RedirectionTask)setupTask;
String sourceURL = redirectionTask.getSourceURL();
if (sourceURL != null)
{
String targetURL = redirectionTask.getTargetURL();
if (targetURL != null)
{
URI sourceURI = URI.createURI(sourceURL);
URI targetURI = URI.createURI(targetURL);
uriMap.put(sourceURI, targetURI);
}
}
it.remove();
}
}
for (SetupTask setupTask : triggeredSetupTasks)
{
redirectStrings(setupTask);
for (Iterator<EObject> it = EcoreUtil.getAllContents(setupTask, false); it.hasNext();)
{
redirectStrings(it.next());
}
}
}
private void redirectStrings(EObject eObject)
{
EClass eClass = eObject.eClass();
for (EAttribute attribute : eClass.getEAllAttributes())
{
if (attribute.isChangeable() && attribute.getEAnnotation(EAnnotationConstants.ANNOTATION_REDIRECT) != null)
{
String instanceClassName = attribute.getEAttributeType().getInstanceClassName();
ValueConverter valueConverter = CONVERTERS.get(instanceClassName);
if (valueConverter != null)
{
if (attribute.isMany())
{
List<?> values = (List<?>)eObject.eGet(attribute);
List<Object> newValues = new ArrayList<Object>();
boolean changed = false;
for (Object value : values)
{
String convertedValue = valueConverter.convertToString(value);
String redirectedValue = redirect(convertedValue);
if (!ObjectUtil.equals(convertedValue, redirectedValue))
{
changed = true;
}
newValues.add(valueConverter.createFromString(redirectedValue));
}
if (changed)
{
eObject.eSet(attribute, newValues);
}
}
else
{
Object value = eObject.eGet(attribute);
if (value != null)
{
String convertedValue = valueConverter.convertToString(value);
String redirectedValue = redirect(convertedValue);
if (!ObjectUtil.equals(convertedValue, redirectedValue))
{
eObject.eSet(attribute, valueConverter.createFromString(redirectedValue));
}
}
}
}
}
}
}
private void expandStrings(EList<SetupTask> setupTasks)
{
Set<String> keys = new LinkedHashSet<String>();
for (SetupTask setupTask : setupTasks)
{
expandVariableTaskValue(keys, setupTask);
}
for (Iterator<EObject> it = EcoreUtil.getAllContents(setupTasks); it.hasNext();)
{
expand(keys, it.next());
}
handleFeatureSubstitutions(setupTasks);
if (!unresolvedSettings.isEmpty())
{
for (String key : keys)
{
boolean found = false;
for (SetupTask setupTask : setupTasks)
{
if (setupTask instanceof VariableTask)
{
VariableTask contextVariableTask = (VariableTask)setupTask;
if (key.equals(contextVariableTask.getName()))
{
unresolvedVariables.add(contextVariableTask);
found = true;
break;
}
}
}
if (!found)
{
undeclaredVariables.add(key);
}
}
}
}
@Override
protected String resolve(String key)
{
return lookup(key);
}
private String specialResolve(String key)
{
String result = null;
VariableTask variable = allVariables.get(key);
if (variable != null)
{
result = getPrompter().getValue(variable);
}
if (StringUtil.isEmpty(result))
{
variable = SetupFactory.eINSTANCE.createVariableTask();
variable.setName(key);
result = getPrompter().getValue(variable);
}
if (StringUtil.isEmpty(result))
{
result = resolve(key);
if (StringUtil.isEmpty(result))
{
result = variable.getValue();
if (StringUtil.isEmpty(result))
{
result = variable.getDefaultValue();
}
}
}
return new StringExpander()
{
@Override
protected String resolve(String key)
{
return specialResolve(key);
}
@Override
protected boolean isUnexpanded(String key)
{
return false;
}
@Override
protected String filter(String value, String filterName)
{
return SetupTaskPerformer.super.filter(value, filterName);
}
}.expandString(result);
}
@Override
protected String filter(String value, String filterName)
{
if (filterName.equalsIgnoreCase("installationID"))
{
String installRoot = specialResolve("install.root");
if (StringUtil.isEmpty(installRoot) || STRING_EXPANSION_PATTERN.matcher(installRoot).find())
{
return null;
}
String installationID;
String projectName = lookup("scope.project.root.name");
if (StringUtil.isEmpty(projectName))
{
installationID = SegmentSequence.create(".", lookup("scope.product.name")).lastSegment() + "-" + lookup("scope.product.version.name").replace('.', '-');
}
else
{
String streamName = lookup("scope.project.stream.name");
installationID = escape(projectName, streamName);
}
String uniqueInstallationID = installationID;
String relativeProductFolder = getRelativeProductFolder();
for (int i = 2; new File(installRoot + "/" + uniqueInstallationID + "/" + relativeProductFolder).exists(); ++i)
{
uniqueInstallationID = installationID + i;
}
return uniqueInstallationID;
}
if (filterName.equalsIgnoreCase("workspaceID"))
{
String workspaceContainerRoot = specialResolve("workspace.container.root");
if (StringUtil.isEmpty(workspaceContainerRoot) || STRING_EXPANSION_PATTERN.matcher(workspaceContainerRoot).find())
{
return null;
}
String projectName = lookup("scope.project.root.name");
String streamName = lookup("scope.project.stream.name");
String workspaceID = escape(projectName, streamName) + "-ws";
String uniqueWorkspaceID = workspaceID;
for (int i = 2; new File(workspaceContainerRoot + "/" + uniqueWorkspaceID).exists(); ++i)
{
uniqueWorkspaceID = workspaceID + i;
}
return uniqueWorkspaceID;
}
return super.filter(value, filterName);
}
private String escape(String projectName, String streamName)
{
return (projectName + "-" + streamName).replace('.', '-').replace('/', '-').replace('\\', '-');
}
@Override
protected boolean isUnexpanded(String key)
{
VariableTask variableTask = allVariables.get(key);
if (variableTask != null)
{
for (Setting setting : unresolvedSettings)
{
if (setting.getEObject() == variableTask && setting.getEStructuralFeature() == SetupPackage.Literals.VARIABLE_TASK__VALUE)
{
return true;
}
}
}
return false;
}
public static Set<String> getVariables(String string)
{
if (string == null)
{
return null;
}
Set<String> result = new LinkedHashSet<String>();
for (Matcher matcher = STRING_EXPANSION_PATTERN.matcher(string); matcher.find();)
{
String key = matcher.group(1);
if (!"$".equals(key))
{
key = matcher.group(2);
}
result.add(key);
}
return result;
}
public boolean isFilterUsed(String name, EObject eObject)
{
return eObject instanceof SetupTask && getFilterProperties((SetupTask)eObject).contains(name);
}
public boolean isVariableUsed(String name, EObject eObject, boolean recursive)
{
for (EAttribute attribute : eObject.eClass().getEAllAttributes())
{
if (attribute.isChangeable() && attribute.getEAttributeType().getInstanceClassName() == "java.lang.String"
&& attribute != SetupPackage.Literals.VARIABLE_TASK__NAME)
{
if (attribute.isMany())
{
@SuppressWarnings("unchecked")
List<String> values = (List<String>)eObject.eGet(attribute);
for (String value : values)
{
Set<String> variables = getVariables(value);
if (variables.contains(name))
{
return true;
}
}
}
else
{
String value = (String)eObject.eGet(attribute);
if (value != null)
{
Set<String> variables = getVariables(value);
if (variables.contains(name))
{
return true;
}
}
}
}
if (recursive)
{
for (EObject child : eObject.eContents())
{
if (isVariableUsed(name, child, recursive))
{
return true;
}
}
}
}
return false;
}
private void propagateRestrictionsPredecessorsAndSuccessors(EList<SetupTask> setupTasks)
{
for (SetupTask setupTask : setupTasks)
{
EList<Scope> restrictions = setupTask.getRestrictions();
for (EObject eContainer = setupTask.eContainer(); eContainer instanceof SetupTask; eContainer = eContainer.eContainer())
{
restrictions.addAll(((SetupTask)eContainer).getRestrictions());
}
EList<SetupTask> predecessors = setupTask.getPredecessors();
for (EObject eContainer = setupTask.eContainer(); eContainer instanceof SetupTask; eContainer = eContainer.eContainer())
{
predecessors.addAll(((SetupTask)eContainer).getPredecessors());
}
EList<SetupTask> successors = setupTask.getSuccessors();
for (EObject eContainer = setupTask.eContainer(); eContainer instanceof SetupTask; eContainer = eContainer.eContainer())
{
successors.addAll(((SetupTask)eContainer).getSuccessors());
}
}
}
private void flattenPredecessorsAndSuccessors(EList<SetupTask> setupTasks)
{
for (SetupTask setupTask : setupTasks)
{
for (ListIterator<SetupTask> it = setupTask.getPredecessors().listIterator(); it.hasNext();)
{
SetupTask predecessor = it.next();
if (predecessor instanceof SetupTaskContainer)
{
it.remove();
for (SetupTask expandedPrecessor : ((SetupTaskContainer)predecessor).getSetupTasks())
{
it.add(expandedPrecessor);
it.previous();
}
}
}
for (ListIterator<SetupTask> it = setupTask.getSuccessors().listIterator(); it.hasNext();)
{
SetupTask successor = it.next();
if (successor instanceof SetupTaskContainer)
{
it.remove();
for (SetupTask expandedSuccessor : ((SetupTaskContainer)successor).getSetupTasks())
{
it.add(expandedSuccessor);
it.previous();
}
}
}
}
}
private CompoundTask findOrCreate(AdapterFactoryItemDelegator itemDelegator, Scope configurableItem, EList<SetupTask> setupTasks)
{
EObject eContainer = configurableItem.eContainer();
if (eContainer instanceof Scope)
{
CompoundTask compoundSetupTask = findOrCreate(itemDelegator, (Scope)eContainer, setupTasks);
setupTasks = compoundSetupTask.getSetupTasks();
}
CompoundTask compoundSetupTask = find(configurableItem, setupTasks);
if (compoundSetupTask == null)
{
compoundSetupTask = SetupFactory.eINSTANCE.createCompoundTask();
compoundSetupTask.setName(itemDelegator.getText(configurableItem));
compoundSetupTask.getRestrictions().add(configurableItem);
setupTasks.add(compoundSetupTask);
}
return compoundSetupTask;
}
private CompoundTask find(Scope configurableItem, EList<SetupTask> setupTasks)
{
LOOP: for (SetupTask setupTask : setupTasks)
{
if (setupTask instanceof CompoundTask)
{
CompoundTask compoundSetupTask = (CompoundTask)setupTask;
List<Scope> restrictions = ((InternalEList<Scope>)compoundSetupTask.getRestrictions()).basicList();
URI uri = EcoreUtil.getURI(configurableItem);
boolean found = false;
for (Scope restriction : restrictions)
{
URI otherURI = EcoreUtil.getURI(restriction);
if (!otherURI.equals(uri))
{
continue LOOP;
}
found = true;
}
if (found)
{
return compoundSetupTask;
}
compoundSetupTask = find(configurableItem, compoundSetupTask.getSetupTasks());
if (compoundSetupTask != null)
{
return compoundSetupTask;
}
}
}
return null;
}
public void resolveSettings()
{
// Do this before expanding any more strings.
List<Setting> unresolvedSettings = new ArrayList<EStructuralFeature.Setting>(this.unresolvedSettings);
this.unresolvedSettings.clear();
Set<String> keys = new LinkedHashSet<String>();
for (VariableTask unspecifiedVariable : unresolvedVariables)
{
String name = unspecifiedVariable.getName();
keys.add(name);
String value = unspecifiedVariable.getValue();
put(name, value);
}
for (EStructuralFeature.Setting setting : unresolvedSettings)
{
if (setting.getEStructuralFeature() == SetupPackage.Literals.VARIABLE_TASK__VALUE)
{
VariableTask variable = (VariableTask)setting.getEObject();
String name = variable.getName();
keys.add(name);
String value = variable.getValue();
put(name, value);
}
}
expandVariableKeys(keys, false);
for (EStructuralFeature.Setting setting : unresolvedSettings)
{
EStructuralFeature eStructuralFeature = setting.getEStructuralFeature();
ValueConverter valueConverter = CONVERTERS.get(eStructuralFeature.getEType().getInstanceClassName());
if (eStructuralFeature.isMany())
{
@SuppressWarnings("unchecked")
List<Object> values = (List<Object>)setting.get(false);
for (ListIterator<Object> it = values.listIterator(); it.hasNext();)
{
it.set(valueConverter.createFromString(expandString(valueConverter.convertToString(it.next()))));
}
}
else
{
Object value = setting.get(false);
String expandedString = expandString(valueConverter.convertToString(value));
setting.set(valueConverter.createFromString(expandedString));
if (eStructuralFeature == SetupPackage.Literals.VARIABLE_TASK__VALUE)
{
put(((VariableTask)setting.getEObject()).getName(), expandedString);
}
}
}
handleFeatureSubstitutions(triggeredSetupTasks);
}
private void handleFeatureSubstitutions(Collection<? extends EObject> eObjects)
{
// Find all the feature substitution annotations.
for (Iterator<EObject> it = EcoreUtil.getAllContents(eObjects); it.hasNext();)
{
InternalEObject eObject = (InternalEObject)it.next();
if (eObject instanceof Annotation)
{
Annotation annotation = (Annotation)eObject;
if (AnnotationConstants.ANNOTATION_FEATURE_SUBSTITUTION.equals(annotation.getSource()))
{
ModelElement modelElement = annotation.getModelElement();
EClass eClass = modelElement.eClass();
for (Map.Entry<String, String> detail : annotation.getDetails())
{
// Look for an attribute with the name of the detail's key.
EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(detail.getKey());
if (eStructuralFeature instanceof EAttribute)
{
try
{
// Convert the detail's value to a value of that attribute's type and replace it.
modelElement.eSet(eStructuralFeature, EcoreUtil.createFromString(((EAttribute)eStructuralFeature).getEAttributeType(), detail.getValue()));
}
catch (RuntimeException ex)
{
// Ignore.
}
}
}
}
}
}
}
private void expandVariableKeys(Set<String> keys, boolean addUnresolvedSettings)
{
Map<String, Set<String>> variables = new LinkedHashMap<String, Set<String>>();
for (Map.Entry<Object, Object> entry : getMap().entrySet())
{
Object entryKey = entry.getKey();
if (keys.contains(entryKey))
{
String key = (String)entryKey;
Object entryValue = entry.getValue();
if (entryValue == null)
{
VariableTask variable = allVariables.get(key);
if (variable != null)
{
SetupPrompter prompter = getPrompter();
String value = prompter.getValue(variable);
if (value == null)
{
value = variable.getValue();
}
if (value != null)
{
variable.setValue(value);
Set<String> valueVariables = getVariables(value);
variables.put(key, valueVariables);
unresolvedVariables.add(variable);
if (!valueVariables.isEmpty())
{
unresolvedSettings.add(((InternalEObject)variable).eSetting(SetupPackage.Literals.VARIABLE_TASK__VALUE));
}
}
}
}
else if (entryKey instanceof String)
{
String value = entryValue.toString();
Set<String> valueVariables = getVariables(value);
variables.put(key, valueVariables);
if (addUnresolvedSettings && !valueVariables.isEmpty())
{
VariableTask variable = allVariables.get(key);
if (variable != null)
{
unresolvedSettings.add(((InternalEObject)variable).eSetting(SetupPackage.Literals.VARIABLE_TASK__VALUE));
}
}
}
}
}
EList<Map.Entry<String, Set<String>>> orderedVariables = reorderVariables(variables);
for (Map.Entry<String, Set<String>> entry : orderedVariables)
{
String key = entry.getKey();
Object object = get(key);
if (object != null)
{
String value = expandString(object.toString());
put(key, value);
}
}
}
public void recordVariables(Installation installation, Workspace workspace, User user)
{
recordRules(user.getAttributeRules(), true);
AdapterFactoryItemDelegator itemDelegator = new AdapterFactoryItemDelegator(adapterFactory)
{
@Override
public String getText(Object object)
{
String result = super.getText(object);
if (object instanceof ProjectCatalog)
{
if (!result.endsWith("Projects"))
{
result += " Projects";
}
}
else if (object instanceof ProductCatalog)
{
if (!result.endsWith("Products"))
{
result += " Products";
}
}
return result;
}
};
EList<SetupTask> userSetupTasks = user.getSetupTasks();
if (!unresolvedVariables.isEmpty())
{
applyUnresolvedVariables(installation, workspace, user, unresolvedVariables, userSetupTasks, itemDelegator);
}
if (!appliedRuleVariables.isEmpty())
{
List<VariableTask> productCatalogScopedVariables = new ArrayList<VariableTask>();
List<VariableTask> projectCatalogScopedVariables = new ArrayList<VariableTask>();
EList<SetupTask> workspaceScopeTasks = null;
EList<SetupTask> installationScopeTasks = null;
for (VariableTask unspecifiedVariable : appliedRuleVariables)
{
for (EObject container = unspecifiedVariable.eContainer(); container != null; container = container.eContainer())
{
if (container instanceof Scope)
{
Scope scope = (Scope)container;
switch (scope.getType())
{
case STREAM:
case PROJECT:
case PROJECT_CATALOG:
case WORKSPACE:
{
if (workspaceScopeTasks == null)
{
workspaceScopeTasks = workspace.getSetupTasks();
}
projectCatalogScopedVariables.add(unspecifiedVariable);
break;
}
case PRODUCT_VERSION:
case PRODUCT:
case PRODUCT_CATALOG:
case INSTALLATION:
{
if (installationScopeTasks == null)
{
installationScopeTasks = installation.getSetupTasks();
}
productCatalogScopedVariables.add(unspecifiedVariable);
break;
}
case USER:
{
if (workspace != null)
{
if (workspaceScopeTasks == null)
{
workspaceScopeTasks = findOrCreate(itemDelegator, workspace, userSetupTasks).getSetupTasks();
}
projectCatalogScopedVariables.add(unspecifiedVariable);
}
if (installationScopeTasks == null)
{
installationScopeTasks = findOrCreate(itemDelegator, installation, userSetupTasks).getSetupTasks();
}
productCatalogScopedVariables.add(unspecifiedVariable);
break;
}
}
break;
}
}
}
applyUnresolvedVariables(installation, workspace, user, productCatalogScopedVariables, installationScopeTasks, itemDelegator);
applyUnresolvedVariables(installation, workspace, user, projectCatalogScopedVariables, workspaceScopeTasks, itemDelegator);
}
}
private URI getEffectiveStorage(VariableTask variable)
{
URI storageURI = variable.getStorageURI();
if (variable.getType() == VariableType.PASSWORD)
{
if (VariableTask.DEFAULT_STORAGE_URI.equals(storageURI))
{
storageURI = PreferencesUtil.ROOT_PREFERENCE_NODE_URI
.appendSegments(new String[] { PreferencesUtil.SECURE_NODE, SetupContext.OOMPH_NODE, variable.getName(), "" });
}
else if (storageURI != null && PreferencesUtil.PREFERENCE_SCHEME.equals(storageURI.scheme()) && !storageURI.hasTrailingPathSeparator())
{
storageURI = storageURI.appendSegment("");
}
}
return storageURI;
}
public void savePasswords()
{
for (Map.Entry<URI, String> entry : passwords.entrySet())
{
String value = PreferencesUtil.decrypt(entry.getValue());
if (!StringUtil.isEmpty(value) && !" ".equals(value))
{
URI storageURI = entry.getKey();
URIConverter uriConverter = getURIConverter();
try
{
Writer writer = ((URIConverter.WriteableOutputStream)uriConverter.createOutputStream(storageURI)).asWriter();
writer.write(value);
writer.close();
}
catch (IOException ex)
{
SetupCorePlugin.INSTANCE.log(ex);
}
}
}
}
private void applyUnresolvedVariables(Installation installation, Workspace workspace, User user, Collection<VariableTask> variables,
EList<SetupTask> rootTasks, AdapterFactoryItemDelegator itemDelegator)
{
Resource installationResource = installation.eResource();
Resource workspaceResource = workspace == null ? null : workspace.eResource();
Resource userResource = user.eResource();
List<VariableTask> unspecifiedVariables = new ArrayList<VariableTask>();
for (VariableTask variable : variables)
{
URI storageURI = getEffectiveStorage(variable);
if (storageURI != null)
{
String value = variable.getValue();
if (value != null)
{
if (variable.getType() == VariableType.PASSWORD)
{
passwords.put(storageURI, value);
}
else
{
Scope scope = variable.getScope();
if (scope != null && storageURI.equals(VariableTask.DEFAULT_STORAGE_URI))
{
switch (scope.getType())
{
case INSTALLATION:
{
apply(installationResource, scope, variable, value);
break;
}
case WORKSPACE:
{
apply(workspaceResource, scope, variable, value);
break;
}
case USER:
{
apply(userResource, scope, variable, value);
break;
}
default:
{
unspecifiedVariables.add(variable);
break;
}
}
}
else
{
unspecifiedVariables.add(variable);
}
}
}
}
}
LOOP: for (VariableTask unspecifiedVariable : unspecifiedVariables)
{
String name = unspecifiedVariable.getName();
String value = unspecifiedVariable.getValue();
URI storageURI = unspecifiedVariable.getStorageURI();
EList<SetupTask> targetSetupTasks = rootTasks;
Scope scope = unspecifiedVariable.getScope();
if (scope != null)
{
if (storageURI.equals(VariableTask.WORKSPACE_STORAGE_URI))
{
if (workspace != null)
{
targetSetupTasks = workspace.getSetupTasks();
}
}
else if (storageURI.equals(VariableTask.INSTALLATION_STORAGE_URI))
{
targetSetupTasks = installation.getSetupTasks();
}
if (unspecifiedVariable.getAnnotation(AnnotationConstants.ANNOTATION_GLOBAL_VARIABLE) == null)
{
targetSetupTasks = findOrCreate(itemDelegator, scope, targetSetupTasks).getSetupTasks();
}
}
// This happens in the multi-stream case where each perform wants to add setup-restricted tasks for the same variable.
for (SetupTask setupTask : targetSetupTasks)
{
if (setupTask instanceof VariableTask)
{
VariableTask variable = (VariableTask)setupTask;
if (name.equals(variable.getName()))
{
variable.setValue(value);
continue LOOP;
}
}
}
VariableTask userPreference = EcoreUtil.copy(unspecifiedVariable);
userPreference.getAnnotations().clear();
userPreference.getChoices().clear();
userPreference.setStorageURI(VariableTask.DEFAULT_STORAGE_URI);
targetSetupTasks.add(userPreference);
}
}
private void apply(Resource resource, Scope scope, VariableTask variable, String value)
{
String uriFragment = scope.eResource().getURIFragment(variable);
EObject eObject = resource.getEObject(uriFragment);
if (eObject instanceof VariableTask)
{
VariableTask targetVariable = (VariableTask)eObject;
if (variable.getName().equals(targetVariable.getName()))
{
targetVariable.setValue(value);
}
}
}
private void expandVariableTaskValue(Set<String> keys, EObject eObject)
{
if (eObject instanceof VariableTask)
{
VariableTask variableTask = (VariableTask)eObject;
String value = variableTask.getValue();
if (value != null)
{
String newValue = expandString(value, keys);
if (newValue == null)
{
unresolvedSettings.add(((InternalEObject)eObject).eSetting(SetupPackage.Literals.VARIABLE_TASK__VALUE));
}
else if (!value.equals(newValue))
{
variableTask.setValue(newValue);
}
}
}
}
private void expand(Set<String> keys, EObject eObject)
{
EClass eClass = eObject.eClass();
for (EAttribute attribute : eClass.getEAllAttributes())
{
if (attribute.isChangeable() && attribute.getEAnnotation(EAnnotationConstants.ANNOTATION_NO_EXPAND) == null)
{
String instanceClassName = attribute.getEAttributeType().getInstanceClassName();
ValueConverter valueConverter = CONVERTERS.get(instanceClassName);
if (valueConverter != null)
{
if (attribute.isMany())
{
List<?> values = (List<?>)eObject.eGet(attribute);
List<Object> newValues = new ArrayList<Object>();
boolean failed = false;
for (Object value : values)
{
String newValue = expandString(valueConverter.convertToString(value), keys);
if (newValue == null)
{
if (!failed)
{
unresolvedSettings.add(((InternalEObject)eObject).eSetting(attribute));
failed = true;
}
}
else
{
newValues.add(valueConverter.createFromString(newValue));
}
}
if (!failed)
{
eObject.eSet(attribute, newValues);
}
}
else
{
Object value = eObject.eGet(attribute);
if (value != null)
{
String newValue;
if (attribute == SetupPackage.Literals.VARIABLE_TASK__DEFAULT_VALUE)
{
// With second parameter not null, if value is not resolved, expandString returns newValue as null
newValue = expandString(valueConverter.convertToString(value), new LinkedHashSet<String>());
eObject.eSet(attribute, valueConverter.createFromString(newValue));
}
else if (attribute != SetupPackage.Literals.VARIABLE_TASK__VALUE)
{
newValue = expandString(valueConverter.convertToString(value), keys);
if (newValue == null)
{
unresolvedSettings.add(((InternalEObject)eObject).eSetting(attribute));
}
else
{
Object object = valueConverter.createFromString(newValue);
if (!value.equals(object))
{
eObject.eSet(attribute, object);
}
}
}
}
}
}
}
}
}
private void performTask(SetupTask task, IProgressMonitor monitor) throws Exception
{
monitor.beginTask("", 101);
try
{
progressMonitor = MonitorUtil.create(monitor, 1);
if (task.isNeeded(this))
{
progressMonitor.done();
progressMonitor = MonitorUtil.create(monitor, 100);
task.perform(this);
}
else
{
progressMonitor.done();
monitor.worked(100);
}
}
finally
{
progressMonitor.done();
progressMonitor = null;
monitor.done();
}
}
public void perform(IProgressMonitor monitor) throws Exception
{
boolean bootstrap = getTrigger() == Trigger.BOOTSTRAP;
monitor.beginTask("", 100 + (bootstrap ? 3 : 0));
try
{
CacheUsageConfirmer cacheUsageConfirmer = (CacheUsageConfirmer)get(CacheUsageConfirmer.class);
if (cacheUsageConfirmer != null)
{
cacheUsageConfirmer.reset();
}
performTriggeredSetupTasks(MonitorUtil.create(monitor, 100));
if (bootstrap)
{
performPostBootstrapTasks(monitor);
}
}
finally
{
monitor.done();
log("", false);
}
hasSuccessfullyPerformed = true;
}
private void performPostBootstrapTasks(IProgressMonitor monitor) throws Exception
{
log("Performing post bootstrap tasks", false, Severity.INFO);
File productConfigurationLocation = getProductConfigurationLocation();
if (OS.INSTANCE.isMac())
{
File file = new File(productConfigurationLocation, "config.ini");
log("Changing " + file + " (osgi.configuration.cascaded=false)", false, Severity.OK);
Map<String, String> configIni = PropertiesUtil.loadProperties(file);
configIni.put("osgi.configuration.cascaded", "false");
P2TaskImpl.saveConfigIni(file, configIni, SetupTaskPerformer.class);
}
Profile profile = getProfile();
File installFolder = profile.getInstallFolder();
File bundlePool = profile.getBundlePool().getLocation();
if (!installFolder.equals(bundlePool))
{
File garbageCollectorPreferences = new File(productConfigurationLocation, ".settings/org.eclipse.equinox.p2.garbagecollector.prefs");
IOUtil.writeLines(garbageCollectorPreferences, "8859_1", Arrays.asList(new String[] { "eclipse.preferences.version=1", "gc_enabled=false" }));
}
monitor.worked(1);
URIConverter uriConverter = getURIConverter();
String[] networkPreferences = new String[] { ".settings", "org.eclipse.core.net.prefs" };
URI networkPreferencesSourceLocation = SetupContext.CONFIGURATION_LOCATION_URI.appendSegments(networkPreferences);
if (uriConverter.exists(networkPreferencesSourceLocation, null))
{
URI targetURI = URI.createFileURI(productConfigurationLocation.toString()).appendSegments(networkPreferences);
ResourceCopyTask resourceCopyTask = SetupFactory.eINSTANCE.createResourceCopyTask();
resourceCopyTask.setSourceURL(networkPreferencesSourceLocation.toString());
resourceCopyTask.setTargetURL(targetURI.toString());
performTask(resourceCopyTask, MonitorUtil.create(monitor, 1));
}
else
{
monitor.worked(1);
}
File workspaceLocation = getWorkspaceLocation();
if (workspaceLocation != null)
{
String[] jschPreferences = new String[] { ".metadata", ".plugins", "org.eclipse.core.runtime", ".settings", "org.eclipse.jsch.core.prefs" };
URI jschPreferencesSourceLocation = SetupContext.CONFIGURATION_LOCATION_URI.appendSegments(jschPreferences);
if (uriConverter.exists(jschPreferencesSourceLocation, null))
{
URI targetURI = URI.createFileURI(workspaceLocation.toString()).appendSegments(jschPreferences);
if (!uriConverter.exists(targetURI, null))
{
ResourceCopyTask resourceCopyTask = SetupFactory.eINSTANCE.createResourceCopyTask();
resourceCopyTask.setSourceURL(jschPreferencesSourceLocation.toString());
resourceCopyTask.setTargetURL(targetURI.toString());
performTask(resourceCopyTask, MonitorUtil.create(monitor, 1));
}
else
{
monitor.worked(1);
}
}
else
{
monitor.worked(1);
}
}
else
{
monitor.worked(1);
}
}
private void performTriggeredSetupTasks(IProgressMonitor monitor) throws Exception
{
monitor.beginTask("", 101);
try
{
initNeededSetupTasks(MonitorUtil.create(monitor, 1));
if (!neededSetupTasks.isEmpty())
{
performNeededSetupTasks(MonitorUtil.create(monitor, 100));
}
else
{
monitor.worked(100);
}
}
finally
{
monitor.done();
}
}
private void performNeededSetupTasks(IProgressMonitor monitor) throws Exception
{
setPerforming(true);
if (getTrigger() == Trigger.BOOTSTRAP)
{
doPerformNeededSetupTasks(monitor);
}
else
{
if (SetupContext.USE_RESOURCES_BUNDLE)
{
WorkspaceUtil.performNeededSetupTasks(this, monitor);
}
else
{
doPerformNeededSetupTasks(monitor);
}
}
}
private void doPerformNeededSetupTasks(IProgressMonitor monitor) throws Exception
{
Boolean autoBuilding = null;
try
{
Trigger trigger = getTrigger();
if (trigger != Trigger.BOOTSTRAP)
{
autoBuilding = disableAutoBuilding();
}
logJREInfos();
logSetupInfos();
logBundleInfos();
int totalWork = 0;
for (SetupTask neededTask : neededSetupTasks)
{
int work = Math.max(0, neededTask.getProgressMonitorWork());
totalWork += work;
}
monitor.beginTask("", totalWork);
for (SetupTask neededTask : neededSetupTasks)
{
checkCancelation();
// Once we're past all the installation priority tasks that might cause restart reasons and there are restart reasons, stop performing.
if (trigger != Trigger.BOOTSTRAP && neededTask.getPriority() >= SetupTask.PRIORITY_CONFIGURATION && !getRestartReasons().isEmpty())
{
break;
}
task(neededTask);
int work = Math.max(0, neededTask.getProgressMonitorWork());
progressMonitor = MonitorUtil.create(monitor, work);
try
{
// We need special case support for setting the auto building preference, because we save and restore this value during the perform process.
// In the case of false, we don't want to set it back to true.
// In the case of true, we don't want to set it to true until after all the tasks have performed.
if (neededTask instanceof PreferenceTask)
{
PreferenceTask preferenceTask = (PreferenceTask)neededTask;
if ("/instance/org.eclipse.core.resources/description.autobuilding".equals(preferenceTask.getKey()))
{
String value = preferenceTask.getValue();
autoBuilding = value == null ? Boolean.TRUE : Boolean.valueOf(value);
neededTask.dispose();
continue;
}
}
neededTask.perform(this);
neededTask.dispose();
}
catch (NoClassDefFoundError ex)
{
log(ex);
}
finally
{
progressMonitor.done();
progressMonitor = null;
}
}
}
catch (OperationCanceledException ex)
{
monitor.setCanceled(true);
throw ex;
}
catch (InterruptedException ex)
{
throw ex;
}
catch (Exception ex)
{
log(ex);
throw ex;
}
finally
{
monitor.done();
if (Boolean.TRUE.equals(autoBuilding))
{
// Disable the PDE's API analysis builder, if it's installed, and remember its previously current state.
// It's considered disabled if it's not installed at all.
final boolean disabled = PDEAPIUtil.setDisableAPIAnalysisBuilder(true);
Job buildJob = new Job("Build")
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
try
{
EcorePlugin.getWorkspaceRoot().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, monitor);
return Status.OK_STATUS;
}
catch (CoreException ex)
{
return SetupCorePlugin.INSTANCE.getStatus(ex);
}
finally
{
try
{
restoreAutoBuilding(true);
}
catch (CoreException ex)
{
SetupCorePlugin.INSTANCE.log(ex);
}
if (!disabled)
{
// Restore it to false if it was true before we set it to false;
PDEAPIUtil.setDisableAPIAnalysisBuilder(false);
}
}
}
@Override
public boolean belongsTo(Object family)
{
return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
}
};
buildJob.setRule(EcorePlugin.getWorkspaceRoot());
buildJob.schedule();
}
}
}
private void logJREInfos()
{
log(System.getProperty("java.runtime.name") + " " + System.getProperty("java.runtime.version"));
}
private void logSetupInfos()
{
SetupContext setupContext = getSetupContext();
Installation installation = setupContext.getInstallation();
if (installation != null)
{
ProductVersion productVersion = installation.getProductVersion();
log("Product " + productVersion.getQualifiedName());
}
Workspace workspace = setupContext.getWorkspace();
if (workspace != null)
{
for (Stream stream : workspace.getStreams())
{
log("Project " + stream.getQualifiedName());
}
}
}
private void logBundleInfos()
{
List<String> bundleInfos = new ArrayList<String>();
for (Bundle bundle : bundles)
{
StringBuilder builder = new StringBuilder("Bundle ");
builder.append(bundle.getSymbolicName());
builder.append(" ");
builder.append(bundle.getVersion());
InputStream source = null;
try
{
URL url = bundle.getResource("about.mappings");
if (url != null)
{
source = url.openStream();
Properties properties = new Properties();
properties.load(source);
String buildID = (String)properties.get("0");
if (buildID != null && !buildID.startsWith("$"))
{
builder.append(", build=");
builder.append(buildID);
}
String gitBranch = (String)properties.get("1");
if (gitBranch != null && !gitBranch.startsWith("$"))
{
builder.append(", branch=");
builder.append(gitBranch);
}
String gitCommit = (String)properties.get("2");
if (gitCommit != null && !gitCommit.startsWith("$"))
{
builder.append(", commit=");
builder.append(gitCommit);
}
}
}
catch (IOException ex)
{
//$FALL-THROUGH$
}
finally
{
IOUtil.closeSilent(source);
}
bundleInfos.add(builder.toString());
}
Collections.sort(bundleInfos);
for (String bundleInfo : bundleInfos)
{
log(bundleInfo);
}
}
private Map<SetupTask, SetupTask> getSubstitutions(EList<SetupTask> setupTasks)
{
Map<Object, SetupTask> overrides = new LinkedHashMap<Object, SetupTask>();
Map<SetupTask, SetupTask> substitutions = new LinkedHashMap<SetupTask, SetupTask>();
for (SetupTask setupTask : setupTasks)
{
Object overrideToken = setupTask.getOverrideToken();
SetupTask overriddenTask = overrides.put(overrideToken, setupTask);
if (overriddenTask != null)
{
substitutions.put(overriddenTask, setupTask);
}
}
return substitutions;
}
private void gather(Set<EObject> roots, Set<Scope> scopesToCopy, EObject eObject)
{
EObject result = eObject;
for (EObject parent = eObject; parent != null; parent = parent.eContainer())
{
if (parent instanceof Scope)
{
if (!scopesToCopy.add((Scope)parent))
{
return;
}
}
result = parent;
}
roots.add(result);
}
private void copySetup(Stream stream, EList<SetupTask> setupTasks, Map<SetupTask, SetupTask> substitutions, Map<SetupTask, SetupTask> directSubstitutions)
{
Set<EObject> roots = new LinkedHashSet<EObject>();
final Set<Scope> scopesToCopy = new LinkedHashSet<Scope>();
Workspace originalWorkspace = getWorkspace();
if (originalWorkspace != null)
{
scopesToCopy.add(originalWorkspace);
roots.add(originalWorkspace);
if (stream != null)
{
gather(roots, scopesToCopy, stream);
}
}
User originalPreferences = getUser();
if (originalPreferences != null)
{
scopesToCopy.add(originalPreferences);
roots.add(originalPreferences);
}
Installation originalInstallation = getInstallation();
if (originalInstallation != null)
{
scopesToCopy.add(originalInstallation);
roots.add(originalInstallation);
for (EObject eObject : originalInstallation.eCrossReferences())
{
gather(roots, scopesToCopy, eObject);
}
}
for (SetupTask setupTask : setupTasks)
{
gather(roots, scopesToCopy, setupTask);
}
EcoreUtil.Copier copier = new EcoreUtil.Copier(true, stream == null)
{
private static final long serialVersionUID = 1L;
@Override
public <T> Collection<T> copyAll(Collection<? extends T> eObjects)
{
Collection<T> result = new ArrayList<T>(eObjects.size());
for (Object object : eObjects)
{
@SuppressWarnings("unchecked")
T t = (T)copy((EObject)object);
if (t != null)
{
result.add(t);
}
}
return result;
}
@Override
protected EObject createCopy(EObject eObject)
{
if (eObject instanceof Scope && !scopesToCopy.contains(eObject))
{
return null;
}
return super.createCopy(eObject);
}
};
copier.copyAll(roots);
// Determine all the copied objects for which the original object is directly contained in a resource.
// For each such resource, create a copy of that resource.
Map<Resource, Resource> resourceCopies = new LinkedHashMap<Resource, Resource>();
@SuppressWarnings("unchecked")
Set<InternalEObject> originals = (Set<InternalEObject>)(Set<?>)copier.keySet();
for (InternalEObject original : originals)
{
Internal resource = original.eDirectResource();
if (resource != null)
{
Resource newResource = resourceCopies.get(resource);
if (newResource == null)
{
URI uri = resource.getURI();
ResourceSet resourceSet = resource.getResourceSet();
Registry resourceFactoryRegistry = resourceSet == null ? SetupCoreUtil.RESOURCE_FACTORY_REGISTRY : resourceSet.getResourceFactoryRegistry();
newResource = resourceFactoryRegistry.getFactory(uri).createResource(uri);
resourceCopies.put(resource, newResource);
}
}
}
// For each original resource, ensure that the copied resource contains either the corresponding copies or
// a placeholder object.
for (Map.Entry<Resource, Resource> entry : resourceCopies.entrySet())
{
Resource originalResource = entry.getKey();
Resource copyResource = entry.getValue();
EList<EObject> copyResourceContents = copyResource.getContents();
for (EObject eObject : originalResource.getContents())
{
EObject copy = copier.get(eObject);
if (copy == null)
{
copy = EcoreFactory.eINSTANCE.createEObject();
}
copyResourceContents.add(copy);
}
}
// Must determine mapping from original setup's references (ProductVersion and Streams) to their copies currently in the copier.
Map<URI, EObject> originalCrossReferences = new LinkedHashMap<URI, EObject>();
if (originalWorkspace != null)
{
for (EObject eObject : originalWorkspace.eCrossReferences())
{
originalCrossReferences.put(EcoreUtil.getURI(eObject), eObject);
}
}
for (EObject copiedObject : new ArrayList<EObject>(copier.values()))
{
if (copiedObject instanceof Stream)
{
URI uri = EcoreUtil.getURI(copiedObject);
EObject originalObject = originalCrossReferences.get(uri);
if (originalObject != null)
{
copier.put(originalObject, copiedObject);
}
}
}
Map<EObject, EObject> originalCopier = new LinkedHashMap<EObject, EObject>(copier);
for (Map.Entry<SetupTask, SetupTask> entry : directSubstitutions.entrySet())
{
SetupTask overriddenTask = entry.getKey();
SetupTask overridingTask = entry.getValue();
EObject copy = copier.get(overridingTask);
copier.put(overriddenTask, copy == null ? overridingTask : copy);
}
copyMap = copier;
copier.copyReferences();
// Perform override merging.
for (Map.Entry<SetupTask, SetupTask> entry : substitutions.entrySet())
{
SetupTask originalOverriddenSetupTask = entry.getKey();
SetupTask overriddenSetupTask = (SetupTask)originalCopier.get(originalOverriddenSetupTask);
// For synthesized tasks, there is no copy, only the original.
if (overriddenSetupTask == null)
{
overriddenSetupTask = originalOverriddenSetupTask;
}
SetupTask originalOverridingSetupTask = entry.getValue();
SetupTask overridingSetupTask = (SetupTask)originalCopier.get(originalOverridingSetupTask);
// For synthesized tasks, there is no copy, only the original.
if (overridingSetupTask == null)
{
overridingSetupTask = originalOverridingSetupTask;
}
overridingSetupTask.overrideFor(overriddenSetupTask);
}
for (ListIterator<SetupTask> it = setupTasks.listIterator(); it.hasNext();)
{
SetupTask setupTask = it.next();
if (directSubstitutions.containsKey(setupTask))
{
it.remove();
}
else
{
SetupTask copy = (SetupTask)copier.get(setupTask);
it.set(copy);
}
}
setSetupContext(
SetupContext.create((Installation)copier.get(originalInstallation), (Workspace)copier.get(originalWorkspace), (User)copier.get(originalPreferences)));
}
private EList<Map.Entry<String, Set<String>>> reorderVariables(final Map<String, Set<String>> variables)
{
EList<Map.Entry<String, Set<String>>> list = new BasicEList<Map.Entry<String, Set<String>>>(variables.entrySet());
SetupCoreUtil.reorder(list, new SetupCoreUtil.DependencyProvider<Map.Entry<String, Set<String>>>()
{
public Collection<Map.Entry<String, Set<String>>> getDependencies(Map.Entry<String, Set<String>> variable)
{
Collection<Map.Entry<String, Set<String>>> result = new ArrayList<Map.Entry<String, Set<String>>>();
for (String key : variable.getValue())
{
for (Map.Entry<String, Set<String>> entry : variables.entrySet())
{
if (entry.getKey().equals(key))
{
result.add(entry);
}
}
}
return result;
}
});
return list;
}
private void reorderSetupTasks(EList<SetupTask> setupTasks)
{
ECollections.sort(setupTasks, new Comparator<SetupTask>()
{
public int compare(SetupTask setupTask1, SetupTask setupTask2)
{
return setupTask1.getPriority() - setupTask2.getPriority();
}
});
final Map<SetupTask, Set<SetupTask>> dependencies = new LinkedHashMap<SetupTask, Set<SetupTask>>();
for (SetupTask setupTask : setupTasks)
{
CollectionUtil.addAll(dependencies, setupTask, setupTask.getPredecessors());
for (SetupTask successor : setupTask.getSuccessors())
{
CollectionUtil.add(dependencies, successor, setupTask);
}
}
SetupCoreUtil.reorder(setupTasks, new SetupCoreUtil.DependencyProvider<SetupTask>()
{
public Collection<SetupTask> getDependencies(SetupTask setupTask)
{
return dependencies.get(setupTask);
}
});
// Set up the predecessor dependencies so these tasks will not be reordered relative to each other when they are merged with tasks from other streams.
SetupTask previousSetupTask = null;
for (SetupTask setupTask : setupTasks)
{
setupTask.getSuccessors().clear();
EList<SetupTask> predecessors = setupTask.getPredecessors();
predecessors.clear();
if (!(setupTask instanceof VariableTask))
{
if (previousSetupTask != null)
{
predecessors.add(previousSetupTask);
}
previousSetupTask = setupTask;
}
}
}
private String getLabel(SetupTask setupTask)
{
IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(setupTask, IItemLabelProvider.class);
String type;
try
{
Method getTypeTextMethod = ReflectUtil.getMethod(labelProvider.getClass(), "getTypeText", Object.class);
getTypeTextMethod.setAccessible(true);
type = getTypeTextMethod.invoke(labelProvider, setupTask).toString();
}
catch (Exception ex)
{
type = setupTask.eClass().getName();
}
String label = labelProvider.getText(setupTask);
if (!label.startsWith(type))
{
label = type + " " + label;
}
int eol = Math.min(label.indexOf('\r'), label.indexOf('\n'));
if (eol != -1)
{
label = label.substring(0, eol) + "...";
}
return label.startsWith(type) ? label : type + " " + label;
}
public static void setCreationMonitor(IProgressMonitor monitor)
{
if (monitor == null)
{
CREATION_MONITOR.remove();
}
else
{
CREATION_MONITOR.set(monitor);
}
}
private static void checkCancel()
{
SetupCorePlugin.checkCancelation(CREATION_MONITOR.get());
}
/**
* Used in IDE.
*/
public static SetupTaskPerformer createForIDE(ResourceSet resourceSet, SetupPrompter prompter, Trigger trigger) throws Exception
{
return create(resourceSet.getURIConverter(), prompter, trigger, SetupContext.create(resourceSet), false);
}
/**
* Used in installer and IDE.
*/
public static SetupTaskPerformer create(URIConverter uriConverter, final SetupPrompter prompter, Trigger trigger, SetupContext setupContext,
boolean fullPrompt) throws Exception
{
List<SetupTaskPerformer> performers = new ArrayList<SetupTaskPerformer>();
boolean needsPrompt = false;
Map<Object, Set<Object>> composedMap = new HashMap<Object, Set<Object>>();
List<VariableTask> allAppliedRuleVariables = new ArrayList<VariableTask>();
List<VariableTask> allUnresolvedVariables = new ArrayList<VariableTask>();
List<VariableTask> allPasswordVariables = new ArrayList<VariableTask>();
Map<VariableTask, EAttribute> allRuleAttributes = new LinkedHashMap<VariableTask, EAttribute>();
Workspace workspace = setupContext.getWorkspace();
List<Stream> streams = workspace == null ? null : workspace.getStreams();
if (streams == null || streams.isEmpty())
{
streams = Collections.singletonList(null);
}
for (Stream stream : streams)
{
checkCancel();
if (stream == null || !stream.eIsProxy())
{
SetupTaskPerformer performer = new SetupTaskPerformer(uriConverter, prompter, null, setupContext, stream);
Set<String> undeclaredVariables = performer.getUndeclaredVariables();
final Set<VariableTask> demandCreatedUnresolvedVariables = new LinkedHashSet<VariableTask>();
if (!undeclaredVariables.isEmpty())
{
List<VariableTask> unresolvedVariables = performer.getUnresolvedVariables();
for (String variableName : undeclaredVariables)
{
VariableTask variable = SetupFactory.eINSTANCE.createVariableTask();
variable.setName(variableName);
variable.setLabel(variableName + " (undeclared)");
variable.setStorageURI(null);
variable.getAnnotations().add(BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_UNDECLARED_VARIABLE));
unresolvedVariables.add(variable);
demandCreatedUnresolvedVariables.add(variable);
}
undeclaredVariables.clear();
}
CollectionUtil.putAll(composedMap, performer.getMap());
if (fullPrompt)
{
SetupContext fullPromptContext = SetupContext.createCopy(setupContext.getInstallation(), setupContext.getWorkspace(), setupContext.getUser());
Set<VariableTask> variables = new LinkedHashSet<VariableTask>();
final SetupTaskPerformer partialPromptPerformer = performer;
prepareFullPrompt(variables, fullPromptContext.getInstallation());
prepareFullPrompt(variables, fullPromptContext.getWorkspace());
User user = fullPromptContext.getUser();
prepareFullPrompt(variables, user);
user.getAttributeRules().clear();
SetupPrompter fullPrompter = new SetupPrompter()
{
private boolean first = true;
public OS getOS()
{
return prompter.getOS();
}
public String getVMPath()
{
return prompter.getVMPath();
}
public UserCallback getUserCallback()
{
return prompter.getUserCallback();
}
public String getValue(VariableTask variable)
{
if (!first)
{
return prompter.getValue(variable);
}
return null;
}
public boolean promptVariables(List<? extends SetupTaskContext> performers)
{
for (SetupTaskContext context : performers)
{
SetupTaskPerformer promptedPerformer = (SetupTaskPerformer)context;
Map<VariableTask, EAttribute> ruleAttributes = promptedPerformer.getRuleAttributes();
for (VariableTask variable : promptedPerformer.getUnresolvedVariables())
{
EAttribute eAttribute = ruleAttributes.get(variable);
if (ruleAttributes.keySet().contains(variable))
{
AttributeRule attributeRule = partialPromptPerformer.getAttributeRule(eAttribute, false);
if (attributeRule != null)
{
String value = prompter.getValue(variable);
variable.setValue(value == null ? attributeRule.getValue() : value);
}
}
else
{
Object value = partialPromptPerformer.get(variable.getName());
if (value instanceof String)
{
variable.setValue(value.toString());
}
}
}
promptedPerformer.getUnresolvedVariables().addAll(demandCreatedUnresolvedVariables);
}
first = false;
return true;
}
};
SetupTaskPerformer fullPromptPerformer = new SetupTaskPerformer(uriConverter, fullPrompter, null, fullPromptContext, stream);
fullPrompter.promptVariables(Collections.singletonList(fullPromptPerformer));
CollectionUtil.putAll(composedMap, performer.getMap());
performer = fullPromptPerformer;
}
allAppliedRuleVariables.addAll(performer.getAppliedRuleVariables());
allUnresolvedVariables.addAll(performer.getUnresolvedVariables());
allPasswordVariables.addAll(performer.getPasswordVariables());
allRuleAttributes.putAll(performer.getRuleAttributes());
performers.add(performer);
if (!performer.getUnresolvedVariables().isEmpty())
{
needsPrompt = true;
}
}
}
if (needsPrompt)
{
if (!prompter.promptVariables(performers))
{
return null;
}
}
for (SetupTaskPerformer setupTaskPerformer : performers)
{
if (!setupTaskPerformer.unresolvedSettings.isEmpty())
{
setupTaskPerformer.resolveSettings();
}
}
// All variables have been expanded, no unresolved variables remain.
// We need a single performer for all streams.
// The per-stream performers from above have triggered task lists that must be composed into a single setup for multiple streams.
EList<SetupTask> setupTasks = new BasicEList<SetupTask>();
Set<Bundle> bundles = new HashSet<Bundle>();
for (SetupTaskPerformer performer : performers)
{
setupTasks.addAll(performer.getTriggeredSetupTasks());
bundles.addAll(performer.getBundles());
}
SetupTaskPerformer composedPerformer = new SetupTaskPerformer(uriConverter, prompter, trigger, setupContext, setupTasks);
composedPerformer.getBundles().addAll(bundles);
composedPerformer.getAppliedRuleVariables().addAll(allAppliedRuleVariables);
composedPerformer.getUnresolvedVariables().addAll(allUnresolvedVariables);
composedPerformer.getPasswordVariables().addAll(allPasswordVariables);
composedPerformer.getRuleAttributes().putAll(allRuleAttributes);
composedPerformer.redirectTriggeredSetupTasks();
File workspaceLocation = composedPerformer.getWorkspaceLocation();
if (workspaceLocation != null)
{
File workspaceSetupLocation = new File(workspaceLocation, ".metadata/.plugins/org.eclipse.oomph.setup/workspace.setup");
URI workspaceURI = URI.createFileURI(workspaceSetupLocation.toString());
for (SetupTaskPerformer performer : performers)
{
performer.getWorkspace().eResource().setURI(workspaceURI);
}
}
File configurationLocation = composedPerformer.getProductConfigurationLocation();
if (configurationLocation != null)
{
File installationLocation = new File(configurationLocation, "org.eclipse.oomph.setup/installation.setup");
URI installationURI = URI.createFileURI(installationLocation.toString());
for (SetupTaskPerformer performer : performers)
{
performer.getInstallation().eResource().setURI(installationURI);
}
}
Map<Object, Object> finalComposedMap = composedPerformer.getMap();
for (Map.Entry<Object, Set<Object>> entry : composedMap.entrySet())
{
Object key = entry.getKey();
if (!finalComposedMap.containsKey(key))
{
Set<Object> value = entry.getValue();
value.remove(null);
value.remove("");
if (value.size() == 1)
{
finalComposedMap.put(key, value.iterator().next());
}
}
}
return composedPerformer;
}
public static Set<? extends Authenticator> getAuthenticators(VariableTask variable)
{
VariableAdapter variableAdapter = (VariableAdapter)EcoreUtil.getExistingAdapter(variable, VariableAdapter.class);
if (variableAdapter != null)
{
return variableAdapter.getAuthenticators(variable);
}
return null;
}
private static class VariableAdapter extends AdapterImpl
{
private SetupTaskPerformer performer;
public VariableAdapter(SetupTaskPerformer perform)
{
performer = perform;
}
@Override
public boolean isAdapterForType(Object type)
{
return type == VariableAdapter.class;
}
protected Set<? extends Authenticator> getAuthenticators(final VariableTask variable)
{
StringExpander stringExpander = new StringExpander()
{
@Override
protected String resolve(String key)
{
String value = getValue(key);
return StringUtil.isEmpty(value) ? performer.resolve(key) : value;
}
@Override
protected boolean isUnexpanded(String key)
{
return performer.isUnexpanded(key) && StringUtil.isEmpty(getValue(key));
}
private String getValue(String key)
{
VariableTask variable = performer.allVariables.get(key);
if (variable != null)
{
return performer.getPrompter().getValue(variable);
}
return null;
}
@Override
protected String filter(String value, String filterName)
{
return performer.filter(value, filterName);
}
};
return Authenticator.create(variable, stringExpander);
}
}
private static class FullPromptMarker extends AdapterImpl
{
@Override
public boolean isAdapterForType(Object type)
{
return type == FullPromptMarker.class;
}
}
private static boolean isFullPromptUser(User user)
{
return EcoreUtil.getExistingAdapter(user, FullPromptMarker.class) != null;
}
private static void prepareFullPrompt(Set<VariableTask> variables, ModelElement modelElement)
{
if (modelElement != null)
{
for (Iterator<EObject> it = modelElement.eAllContents(); it.hasNext();)
{
EObject eObject = it.next();
if (eObject instanceof VariableTask)
{
VariableTask variableTask = (VariableTask)eObject;
variables.add(variableTask);
variableTask.setValue(null);
}
}
setFullPromptMarker(modelElement);
}
}
private static void setFullPromptMarker(ModelElement modelElement)
{
modelElement.eAdapters().add(new FullPromptMarker());
}
public void setProgress(ProgressLog progress)
{
this.progress = progress;
}
public static boolean disableAutoBuilding() throws CoreException
{
return SetupContext.USE_RESOURCES_BUNDLE && WorkspaceUtil.disableAutoBuilding();
}
public static void restoreAutoBuilding(boolean autoBuilding) throws CoreException
{
if (SetupContext.USE_RESOURCES_BUNDLE)
{
WorkspaceUtil.restoreAutoBuilding(autoBuilding);
}
}
public static EList<SetupTask> createEnablementTasks(EModelElement eModelElement, boolean withVariables)
{
EList<SetupTask> enablementTasks = null;
for (EAnnotation eAnnotation : eModelElement.getEAnnotations())
{
String source = eAnnotation.getSource();
if (EAnnotationConstants.ANNOTATION_ENABLEMENT.equals(source))
{
if (enablementTasks == null)
{
enablementTasks = new BasicEList<SetupTask>();
}
String repositoryLocation = eAnnotation.getDetails().get(EAnnotationConstants.KEY_REPOSITORY);
if (!StringUtil.isEmpty(repositoryLocation))
{
if (withVariables)
{
String variableName = eAnnotation.getDetails().get(EAnnotationConstants.KEY_VARIABLE_NAME);
if (!StringUtil.isEmpty(variableName))
{
VariableTask variable = SetupFactory.eINSTANCE.createVariableTask();
variable.setName(variableName);
variable.setValue(repositoryLocation);
enablementTasks.add(0, variable);
repositoryLocation = getVariableReference(variableName, null);
}
}
}
P2Task p2Task = SetupP2Factory.eINSTANCE.createP2Task();
EList<Requirement> requirements = p2Task.getRequirements();
String ius = eAnnotation.getDetails().get(EAnnotationConstants.KEY_INSTALLABLE_UNITS);
if (!StringUtil.isEmpty(ius))
{
for (String requirementSpecification : ius.split("\\s"))
{
Matcher matcher = INSTALLABLE_UNIT_WITH_RANGE_PATTERN.matcher(requirementSpecification);
if (matcher.matches())
{
Requirement requirement = P2Factory.eINSTANCE.createRequirement(matcher.group(1));
String versionRange = matcher.group(2);
if (!StringUtil.isEmpty(versionRange))
{
requirement.setVersionRange(new VersionRange(versionRange));
}
requirements.add(requirement);
}
}
}
if (!StringUtil.isEmpty(repositoryLocation))
{
Repository repository = P2Factory.eINSTANCE.createRepository(repositoryLocation);
p2Task.getRepositories().add(repository);
}
// Ensure that these are first so that these are the targets for merging rather than the sources.
// The latter causes problems in the copier.
enablementTasks.add(0, p2Task);
}
}
EObject eContainer = eModelElement.eContainer();
if (eContainer instanceof EModelElement)
{
EList<SetupTask> containerEnablementTasks = createEnablementTasks((EModelElement)eContainer, withVariables);
if (containerEnablementTasks != null)
{
if (enablementTasks == null)
{
enablementTasks = containerEnablementTasks;
}
else
{
enablementTasks.addAll(containerEnablementTasks);
}
}
}
return enablementTasks;
}
private static String getVariableReference(String variableName, EAnnotation variableAnnotation)
{
if (variableAnnotation != null)
{
String filter = variableAnnotation.getDetails().get(EAnnotationConstants.KEY_FILTER);
if (filter != null)
{
return "${" + variableName + "|" + filter + "}";
}
}
return "${" + variableName + "}";
}
/**
* @author Eike Stepper
*/
public static final class ExecutableInfo
{
private final File eclipseLocation;
private final File executable;
private final boolean needsConsole;
private final OS os;
private ExecutableInfo(SetupTaskPerformer performer)
{
os = performer.getOS();
String relativeProductFolder = performer.getRelativeProductFolder();
String relativeExecutableFolder = os.getRelativeExecutableFolder();
String executableName = os.getExecutableName(performer.getLauncherName());
File eclipseLocation = new File(performer.getInstallationLocation(), relativeProductFolder);
File executableFolder = new File(eclipseLocation, relativeExecutableFolder);
File executable = new File(executableFolder, executableName);
needsConsole = computeNeedsConsole(performer);
if (needsConsole && os.isWin())
{
String consoleExecutableName = executableName.substring(0, executableName.length() - ".exe".length()) + "c.exe";
File consoleExectuable = new File(executableFolder, consoleExecutableName);
if (consoleExectuable.isFile())
{
executable = consoleExectuable;
}
}
this.eclipseLocation = eclipseLocation;
this.executable = executable;
}
public File getEclipseLocation()
{
return eclipseLocation;
}
public File getExecutable()
{
return executable;
}
public File getLaunchLocation()
{
return os.isMac() ? executable.getParentFile().getParentFile().getParentFile() : executable;
}
public boolean needsConsole()
{
return needsConsole;
}
private static boolean computeNeedsConsole(SetupTaskPerformer performer)
{
for (SetupTask task : performer.getTriggeredSetupTasks())
{
if (task instanceof EclipseIniTask)
{
EclipseIniTask iniTask = (EclipseIniTask)task;
if (!iniTask.isVm() && "-console".equals(iniTask.getOption()))
{
return true;
}
}
}
return false;
}
}
protected static class ValueConverter
{
public Object createFromString(String literal)
{
return literal;
}
public String convertToString(Object value)
{
return value == null ? null : value.toString();
}
}
protected static class URIValueConverter extends ValueConverter
{
@Override
public Object createFromString(String literal)
{
return BaseFactory.eINSTANCE.createURI(literal);
}
}
private static class PDEAPIUtil
{
private static final Field BUILD_DISABLED_FIELD;
static
{
Field buildDisabledField = null;
// Disable API analysis building for the initial build.
try
{
Class<?> apiAnalysisBuilder = CommonPlugin.loadClass("org.eclipse.pde.api.tools", "org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder");
buildDisabledField = apiAnalysisBuilder.getDeclaredField("buildDisabled");
buildDisabledField.setAccessible(true);
}
catch (Exception ex)
{
// Ignore
}
BUILD_DISABLED_FIELD = buildDisabledField;
}
private static boolean setDisableAPIAnalysisBuilder(boolean disabled)
{
if (BUILD_DISABLED_FIELD != null)
{
try
{
boolean result = (Boolean)BUILD_DISABLED_FIELD.get(null);
if (result != disabled)
{
BUILD_DISABLED_FIELD.set(null, disabled);
}
return result;
}
catch (Exception ex)
{
// Ignore.
}
}
return true;
}
}
/**
* @author Eike Stepper
*/
private static class WorkspaceUtil
{
private static boolean disableAutoBuilding() throws CoreException
{
boolean autoBuilding = ResourcesPlugin.getWorkspace().isAutoBuilding();
if (autoBuilding)
{
restoreAutoBuilding(false);
}
return autoBuilding;
}
private static void restoreAutoBuilding(boolean autoBuilding) throws CoreException
{
if (autoBuilding != ResourcesPlugin.getWorkspace().isAutoBuilding())
{
IWorkspaceDescription description = ResourcesPlugin.getWorkspace().getDescription();
description.setAutoBuilding(autoBuilding);
ResourcesPlugin.getWorkspace().setDescription(description);
}
}
private static void performNeededSetupTasks(final SetupTaskPerformer performer, IProgressMonitor monitor) throws Exception
{
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable()
{
public void run(IProgressMonitor monitor) throws CoreException
{
try
{
performer.doPerformNeededSetupTasks(monitor);
}
catch (Throwable t)
{
SetupCorePlugin.INSTANCE.coreException(t);
}
}
}, null, IWorkspace.AVOID_UPDATE, monitor);
}
}
}