diff options
76 files changed, 7328 insertions, 432 deletions
diff --git a/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF index 0d3d760cc..7396404bf 100644 --- a/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF @@ -12,6 +12,6 @@ Export-Package: org.eclipse.oomph.base.provider;version="1.5.0";x-internal:=true org.eclipse.oomph.edit;version="1.5.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.edit;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, - org.eclipse.oomph.base;bundle-version="[1.10.0,2.0.0)";visibility:=reexport + org.eclipse.oomph.base;bundle-version="[1.11.0,2.0.0)";visibility:=reexport Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.base.edit diff --git a/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/base/provider/ModelElementItemProvider.java b/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/base/provider/ModelElementItemProvider.java index 9783e16e2..edc4a48ac 100644 --- a/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/base/provider/ModelElementItemProvider.java +++ b/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/base/provider/ModelElementItemProvider.java @@ -949,7 +949,7 @@ public class ModelElementItemProvider extends ItemProviderAdapter { if (image == null) { - new AdapterFactoryItemDelegator(adapterFactory).getImage(EcorePackage.Literals.ECLASS); + image = new AdapterFactoryItemDelegator(adapterFactory).getImage(EcorePackage.Literals.ECLASS); } } diff --git a/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/NoChildrenDelegatingWrapperItemProvider.java b/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/NoChildrenDelegatingWrapperItemProvider.java new file mode 100644 index 000000000..bd3e18833 --- /dev/null +++ b/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/NoChildrenDelegatingWrapperItemProvider.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.edit; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.command.CommandParameter; +import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider; + +import java.util.Collection; +import java.util.Collections; + +/** + * @author Ed Merks + */ +public class NoChildrenDelegatingWrapperItemProvider extends DelegatingWrapperItemProvider +{ + public NoChildrenDelegatingWrapperItemProvider(Object value, Object owner, EStructuralFeature feature, int index, AdapterFactory adapterFactory) + { + super(value, owner, feature, index, adapterFactory); + } + + public NoChildrenDelegatingWrapperItemProvider(Object value, Object owner, AdapterFactory adapterFactory) + { + this(value, owner, null, CommandParameter.NO_INDEX, adapterFactory); + } + + @Override + public boolean hasChildren(Object object) + { + return false; + } + + @Override + protected void updateChildren() + { + // Don't show children. + } + + @Override + public Collection<?> getChildren(Object object) + { + return Collections.emptyList(); + } +} diff --git a/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF index cf09ced1e..dd636098a 100644 --- a/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF @@ -2,19 +2,19 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.base;singleton:=true -Bundle-Version: 1.10.0.qualifier +Bundle-Version: 1.11.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.internal.base.BasePlugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.oomph.base;version="1.10.0";x-internal:=true, - org.eclipse.oomph.base.impl;version="1.10.0";x-internal:=true, - org.eclipse.oomph.base.util;version="1.10.0";x-internal:=true, - org.eclipse.oomph.internal.base;version="1.10.0";x-internal:=true +Export-Package: org.eclipse.oomph.base;version="1.11.0";x-internal:=true, + org.eclipse.oomph.base.impl;version="1.11.0";x-internal:=true, + org.eclipse.oomph.base.util;version="1.11.0";x-internal:=true, + org.eclipse.oomph.internal.base;version="1.11.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.ecore;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, - org.eclipse.oomph.util;bundle-version="[1.10.0,2.0.0)";visibility:=reexport + org.eclipse.oomph.util;bundle-version="[1.11.0,2.0.0)";visibility:=reexport Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.base diff --git a/plugins/org.eclipse.oomph.base/model/Base.ecore b/plugins/org.eclipse.oomph.base/model/Base.ecore index 3351688b5..868562b2d 100644 --- a/plugins/org.eclipse.oomph.base/model/Base.ecore +++ b/plugins/org.eclipse.oomph.base/model/Base.ecore @@ -21,7 +21,9 @@ </eAnnotations> <eStructuralFeatures xsi:type="ecore:EReference" name="modelElement" eType="#//ModelElement" transient="true" resolveProxies="false" eOpposite="#//ModelElement/annotations"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="source" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="source" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> + </eStructuralFeatures> <eStructuralFeatures xsi:type="ecore:EReference" name="details" upperBound="-1" eType="#//StringToStringMapEntry" containment="true" resolveProxies="false"> <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> @@ -43,7 +45,9 @@ </eStructuralFeatures> </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="StringToStringMapEntry" instanceClassName="java.util.Map$Entry"> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> + </eStructuralFeatures> <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="#//Text"> <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> <details key="kind" value="element"/> diff --git a/plugins/org.eclipse.oomph.base/pom.xml b/plugins/org.eclipse.oomph.base/pom.xml index 998944eee..c70a398c5 100644 --- a/plugins/org.eclipse.oomph.base/pom.xml +++ b/plugins/org.eclipse.oomph.base/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.base</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.11.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/Annotation.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/Annotation.java index ee350b746..ef438ecf6 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/Annotation.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/Annotation.java @@ -75,7 +75,7 @@ public interface Annotation extends ModelElement * @return the value of the '<em>Source</em>' attribute. * @see #setSource(String) * @see org.eclipse.oomph.base.BasePackage#getAnnotation_Source() - * @model + * @model annotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ String getSource(); diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BaseFactory.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BaseFactory.java index 3cc17efe0..c22e26128 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BaseFactory.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BaseFactory.java @@ -13,6 +13,8 @@ package org.eclipse.oomph.base; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EFactory; +import java.util.Map; + /** * <!-- begin-user-doc --> * The <b>Factory</b> for the model. @@ -48,6 +50,8 @@ public interface BaseFactory extends EFactory Annotation createInfoAnnotation(String diagnostic); + Map.Entry<String, String> createStringToStringMapEntry(); + /** * Returns an instance of data type '<em>URI</em>' corresponding the given literal. * <!-- begin-user-doc --> diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BasePackage.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BasePackage.java index bae7bfdb9..fb6364f88 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BasePackage.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/BasePackage.java @@ -394,6 +394,7 @@ public interface BasePackage extends EPackage * @return the meta object for class '<em>String To String Map Entry</em>'. * @see java.util.Map.Entry * @model keyDataType="org.eclipse.emf.ecore.EString" + * keyAnnotation="http://www.eclipse.org/oomph/setup/NoExpand" * valueDataType="org.eclipse.oomph.base.Text" * valueExtendedMetaData="kind='element'" * @generated diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/AnnotationImpl.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/AnnotationImpl.java index 733628188..be58d8a07 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/AnnotationImpl.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/AnnotationImpl.java @@ -433,7 +433,7 @@ public class AnnotationImpl extends ModelElementImpl implements Annotation return super.toString(); } - StringBuffer result = new StringBuffer(super.toString()); + StringBuilder result = new StringBuilder(super.toString()); result.append(" (source: "); result.append(source); result.append(')'); diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/BasePackageImpl.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/BasePackageImpl.java index 44f0d0fc5..0f06b92a0 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/BasePackageImpl.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/BasePackageImpl.java @@ -131,8 +131,8 @@ public class BasePackageImpl extends EPackageImpl implements BasePackage } // Obtain or create and register package - BasePackageImpl theBasePackage = (BasePackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof BasePackageImpl - ? EPackage.Registry.INSTANCE.get(eNS_URI) : new BasePackageImpl()); + Object registeredBasePackage = EPackage.Registry.INSTANCE.get(eNS_URI); + BasePackageImpl theBasePackage = registeredBasePackage instanceof BasePackageImpl ? (BasePackageImpl)registeredBasePackage : new BasePackageImpl(); isInited = true; @@ -450,6 +450,8 @@ public class BasePackageImpl extends EPackageImpl implements BasePackage createExtendedMetaDataAnnotations(); // http://www.eclipse.org/emf/2002/Ecore createEcoreAnnotations(); + // http://www.eclipse.org/oomph/setup/NoExpand + createNoExpandAnnotations(); } /** @@ -494,4 +496,17 @@ public class BasePackageImpl extends EPackageImpl implements BasePackage addAnnotation(annotationEClass, source, new String[] { "constraints", "WellFormedSourceURI" }); } + /** + * Initializes the annotations for <b>http://www.eclipse.org/oomph/setup/NoExpand</b>. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void createNoExpandAnnotations() + { + String source = "http://www.eclipse.org/oomph/setup/NoExpand"; + addAnnotation(getAnnotation_Source(), source, new String[] {}); + addAnnotation(getStringToStringMapEntry_Key(), source, new String[] {}); + } + } // BasePackageImpl diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/StringToStringMapEntryImpl.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/StringToStringMapEntryImpl.java index 084dd8b46..33697284a 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/StringToStringMapEntryImpl.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/impl/StringToStringMapEntryImpl.java @@ -236,7 +236,7 @@ public class StringToStringMapEntryImpl extends MinimalEObjectImpl.Container imp return super.toString(); } - StringBuffer result = new StringBuffer(super.toString()); + StringBuilder result = new StringBuilder(super.toString()); result.append(" (key: "); result.append(key); result.append(", value: "); diff --git a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupContext.java b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupContext.java index b2784da62..ec7125d5a 100644 --- a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupContext.java +++ b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupContext.java @@ -303,7 +303,10 @@ public class SetupContext User user = createUser(); Workspace workspace = createWorkspace(); - workspace.getStreams().add(stream); + if (stream != null) + { + workspace.getStreams().add(stream); + } Installation installation = createInstallation(); installation.setProductVersion(productVersion); diff --git a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupTaskPerformer.java b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupTaskPerformer.java index 410e0b2c1..84f9b601e 100644 --- a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupTaskPerformer.java +++ b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/SetupTaskPerformer.java @@ -16,6 +16,7 @@ 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.BaseResourceImpl; import org.eclipse.oomph.base.util.BaseUtil; import org.eclipse.oomph.internal.setup.SetupPrompter; import org.eclipse.oomph.internal.setup.SetupProperties; @@ -26,12 +27,16 @@ 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.Argument; 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.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.PreferenceTask; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; @@ -156,14 +161,13 @@ 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.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.regex.Matcher; @@ -180,7 +184,9 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext public static final Adapter RULE_VARIABLE_ADAPTER = new AdapterImpl(); - private static final Map<String, ValueConverter> CONVERTERS = new HashMap<String, ValueConverter>(); + private static final Pattern FILTER_MEMBER_PATTERN = Pattern.compile("(\\(\\s*)([^~<>=\\(\\)]+)([~<>=\\\\(\\\\)])"); + + private static final Map<String, ValueConverter> CONVERTERS = new LinkedHashMap<String, ValueConverter>(); static { @@ -206,11 +212,13 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext private EList<SetupTask> triggeredSetupTasks; - private Map<EObject, EObject> copyMap; + private final Map<EObject, Set<EObject>> copyMap = new LinkedHashMap<EObject, Set<EObject>>(); + + private final Map<EObject, Set<EObject>> macroCopyMap = new LinkedHashMap<EObject, Set<EObject>>(); private EList<SetupTask> neededSetupTasks; - private final Set<Bundle> bundles = new HashSet<Bundle>(); + private final Set<Bundle> bundles = new LinkedHashSet<Bundle>(); /** * A list that contains instances of String and/or Pair<String, ProgressLog.Severity>. @@ -464,7 +472,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext Map<SetupTask, SetupTask> substitutions = getSubstitutions(triggeredSetupTasks); // Shorten the paths through the substitutions map - Map<SetupTask, SetupTask> directSubstitutions = new HashMap<SetupTask, SetupTask>(substitutions); + Map<SetupTask, SetupTask> directSubstitutions = new LinkedHashMap<SetupTask, SetupTask>(substitutions); for (Map.Entry<SetupTask, SetupTask> entry : directSubstitutions.entrySet()) { SetupTask task = entry.getValue(); @@ -485,7 +493,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext if (phase == Phase.COMPOSE_PHASE) { // Perform override merging. - Map<SetupTask, SetupTask> overrides = new HashMap<SetupTask, SetupTask>(); + Map<SetupTask, SetupTask> overrides = new LinkedHashMap<SetupTask, SetupTask>(); for (Map.Entry<SetupTask, SetupTask> entry : substitutions.entrySet()) { SetupTask overriddenSetupTask = entry.getKey(); @@ -620,7 +628,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext copySetup(stream, triggeredSetupTasks, substitutions, directSubstitutions); // 2.4. Build variable map in the context - Map<String, VariableTask> explicitKeys = new HashMap<String, VariableTask>(); + Map<String, VariableTask> explicitKeys = new LinkedHashMap<String, VariableTask>(); for (SetupTask setupTask : triggeredSetupTasks) { if (setupTask instanceof VariableTask) @@ -883,7 +891,8 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext appliedRuleVariables.clear(); attributeRules.clear(); bundles.clear(); - copyMap = null; + copyMap.clear(); + macroCopyMap.clear(); originalMap.keySet().retainAll(originalMap.keySet()); originalMap.putAll(originalMap); @@ -905,8 +914,10 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext private String getAttributeRuleVariableName(EAttribute eAttribute) { - String attributeName = ExtendedMetaData.INSTANCE.getName(eAttribute); - String variableName = "@<id>." + eAttribute.getEContainingClass() + "." + attributeName; + EClass eContainingClass = eAttribute.getEContainingClass(); + String instanceTypeName = eContainingClass.getInstanceTypeName(); + String variableName = "@<id>." + + (instanceTypeName != null ? instanceTypeName + "." + ExtendedMetaData.INSTANCE.getName(eAttribute) : getAttributeURI(eAttribute)); return variableName; } @@ -1488,9 +1499,16 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext String qualifier = null; Scope rootProject = null; + // Expand all the macros, effectively to make a deep recursive copy of all the tasks. + Map<MacroTask, Macro> expandedMacros = new LinkedHashMap<MacroTask, Macro>(); + for (Scope scope : scopes) + { + expandMacroTasks(macroCopyMap, expandedMacros, scope); + } + for (Scope scope : scopes) { - gatherFilters(configurableItems, scope); + gatherFilters(configurableItems, expandedMacros, scope); } for (Scope scope : scopes) @@ -1569,9 +1587,14 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext generateScopeVariables(result, "user", qualifier, name, label, description); break; } + case MACRO: + { + // Macros do not generate any scope variables. + break; + } } - getSetupTasks(result, configurableItems, scope, false); + getSetupTasks(result, configurableItems, expandedMacros, scope, false); } } @@ -1651,7 +1674,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext task.setVm(vm); task.setOption(option); task.setValue(value); - task.setExcludedTriggers(new HashSet<Trigger>(Arrays.asList(new Trigger[] { Trigger.STARTUP, Trigger.MANUAL }))); + task.setExcludedTriggers(new LinkedHashSet<Trigger>(Arrays.asList(new Trigger[] { Trigger.STARTUP, Trigger.MANUAL }))); result.add(task); } @@ -1677,8 +1700,10 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext return variable; } - private void getSetupTasks(EList<SetupTask> setupTasks, List<Scope> configurableItems, SetupTaskContainer setupTaskContainer, boolean isFiltered) + private void getSetupTasks(EList<SetupTask> setupTasks, List<Scope> configurableItems, Map<MacroTask, Macro> expandedMacros, + SetupTaskContainer setupTaskContainer, boolean isFiltered) { + // Visit the container's contents. for (SetupTask setupTask : setupTaskContainer.getSetupTasks()) { if (setupTask.isDisabled()) @@ -1706,17 +1731,433 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext if (setupTask instanceof SetupTaskContainer) { + // If it's a container, visit the contents. SetupTaskContainer container = (SetupTaskContainer)setupTask; - getSetupTasks(setupTasks, configurableItems, container, effectiveIsFiltered); + getSetupTasks(setupTasks, configurableItems, expandedMacros, container, effectiveIsFiltered); } - else if (!effectiveIsFiltered) + else { - setupTasks.add(setupTask); + // If the task is a macro task that has been expanded, visit the expanded macro instead. + Macro macro = expandedMacros.get(setupTask); + if (macro != null) + { + getSetupTasks(setupTasks, configurableItems, expandedMacros, macro, effectiveIsFiltered); + } + else if (!effectiveIsFiltered) + { + // Otherwise add the leaf task. + setupTasks.add(setupTask); + } } } } - private void gatherFilters(List<Scope> configurableItems, SetupTaskContainer setupTaskContainer) + private void expandMacroTasks(Map<EObject, Set<EObject>> macroCopies, Map<MacroTask, Macro> expandedMacros, SetupTaskContainer setupTaskContainer) + { + for (SetupTask setupTask : setupTaskContainer.getSetupTasks()) + { + if (setupTask instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)setupTask; + Macro macro = macroTask.getMacro(); + if (macro != null) + { + // Deeply copy the macro for this macro task, keep track of this task as the logical container, and put it in the map. + Macro copiedAndExpandedMacro = copyAndExpandMacro(macroCopies, new LinkedHashSet<Macro>(), macroTask, macro); + copiedAndExpandedMacro.setLogicalContainer(macroTask); + expandedMacros.put(macroTask, copiedAndExpandedMacro); + } + } + else if (setupTask instanceof SetupTaskContainer) + { + // Visit all the recursively contained tasks. + SetupTaskContainer container = (SetupTaskContainer)setupTask; + expandMacroTasks(macroCopies, expandedMacros, container); + } + } + } + + public static CompoundTask expand(MacroTask macroTask) + { + Macro macro = macroTask.getMacro(); + if (macro != null) + { + Macro copiedAndExpandedMacro = copyAndExpandMacro(new LinkedHashMap<EObject, Set<EObject>>(), new LinkedHashSet<Macro>(), macroTask, macro); + return (CompoundTask)copiedAndExpandedMacro.getSetupTasks().get(0); + } + + return null; + } + + private static Macro copyAndExpandMacro(final Map<EObject, Set<EObject>> macroCopies, final Set<Macro> visited, final MacroTask macroTask, final Macro macro) + { + // Prevent infinite recursion of macro expansion. + if (visited.add(macro)) + { + EcoreUtil.Copier copier = new EcoreUtil.Copier(true, false) + { + 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) + { + // A macro might not be expanded, i.e., if it's circular. + @SuppressWarnings("unchecked") + T t = (T)copy((EObject)object); + if (t != null) + { + result.add(t); + } + } + + return result; + } + + @Override + public EObject copy(EObject eObject) + { + if (eObject instanceof MacroTask) + { + // Recursively create an independent copy of the macro task's macro. + MacroTask macroTask = (MacroTask)eObject; + Macro macro = macroTask.getMacro(); + Macro copiedAndExpandedMacro = copyAndExpandMacro(macroCopies, visited, macroTask, macro); + if (copiedAndExpandedMacro == null) + { + return null; + } + + // The copy will have exactly one task because a compound task is created. + // This task will be a replacement, i.e., act as the copy of the macro task. + SetupTask setupTask = copiedAndExpandedMacro.getSetupTasks().get(0); + put(macroTask, setupTask); + return setupTask; + } + else if (eObject == macro) + { + Macro copiedMacro = (Macro)super.copy(macro); + applyArguments(macroCopies, macroTask, copiedMacro); + + // When coping a macro, embed all the tasks in a compound task and copy over all the "containing" macro tasks features. + // This ensures that filters, restrictions, predecessors, and successors are properly preserved/respected for the macro expansion. + CompoundTask compoundTask = SetupFactory.eINSTANCE.createCompoundTask(copiedMacro.getLabel()); + for (EStructuralFeature eStructuralFeature : SetupPackage.Literals.SETUP_TASK.getEAllStructuralFeatures()) + { + if (eStructuralFeature.isChangeable() && macroTask.eIsSet(eStructuralFeature)) + { + Object value = macroTask.eGet(eStructuralFeature); + if (eStructuralFeature instanceof EReference && ((EReference)eStructuralFeature).isContainment()) + { + @SuppressWarnings("unchecked") + Collection<EObject> listValue = (Collection<EObject>)value; + value = EcoreUtil.copyAll(listValue); + + } + compoundTask.eSet(eStructuralFeature, value); + } + } + + // Replace the setup tasks with this compound task. + compoundTask.getSetupTasks().addAll(copiedMacro.getSetupTasks()); + copiedMacro.getSetupTasks().add(compoundTask); + + return copiedMacro; + } + + // Otherwise do a normal copy. + return super.copy(eObject); + } + + @Override + protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) + { + // Don't copy the macro task's macro reference. + if (eReference != SetupPackage.Literals.MACRO_TASK__MACRO) + { + super.copyReference(eReference, eObject, copyEObject); + } + } + }; + + // Copy the macro and its references and then forget that we've visited it. + Macro copy = (Macro)copier.copy(macro); + copier.copyReferences(); + + for (Map.Entry<EObject, EObject> entry : copier.entrySet()) + { + EObject key = entry.getKey(); + EObject value = entry.getValue(); + if (value != null) + { + Set<EObject> copies = macroCopies.get(key); + if (copies == null) + { + copies = new LinkedHashSet<EObject>(); + macroCopies.put(key, copies); + } + copies.add(value); + } + } + + visited.remove(macro); + return copy; + } + else + { + // We should not keep copying forever. + return null; + } + } + + private static void applyArguments(Map<EObject, Set<EObject>> macroCopies, MacroTask macroTask, Macro macro) + { + final String macroTaskID = StringUtil.isEmpty(macroTask.getID()) ? "macro" : macroTask.getID(); + EList<Parameter> parameters = macro.getParameters(); + EList<Argument> arguments = macroTask.getArguments(); + + // These are variable names that will be redirected to used qualified names. + final Map<String, String> variableSubstitutions = new LinkedHashMap<String, String>(); + final Set<VariableTask> parameterVariables = new LinkedHashSet<VariableTask>(); + if (!parameters.isEmpty()) + { + // Add variable tasks to bind arguments to parameters. + EList<SetupTask> setupTasks = macro.getSetupTasks(); + int index = 0; + for (Parameter parameter : parameters) + { + String parameterName = parameter.getName(); + if (parameterName != null) + { + // Find the corresponding argument by finding the argument with a parameter whose name matches. + // At this point, the macro copy references contains copies of the parameters. + Argument correspondingArgument = null; + for (Argument argument : arguments) + { + Parameter argumentParameter = argument.getParameter(); + if (argumentParameter != null) + { + String argumentParameterName = argumentParameter.getName(); + if (parameterName.equals(argumentParameterName)) + { + correspondingArgument = argument; + break; + } + } + } + + String argumentValue = correspondingArgument == null || correspondingArgument.getValue() == null ? parameter.getDefaultValue() + : correspondingArgument.getValue(); + + // Create the variable and add it at the start, it's marked local and will be qualified in the loop that follows. + VariableTask variable = SetupFactory.eINSTANCE.createVariableTask(); + variable.setName("*" + parameterName); + variable.setValue(argumentValue); + setupTasks.add(index++, variable); + + // Map the argument to the variable used to bind its value. + if (correspondingArgument != null) + { + Set<EObject> set = new LinkedHashSet<EObject>(); + set.add(variable); + macroCopies.put(correspondingArgument, set); + } + + // Map the parameter to the variable used to bind its value. + Set<EObject> set = new LinkedHashSet<EObject>(); + set.add(variable); + macroCopies.put(parameter, set); + + // Remember these so that we don't process the value when replacing references. + parameterVariables.add(variable); + + // Qualify the parameter name with the task's ID. + String qualifiedName = createQualifiedName(macroTaskID, parameterName); + + // Redirect any references to the parameter name to use the qualified name instead. + variableSubstitutions.put(parameterName, qualifiedName); + } + } + } + + // Any variable references that start with an ID as a qualifier will be redirected to use a more uniquely qualified ID. + final Set<String> ids = new LinkedHashSet<String>(); + for (Iterator<EObject> it = macro.eAllContents(); it.hasNext();) + { + EObject eObject = it.next(); + if (eObject instanceof SetupTask) + { + SetupTask setupTask = (SetupTask)eObject; + String id = setupTask.getID(); + if (!StringUtil.isEmpty(id)) + { + // If the task has an ID, remember it and update it to be qualified by the task's ID. + ids.add(id); + setupTask.setID(macroTaskID + '.' + id); + } + + if (setupTask instanceof VariableTask) + { + // If it's a variable and the name is "marked" to indicate it's a local variable... + VariableTask variable = (VariableTask)setupTask; + String name = variable.getName(); + if (name != null && name.startsWith("*")) + { + // Change the name to be qualified, and remember to redirect uses of this variable name to the new local qualified name. + String baseName = name.substring(1); + String qualifiedName = createQualifiedName(macroTaskID, baseName); + variable.setName(qualifiedName); + variableSubstitutions.put(name, qualifiedName); + } + } + } + } + + class ValueTransformer + { + public String transform(String string) + { + if (!StringUtil.isEmpty(string)) + { + // Find all variable references and replace them with the remapped name. + Matcher matcher = StringExpander.STRING_EXPANSION_PATTERN.matcher(string); + if (matcher.find()) + { + StringBuffer result = new StringBuffer(); + do + { + String group1 = matcher.group(1); + if ("$".equals(group1)) + { + matcher.appendReplacement(result, "\\$\\$"); + } + else + { + String key = matcher.group(2); + matcher.appendReplacement(result, "\\${" + remap(key).replace("$", "\\$") + "$3}"); + } + } while (matcher.find()); + + matcher.appendTail(result); + return result.toString(); + } + } + + return string; + } + + public String remap(String variableName) + { + // If the variable name is directly redirected, return that substitution. + String variableSubstitution = variableSubstitutions.get(variableName); + if (variableSubstitution != null) + { + return variableSubstitution; + } + + for (String id : ids) + { + // Check if the variable name is qualified by any ID. + if (variableName.startsWith(id) && (id.equals(variableName) || variableName.charAt(id.length()) == '.')) + { + // If so, redirect it to the more qualified name. + return macroTaskID + '.' + variableName; + } + } + + return variableName; + } + } + + // Transform all contents in the macro. + final ValueTransformer valueTransformer = new ValueTransformer(); + for (Iterator<EObject> it = macro.eAllContents(); it.hasNext();) + { + // Don't expand the values of the variables containing the parameter values. + // They are resolved in the scope of the containing context. + EObject eObject = it.next(); + if (!parameterVariables.contains(eObject)) + { + EClass eClass = eObject.eClass(); + for (EAttribute attribute : eClass.getEAllAttributes()) + { + if (attribute == SetupPackage.Literals.SETUP_TASK__FILTER) + { + // If it's the filter property, we need to look variable references in the filter. + SetupTask setupTask = (SetupTask)eObject; + Set<String> filterProperties = getFilterProperties(setupTask); + if (!filterProperties.isEmpty()) + { + // Re-compose the filter, redirecting any member names that correspond to remapped variables. + String filter = setupTask.getFilter(); + StringBuffer result = new StringBuffer(); + Matcher matcher = FILTER_MEMBER_PATTERN.matcher(filter); + while (matcher.find()) + { + String memberName = matcher.group(2); + String remappedMemberName = valueTransformer.remap(memberName); + matcher.appendReplacement(result, "$1" + remappedMemberName.replace("$", "\\$") + "$3"); + } + + matcher.appendTail(result); + setupTask.setFilter(result.toString()); + } + } + else if (attribute.isChangeable() && attribute.getEAnnotation(EAnnotationConstants.ANNOTATION_NO_EXPAND) == null) + { + // Visit all the values that might validly contain variable references. + 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>(); + for (Object value : values) + { + String newValue = valueTransformer.transform(valueConverter.convertToString(value)); + newValues.add(valueConverter.createFromString(newValue)); + } + + eObject.eSet(attribute, newValues); + } + else + { + Object value = eObject.eGet(attribute); + if (value != null) + { + String newValue = valueTransformer.transform(valueConverter.convertToString(value)); + eObject.eSet(attribute, valueConverter.createFromString(newValue)); + } + } + } + } + } + } + } + + // Dump the result. + if (Boolean.FALSE) + { + BaseResourceImpl resource = new BaseResourceImpl(URI.createURI("dummy.setup")); + resource.getContents().add(EcoreUtil.copy(macro)); + try + { + System.out.println(macro.getLabel() + " : " + macroTaskID); + resource.doSave(System.out, null); + System.out.println(); + } + catch (IOException ex) + { + ex.printStackTrace(); + } + } + } + + private void gatherFilters(List<Scope> configurableItems, Map<MacroTask, Macro> expandedMacros, SetupTaskContainer setupTaskContainer) { for (SetupTask setupTask : setupTaskContainer.getSetupTasks()) { @@ -1733,17 +2174,47 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext filterProperties.addAll(getFilterProperties(setupTask)); - if (setupTask instanceof SetupTaskContainer) + // If the task has a macro expansion/substitution, process that instead. + Macro macro = expandedMacros.get(setupTask); + if (macro != null) + { + gatherFilters(configurableItems, expandedMacros, macro); + } + else if (setupTask instanceof SetupTaskContainer) { SetupTaskContainer container = (SetupTaskContainer)setupTask; - gatherFilters(configurableItems, container); + gatherFilters(configurableItems, expandedMacros, container); } } } - private Set<String> getFilterProperties(SetupTask setupTask) + private static Set<String> getFilterProperties(SetupTask setupTask) { final Set<String> filterProperties = new LinkedHashSet<String>(); + LDAPFilter ldapFilter = getLDAPFilter(setupTask); + if (ldapFilter != null) + { + 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; + } + }); + } + + return filterProperties; + } + + private static LDAPFilter getLDAPFilter(SetupTask setupTask) + { String filter = setupTask.getFilter(); if (!StringUtil.isEmpty(filter)) { @@ -1754,20 +2225,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext 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; - } - }); + return ldapFilter; } } catch (Exception ex) @@ -1776,7 +2234,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext } } - return filterProperties; + return null; } public EList<SetupTask> initNeededSetupTasks(IProgressMonitor monitor) throws Exception @@ -1841,11 +2299,16 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext return neededSetupTasks; } - public Map<EObject, EObject> getCopyMap() + public Map<EObject, Set<EObject>> getCopyMap() { return copyMap; } + public Map<EObject, Set<EObject>> getMacroCopyMap() + { + return macroCopyMap; + } + public IProgressMonitor getProgressMonitor(boolean working) { if (!working || progressMonitor == null) @@ -2403,12 +2866,12 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext return result; } - public boolean isFilterUsed(String name, EObject eObject) + public static boolean isFilterUsed(String name, EObject eObject) { return eObject instanceof SetupTask && getFilterProperties((SetupTask)eObject).contains(name); } - public boolean isVariableUsed(String name, EObject eObject, boolean recursive) + public static boolean isVariableUsed(String name, EObject eObject, boolean recursive) { for (EAttribute attribute : eObject.eClass().getEAllAttributes()) { @@ -2470,15 +2933,34 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext EList<SetupTask> predecessors = setupTask.getPredecessors(); for (EObject eContainer = setupTask.eContainer(); eContainer instanceof SetupTask; eContainer = eContainer.eContainer()) { - predecessors.addAll(((SetupTask)eContainer).getPredecessors()); + predecessors.addAll(collectChildren(new ArrayList<SetupTask>(), ((SetupTask)eContainer).getPredecessors())); } EList<SetupTask> successors = setupTask.getSuccessors(); for (EObject eContainer = setupTask.eContainer(); eContainer instanceof SetupTask; eContainer = eContainer.eContainer()) { - successors.addAll(((SetupTask)eContainer).getSuccessors()); + successors.addAll(collectChildren(new ArrayList<SetupTask>(), ((SetupTask)eContainer).getSuccessors())); + } + } + } + + private List<SetupTask> collectChildren(List<SetupTask> result, List<SetupTask> setupTasks) + { + for (SetupTask setupTask : setupTasks) + { + if (setupTask instanceof CompoundTask) + { + // Expand a compound task to all its leaf setup tasks. + // This ensures predecessor/successor reference to a compound task is expanded to references all the contained leaf tasks. + CompoundTask compoundTask = (CompoundTask)setupTask; + collectChildren(result, compoundTask.getSetupTasks()); + } + else + { + result.add(setupTask); } } + return result; } private void flattenPredecessorsAndSuccessors(EList<SetupTask> setupTasks) @@ -2649,7 +3131,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext { // Look for an attribute with the name of the detail's key. EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(detail.getKey()); - if (eStructuralFeature instanceof EAttribute) + if (eStructuralFeature instanceof EAttribute && eStructuralFeature.getEAnnotation(EAnnotationConstants.ANNOTATION_NO_EXPAND) == null) { try { @@ -3174,6 +3656,13 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext Profile profile = getProfile(); File installFolder = profile.getInstallFolder(); + if (installFolder == null) + { + log("No install folder found for profile", false, Severity.WARNING); + monitor.worked(3); + return; + } + File bundlePool = profile.getBundlePool().getLocation(); if (!installFolder.equals(bundlePool)) { @@ -3606,6 +4095,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext result.add(t); } } + return result; } @@ -3619,10 +4109,60 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext return super.createCopy(eObject); } + + @Override + protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) + { + // Do not copy any references of a macro task (it will be replaced later) and do not copy a macro's logical container. + if (!(eObject instanceof MacroTask) && eReference != SetupPackage.Literals.MACRO__LOGICAL_CONTAINER) + { + super.copyReference(eReference, eObject, copyEObject); + } + } }; copier.copyAll(roots); + // All the expanded macros will be in the scopes to copy. + // Now we need to replace the macro task with the copied macro's contained compound task. + for (Iterator<Scope> it = scopesToCopy.iterator(); it.hasNext();) + { + Scope scope = it.next(); + if (scope instanceof Macro) + { + // We recorded the logical container of the macro while expanding it. + Macro originalMacro = (Macro)scope; + MacroTask originalLogicalContainer = originalMacro.getLogicalContainer(); + + // There should be a corresponding copy of that macro task. + MacroTask copiedMacroTask = (MacroTask)copier.get(originalLogicalContainer); + if (copiedMacroTask != null) + { + // It should have a container. + EObject eContainer = copiedMacroTask.eContainer(); + if (eContainer instanceof SetupTaskContainer) + { + // This is the list containing the copied macro task. + EList<SetupTask> targetSetupTasks = ((SetupTaskContainer)eContainer).getSetupTasks(); + + // The macro itself will definitely have been copied as a root object. + Macro copiedMacro = (Macro)copier.get(originalMacro); + + // It will have a single compound task. + SetupTask compoundTask = copiedMacro.getSetupTasks().get(0); + + // Replace the macro task with this compound task in its containing list. + int index = targetSetupTasks.indexOf(copiedMacroTask); + targetSetupTasks.set(index, compoundTask); + + // Record the macro task as if it were copied as this compound task. + // This ensures that references to the macro task will be mapped as references to the compound task representing the macro expansion. + copier.put(originalLogicalContainer, compoundTask); + } + } + } + } + // 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>(); @@ -3699,7 +4239,12 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext copier.put(overriddenTask, copy == null ? overridingTask : copy); } - copyMap = copier; + for (Map.Entry<EObject, EObject> entry : copier.entrySet()) + { + Set<EObject> copies = new LinkedHashSet<EObject>(); + copies.add(entry.getValue()); + copyMap.put(entry.getKey(), copies); + } copier.copyReferences(); @@ -3867,6 +4412,11 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext SetupCorePlugin.checkCancelation(CREATION_MONITOR.get()); } + public static String createQualifiedName(String id, String name) + { + return "*" + id + "." + name; + } + /** * Used in IDE. */ @@ -3881,12 +4431,23 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext public static SetupTaskPerformer create(URIConverter uriConverter, final SetupPrompter prompter, Trigger trigger, SetupContext setupContext, boolean fullPrompt) throws Exception { + return create(uriConverter, prompter, trigger, setupContext, fullPrompt, false); + } + + /** + * Used with full composition true only for the outline preview in the setup editor. + */ + public static SetupTaskPerformer create(URIConverter uriConverter, final SetupPrompter prompter, Trigger trigger, SetupContext setupContext, + boolean fullPrompt, boolean fullComposition) throws Exception + { List<SetupTaskPerformer> performers = new ArrayList<SetupTaskPerformer>(); boolean needsPrompt = false; - Map<Object, Set<Object>> composedMap = new HashMap<Object, Set<Object>>(); + Map<Object, Set<Object>> composedMap = new LinkedHashMap<Object, Set<Object>>(); List<VariableTask> allAppliedRuleVariables = new ArrayList<VariableTask>(); + Set<String> allUndeclaredVariables = new LinkedHashSet<String>(); List<VariableTask> allUnresolvedVariables = new ArrayList<VariableTask>(); + List<VariableTask> allResolvedVariables = new ArrayList<VariableTask>(); List<VariableTask> allPasswordVariables = new ArrayList<VariableTask>(); Map<VariableTask, EAttribute> allRuleAttributes = new LinkedHashMap<VariableTask, EAttribute>(); @@ -3920,6 +4481,11 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext demandCreatedUnresolvedVariables.add(variable); } + if (fullComposition) + { + allUndeclaredVariables.addAll(undeclaredVariables); + } + undeclaredVariables.clear(); } @@ -4012,6 +4578,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext allAppliedRuleVariables.addAll(performer.getAppliedRuleVariables()); allUnresolvedVariables.addAll(performer.getUnresolvedVariables()); + allResolvedVariables.addAll(performer.getResolvedVariables()); allPasswordVariables.addAll(performer.getPasswordVariables()); allRuleAttributes.putAll(performer.getRuleAttributes()); performers.add(performer); @@ -4044,7 +4611,7 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext // 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>(); + Set<Bundle> bundles = new LinkedHashSet<Bundle>(); for (SetupTaskPerformer performer : performers) { setupTasks.addAll(performer.getTriggeredSetupTasks()); @@ -4059,25 +4626,69 @@ public class SetupTaskPerformer extends AbstractSetupTaskContext composedPerformer.getRuleAttributes().putAll(allRuleAttributes); composedPerformer.redirectTriggeredSetupTasks(); - File workspaceLocation = composedPerformer.getWorkspaceLocation(); - if (workspaceLocation != null) + if (fullComposition) { - File workspaceSetupLocation = new File(workspaceLocation, ".metadata/.plugins/org.eclipse.oomph.setup/workspace.setup"); - URI workspaceURI = URI.createFileURI(workspaceSetupLocation.toString()); - for (SetupTaskPerformer performer : performers) + composedPerformer.getUndeclaredVariables().addAll(allUndeclaredVariables); + composedPerformer.getResolvedVariables().addAll(allResolvedVariables); + Map<EObject, Set<EObject>> copyMap = composedPerformer.getCopyMap(); + Map<EObject, Set<EObject>> macroCopyMap = composedPerformer.getMacroCopyMap(); + for (SetupTaskPerformer setupTaskPerformer : performers) { - performer.getWorkspace().eResource().setURI(workspaceURI); + Map<EObject, Set<EObject>> performerCopyMap = setupTaskPerformer.getCopyMap(); + for (Entry<EObject, Set<EObject>> entry : performerCopyMap.entrySet()) + { + EObject key = entry.getKey(); + Set<EObject> copies = entry.getValue(); + Set<EObject> combinedCopies = copyMap.get(key); + if (combinedCopies == null) + { + copyMap.put(key, copies); + } + else + { + combinedCopies.addAll(copies); + } + } + + Map<EObject, Set<EObject>> performerMacroCopyMap = setupTaskPerformer.getMacroCopyMap(); + for (Entry<EObject, Set<EObject>> entry : performerMacroCopyMap.entrySet()) + { + EObject key = entry.getKey(); + Set<EObject> copies = entry.getValue(); + Set<EObject> combinedCopies = macroCopyMap.get(key); + if (combinedCopies == null) + { + macroCopyMap.put(key, copies); + } + else + { + combinedCopies.addAll(copies); + } + } } } - - File configurationLocation = composedPerformer.getProductConfigurationLocation(); - if (configurationLocation != null) + else { - File installationLocation = new File(configurationLocation, "org.eclipse.oomph.setup/installation.setup"); - URI installationURI = URI.createFileURI(installationLocation.toString()); - for (SetupTaskPerformer performer : performers) + File workspaceLocation = composedPerformer.getWorkspaceLocation(); + if (workspaceLocation != null) { - performer.getInstallation().eResource().setURI(installationURI); + 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); + } } } diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/DeletedOverlay.gif b/plugins/org.eclipse.oomph.setup.edit/icons/DeletedOverlay.gif Binary files differnew file mode 100644 index 000000000..0786c145e --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/DeletedOverlay.gif diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/LinkOverlay.gif b/plugins/org.eclipse.oomph.setup.edit/icons/LinkOverlay.gif Binary files differnew file mode 100644 index 000000000..4f1440ebe --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/LinkOverlay.gif diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/MacroOverlay.png b/plugins/org.eclipse.oomph.setup.edit/icons/MacroOverlay.png Binary files differnew file mode 100644 index 000000000..a19fb084f --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/MacroOverlay.png diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/PreviewOverlay.png b/plugins/org.eclipse.oomph.setup.edit/icons/PreviewOverlay.png Binary files differnew file mode 100644 index 000000000..23d70cb7c --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/PreviewOverlay.png diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Argument.gif b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Argument.gif Binary files differnew file mode 100644 index 000000000..aeea60e19 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Argument.gif diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Macro.gif b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Macro.gif Binary files differnew file mode 100644 index 000000000..578129ff1 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Macro.gif diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/MacroTask.gif b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/MacroTask.gif Binary files differnew file mode 100644 index 000000000..1753b9627 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/MacroTask.gif diff --git a/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Parameter.gif b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Parameter.gif Binary files differnew file mode 100644 index 000000000..d12cafac1 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/icons/full/obj16/Parameter.gif diff --git a/plugins/org.eclipse.oomph.setup.edit/plugin.properties b/plugins/org.eclipse.oomph.setup.edit/plugin.properties index e1a0fa830..619982503 100644 --- a/plugins/org.eclipse.oomph.setup.edit/plugin.properties +++ b/plugins/org.eclipse.oomph.setup.edit/plugin.properties @@ -185,3 +185,17 @@ _UI_Workspace_streams_feature = Streams _UI_Workspace_type = Workspace _UI_ResourceCopyTask_force_feature = Force _UI_ResourceCreationTask_force_feature = Force +_UI_Macro_type = Macro +_UI_MacroTask_type = Macro Expansion +_UI_Macro_logicalContainer_feature = Logical Container +_UI_ScopeType_Macro_literal = Macro +_UI_MacroTask_macro_feature = Macro +_UI_Macro_parameters_feature = Parameters +_UI_MacroTask_arguments_feature = Arguments +_UI_Parameter_type = Parameter +_UI_Argument_type = Argument +_UI_Parameter_name_feature = Name +_UI_Parameter_description_feature = Description +_UI_Parameter_defaultValue_feature = Default Value +_UI_Argument_parameter_feature = Parameter +_UI_Argument_value_feature = Value diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/ArgumentItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/ArgumentItemProvider.java new file mode 100644 index 000000000..56ffd5247 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/ArgumentItemProvider.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.provider; + +import org.eclipse.oomph.base.provider.ModelElementItemProvider; +import org.eclipse.oomph.setup.Argument; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.oomph.util.StringUtil; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.ResourceLocator; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; +import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; +import org.eclipse.emf.edit.provider.ViewerNotification; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * This is the item provider adapter for a {@link org.eclipse.oomph.setup.Argument} object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ +public class ArgumentItemProvider extends ModelElementItemProvider +{ + /** + * This constructs an instance from a factory and a notifier. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public ArgumentItemProvider(AdapterFactory adapterFactory) + { + super(adapterFactory); + } + + /** + * This returns the property descriptors for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) + { + if (itemPropertyDescriptors == null) + { + super.getPropertyDescriptors(object); + + addParameterPropertyDescriptor(object); + addValuePropertyDescriptor(object); + } + return itemPropertyDescriptors; + } + + /** + * This adds a property descriptor for the Parameter feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void addParameterPropertyDescriptor(Object object) + { + itemPropertyDescriptors.add(createItemPropertyDescriptor(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(), getResourceLocator(), + getString("_UI_Argument_parameter_feature"), getString("_UI_PropertyDescriptor_description", "_UI_Argument_parameter_feature", "_UI_Argument_type"), + SetupPackage.Literals.ARGUMENT__PARAMETER, true, false, true, null, null, null)); + } + + @Override + protected ItemPropertyDescriptor createItemPropertyDescriptor(AdapterFactory adapterFactory, ResourceLocator resourceLocator, String displayName, + String description, EStructuralFeature feature, boolean isSettable, boolean multiLine, boolean sortChoices, Object staticImage, String category, + String[] filterFlags) + { + if (feature == SetupPackage.Literals.ARGUMENT__PARAMETER) + { + return new HierarchicalPropertyDescriptor(adapterFactory, resourceLocator, displayName, description, feature, isSettable, multiLine, sortChoices, + staticImage, category, filterFlags) + { + @Override + protected IItemLabelProvider createLabelProvider() + { + return new HierarchicalItemLabelProvider(itemDelegator) + { + @Override + public String getText(Object object) + { + String text = super.getText(object); + Parameter parameter = (Parameter)object; + if (parameter != null) + { + String description = parameter.getDescription(); + if (!StringUtil.isEmpty(description)) + { + text += " - " + description; + } + } + + return text; + } + + @Override + protected Object getParent(Object object) + { + return null; + } + }; + } + + @Override + public Collection<?> getChoiceOfValues(Object object) + { + return filterChoices(super.getChoiceOfValues(object), feature, object); + } + }; + } + + return super.createItemPropertyDescriptor(adapterFactory, resourceLocator, displayName, description, feature, isSettable, multiLine, sortChoices, + staticImage, category, filterFlags); + } + + @Override + protected Collection<?> filterChoices(Collection<?> choices, EStructuralFeature feature, Object object) + { + if (feature == SetupPackage.Literals.ARGUMENT__PARAMETER) + { + Argument argument = (Argument)object; + EObject eContainer = argument.eContainer(); + if (eContainer instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)eContainer; + Macro macro = macroTask.getMacro(); + if (macro != null) + { + List<Object> result = new ArrayList<Object>(macro.getParameters()); + EList<Argument> arguments = macroTask.getArguments(); + for (Argument otherArgument : arguments) + { + if (otherArgument != argument) + { + result.remove(otherArgument.getParameter()); + } + } + + return result; + } + } + } + + return super.filterChoices(choices, feature, object); + } + + /** + * This adds a property descriptor for the Value feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void addValuePropertyDescriptor(Object object) + { + itemPropertyDescriptors.add(createItemPropertyDescriptor(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(), getResourceLocator(), + getString("_UI_Argument_value_feature"), getString("_UI_PropertyDescriptor_description", "_UI_Argument_value_feature", "_UI_Argument_type"), + SetupPackage.Literals.ARGUMENT__VALUE, true, false, false, ItemPropertyDescriptor.GENERIC_VALUE_IMAGE, null, null)); + } + + /** + * This returns Argument.gif. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object getImage(Object object) + { + return overlayImage(object, getResourceLocator().getImage("full/obj16/Argument")); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected boolean shouldComposeCreationImage() + { + return true; + } + + /** + * This returns the label text for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + @Override + public String getText(Object object) + { + Argument argument = (Argument)object; + Parameter parameter = argument.getParameter(); + String label = parameter == null ? null : parameter.getName(); + if (StringUtil.isEmpty(label)) + { + label = "<no-parameter>"; + } + + String value = argument.getValue(); + if (value != null) + { + if (value.length() == 0) + { + label += " = \"\""; + } + else + { + label += " = " + value; + } + } + else + { + String defaultValue = parameter == null ? null : parameter.getDefaultValue(); + if (defaultValue != null) + { + if (defaultValue.length() == 0) + { + label += " (default: \"\")"; + } + else + { + label += " (default: " + defaultValue + ")"; + } + } + } + + return label; + } + + /** + * This handles model notifications by calling {@link #updateChildren} to update any cached + * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void notifyChanged(Notification notification) + { + updateChildren(notification); + + switch (notification.getFeatureID(Argument.class)) + { + case SetupPackage.ARGUMENT__PARAMETER: + case SetupPackage.ARGUMENT__VALUE: + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true)); + return; + } + super.notifyChanged(notification); + } + + /** + * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children + * that can be created under this object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) + { + super.collectNewChildDescriptors(newChildDescriptors, object); + } + +} diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java index c3c90079d..7ed814f00 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java @@ -14,9 +14,12 @@ import org.eclipse.oomph.setup.CompoundTask; import org.eclipse.oomph.setup.SetupFactory; import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.command.CommandParameter; +import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; @@ -209,6 +212,8 @@ public class CompoundTaskItemProvider extends SetupTaskItemProvider newChildDescriptors.add(createChildParameter(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS, SetupFactory.eINSTANCE.createResourceCreationTask())); newChildDescriptors.add(createChildParameter(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS, SetupFactory.eINSTANCE.createTextModifyTask())); + + newChildDescriptors.add(createChildParameter(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS, SetupFactory.eINSTANCE.createMacroTask())); } @Override @@ -218,4 +223,9 @@ public class CompoundTaskItemProvider extends SetupTaskItemProvider SetupTaskContainerItemProvider.removeUnwantedTasks(newChildDescriptors, object); } + @Override + protected Command factorAddCommand(EditingDomain domain, CommandParameter commandParameter) + { + return super.factorAddCommand(domain, SetupTaskContainerItemProvider.transformCommandParameter(domain, commandParameter)); + } } diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/InstallationItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/InstallationItemProvider.java index 408296640..c9b4f00cc 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/InstallationItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/InstallationItemProvider.java @@ -10,6 +10,7 @@ */ package org.eclipse.oomph.setup.provider; +import org.eclipse.oomph.edit.NoChildrenDelegatingWrapperItemProvider; import org.eclipse.oomph.setup.Installation; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductVersion; @@ -20,6 +21,8 @@ import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.command.SetCommand; @@ -85,6 +88,75 @@ public class InstallationItemProvider extends ScopeItemProvider } /** + * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an + * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or + * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private Collection<? extends EStructuralFeature> getChildrenFeaturesGen(Object object) + { + if (childrenFeatures == null) + { + super.getChildrenFeatures(object); + childrenFeatures.add(SetupPackage.Literals.INSTALLATION__PRODUCT_VERSION); + } + return childrenFeatures; + } + + @Override + public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) + { + if (childrenFeatures == null) + { + getChildrenFeaturesGen(object); + childrenFeatures.remove(SetupPackage.Literals.INSTALLATION__PRODUCT_VERSION); + childrenFeatures.add(0, SetupPackage.Literals.INSTALLATION__PRODUCT_VERSION); + } + + return childrenFeatures; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EStructuralFeature getChildFeature(Object object, Object child) + { + // Check the type of the specified child object and return the proper feature to use for + // adding (see {@link AddCommand}) it as a child. + + return super.getChildFeature(object, child); + } + + @Override + protected boolean isWrappingNeeded(Object object) + { + return true; + } + + @Override + protected Object createWrapper(EObject object, EStructuralFeature feature, Object value, int index) + { + if (feature == SetupPackage.Literals.INSTALLATION__PRODUCT_VERSION) + { + return new NoChildrenDelegatingWrapperItemProvider(value, object, feature, index, adapterFactory) + { + @Override + public String getText(Object object) + { + return ((ProductVersion)value).getQualifiedLabel(); + } + }; + } + + return null; + } + + /** * This returns Installation.gif. * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -155,7 +227,7 @@ public class InstallationItemProvider extends ScopeItemProvider switch (notification.getFeatureID(Installation.class)) { case SetupPackage.INSTALLATION__PRODUCT_VERSION: - fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true)); + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false)); return; } super.notifyChanged(notification); diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java new file mode 100644 index 000000000..28ad57aba --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.provider; + +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.SetupFactory; +import org.eclipse.oomph.setup.SetupPackage; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; +import org.eclipse.emf.edit.provider.ViewerNotification; + +import java.util.Collection; +import java.util.List; + +/** + * This is the item provider adapter for a {@link org.eclipse.oomph.setup.Macro} object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ +public class MacroItemProvider extends ScopeItemProvider +{ + /** + * This constructs an instance from a factory and a notifier. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public MacroItemProvider(AdapterFactory adapterFactory) + { + super(adapterFactory); + } + + /** + * This returns the property descriptors for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) + { + if (itemPropertyDescriptors == null) + { + super.getPropertyDescriptors(object); + + } + return itemPropertyDescriptors; + } + + /** + * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an + * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or + * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private Collection<? extends EStructuralFeature> getChildrenFeaturesGen(Object object) + { + if (childrenFeatures == null) + { + super.getChildrenFeatures(object); + childrenFeatures.add(SetupPackage.Literals.MACRO__PARAMETERS); + } + return childrenFeatures; + } + + @Override + public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) + { + if (childrenFeatures == null) + { + getChildrenFeaturesGen(object); + childrenFeatures.remove(SetupPackage.Literals.MACRO__PARAMETERS); + childrenFeatures.add(0, SetupPackage.Literals.MACRO__PARAMETERS); + } + + return childrenFeatures; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EStructuralFeature getChildFeature(Object object, Object child) + { + // Check the type of the specified child object and return the proper feature to use for + // adding (see {@link AddCommand}) it as a child. + + return super.getChildFeature(object, child); + } + + /** + * This returns Macro.gif. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object getImage(Object object) + { + return overlayImage(object, getResourceLocator().getImage("full/obj16/Macro")); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected boolean shouldComposeCreationImage() + { + return true; + } + + /** + * This returns the label text for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + @Override + public String getText(Object object) + { + String label = ((Macro)object).getLabel(); + return label == null || label.length() == 0 ? getString("_UI_Fragment_type") : label; + } + + /** + * This handles model notifications by calling {@link #updateChildren} to update any cached + * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void notifyChanged(Notification notification) + { + updateChildren(notification); + + switch (notification.getFeatureID(Macro.class)) + { + case SetupPackage.MACRO__PARAMETERS: + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false)); + return; + } + super.notifyChanged(notification); + } + + /** + * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children + * that can be created under this object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) + { + super.collectNewChildDescriptors(newChildDescriptors, object); + + newChildDescriptors.add(createChildParameter(SetupPackage.Literals.MACRO__PARAMETERS, SetupFactory.eINSTANCE.createParameter())); + } +} diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroTaskItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroTaskItemProvider.java new file mode 100644 index 000000000..b87667c4f --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroTaskItemProvider.java @@ -0,0 +1,563 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.provider; + +import org.eclipse.oomph.setup.Argument; +import org.eclipse.oomph.setup.CompoundTask; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupFactory; +import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.oomph.util.ReflectUtil; +import org.eclipse.oomph.util.StringUtil; + +import org.eclipse.emf.common.CommonPlugin; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; +import org.eclipse.emf.edit.provider.ComposedImage; +import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider; +import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; +import org.eclipse.emf.edit.provider.ITreeItemContentProvider; +import org.eclipse.emf.edit.provider.IWrapperItemProvider; +import org.eclipse.emf.edit.provider.ViewerNotification; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * This is the item provider adapter for a {@link org.eclipse.oomph.setup.MacroTask} object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ +public class MacroTaskItemProvider extends SetupTaskItemProvider +{ + private static final Method EXPAND_MACRO_METHOD; + + static + { + Method expandMacroTaskMethod = null; + try + { + Class<?> setupTaskPerformer = CommonPlugin.loadClass("org.eclipse.oomph.setup.core", "org.eclipse.oomph.setup.internal.core.SetupTaskPerformer"); + expandMacroTaskMethod = setupTaskPerformer.getMethod("expand", MacroTask.class); + } + catch (Exception ex) + { + //$FALL-THROUGH$ + } + + EXPAND_MACRO_METHOD = expandMacroTaskMethod; + } + + /** + * This constructs an instance from a factory and a notifier. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public MacroTaskItemProvider(AdapterFactory adapterFactory) + { + super(adapterFactory); + } + + /** + * This returns the property descriptors for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) + { + if (itemPropertyDescriptors == null) + { + super.getPropertyDescriptors(object); + + addMacroPropertyDescriptor(object); + } + return itemPropertyDescriptors; + } + + /** + * This adds a property descriptor for the Macro feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void addMacroPropertyDescriptor(Object object) + { + itemPropertyDescriptors.add(createItemPropertyDescriptor(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(), getResourceLocator(), + getString("_UI_MacroTask_macro_feature"), getString("_UI_PropertyDescriptor_description", "_UI_MacroTask_macro_feature", "_UI_MacroTask_type"), + SetupPackage.Literals.MACRO_TASK__MACRO, true, false, true, null, null, null)); + } + + /** + * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an + * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or + * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) + { + if (childrenFeatures == null) + { + super.getChildrenFeatures(object); + childrenFeatures.add(SetupPackage.Literals.MACRO_TASK__ARGUMENTS); + childrenFeatures.add(SetupPackage.Literals.MACRO_TASK__MACRO); + } + return childrenFeatures; + } + + @Override + protected boolean isWrappingNeeded(Object object) + { + return true; + } + + @Override + public boolean hasChildren(Object object) + { + return !isDirectlyRecursive(object) && super.hasChildren(object); + } + + protected boolean isDirectlyRecursive(Object object) + { + MacroTask macroTask = (MacroTask)object; + EObject rootContainer = EcoreUtil.getRootContainer(macroTask); + return rootContainer == macroTask.getMacro(); + } + + @Override + public Collection<?> getChildren(Object object) + { + if (isDirectlyRecursive(object)) + { + return Collections.emptyList(); + } + + Collection<?> children = super.getChildren(object); + + CompoundTask expandedMacroTask = expandMacroTask(object); + if (expandedMacroTask != null) + { + List<Object> extendedChildren = new ArrayList<Object>(children); + String name = expandedMacroTask.getName(); + expandedMacroTask.setName(StringUtil.isEmpty(name) ? "Preview" : name + " - Preview"); + + extendedChildren.add(new PreviewDelegatingWrapper(expandedMacroTask, object, adapterFactory)); + children = extendedChildren; + } + + return children; + } + + protected CompoundTask expandMacroTask(Object object) + { + if (EXPAND_MACRO_METHOD != null) + { + CompoundTask expandedMacro = ReflectUtil.invokeMethod(EXPAND_MACRO_METHOD, null, object); + if (expandedMacro != null) + { + EObject eContainer = expandedMacro.eContainer(); + if (eContainer instanceof Macro) + { + Macro macro = (Macro)eContainer; + macro.setLogicalContainer((MacroTask)object); + } + } + + return expandedMacro; + } + + return null; + } + + @Override + protected Object createWrapper(EObject object, EStructuralFeature feature, Object value, int index) + { + if (feature == SetupPackage.Literals.MACRO_TASK__MACRO) + { + return new DelegatingWrapperItemProvider(value, object, feature, index, adapterFactory) + { + @Override + public Object getImage(Object object) + { + Object image = super.getImage(object); + List<Object> images = new ArrayList<Object>(2); + images.add(image); + images.add(SetupEditPlugin.INSTANCE.getImage("MacroOverlay.png")); + images.add(SetupEditPlugin.INSTANCE.getImage("LinkOverlay")); + return new ComposedImage(images); + } + + @Override + public Object getFont(Object object) + { + return ITALIC_FONT; + } + + @Override + public Object getForeground(Object object) + { + Object foreground = super.getForeground(object); + return foreground == null ? RecursionSafeDelegatingWrapper.FOREGROUND_COLOR : foreground; + } + + @Override + protected IWrapperItemProvider createWrapper(Object value, Object owner, AdapterFactory adapterFactory) + { + return new RecursionSafeDelegatingWrapper(value, owner, adapterFactory); + } + }; + } + + return super.createWrapper(object, feature, value, index); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EStructuralFeature getChildFeature(Object object, Object child) + { + // Check the type of the specified child object and return the proper feature to use for + // adding (see {@link AddCommand}) it as a child. + + return super.getChildFeature(object, child); + } + + /** + * This returns MacroTask.gif. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private Object getImageGen(Object object) + { + return overlayImage(object, getResourceLocator().getImage("full/obj16/MacroTask")); + } + + @Override + public Object getImage(Object object) + { + Object image = getImageGen(object); + return getRecursiveOverlayImage(isDirectlyRecursive(object), false, image); + } + + protected static Object getRecursiveOverlayImage(boolean isRecursive, boolean isMacro, Object image) + { + List<Object> images = new ArrayList<Object>(2); + images.add(image); + if (isRecursive) + { + images.add(SetupEditPlugin.INSTANCE.getImage("DeletedOverlay")); + } + + if (isMacro) + { + images.add(SetupEditPlugin.INSTANCE.getImage("MacroOverlay.png")); + } + + return images.size() == 1 ? image : new ComposedImage(images); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected boolean shouldComposeCreationImage() + { + return true; + } + + /** + * This returns the label text for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + @Override + public String getText(Object object) + { + MacroTask macroTask = (MacroTask)object; + String id = macroTask.getID(); + Macro macro = macroTask.getMacro(); + String label = macro != null ? macro.getLabel() : null; + return (StringUtil.isEmpty(label) ? getString("_UI_MacroTask_type") : label) + " : " + (StringUtil.isEmpty(id) ? "?" : id); + } + + /** + * This handles model notifications by calling {@link #updateChildren} to update any cached + * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private void notifyChangedGen(Notification notification) + { + updateChildren(notification); + + switch (notification.getFeatureID(MacroTask.class)) + { + case SetupPackage.MACRO_TASK__ARGUMENTS: + case SetupPackage.MACRO_TASK__MACRO: + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false)); + return; + } + super.notifyChanged(notification); + } + + @Override + public void notifyChanged(Notification notification) + { + notifyChangedGen(notification); + switch (notification.getFeatureID(MacroTask.class)) + { + case SetupPackage.MACRO_TASK__ID: + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, true)); + return; + } + } + + /** + * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children + * that can be created under this object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unused") + private void collectNewChildDescriptorsGen(Collection<Object> newChildDescriptors, Object object) + { + super.collectNewChildDescriptors(newChildDescriptors, object); + + newChildDescriptors.add(createChildParameter(SetupPackage.Literals.MACRO_TASK__ARGUMENTS, SetupFactory.eINSTANCE.createArgument())); + } + + @Override + protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) + { + super.collectNewChildDescriptors(newChildDescriptors, object); + + MacroTask macroTask = (MacroTask)object; + Macro macro = macroTask.getMacro(); + if (macro != null) + { + Set<Parameter> boundParameters = new HashSet<Parameter>(); + for (Argument argument : macroTask.getArguments()) + { + boundParameters.add(argument.getParameter()); + } + + for (Parameter parameter : macro.getParameters()) + { + if (!boundParameters.contains(parameter)) + { + Argument argument = SetupFactory.eINSTANCE.createArgument(); + argument.setParameter(parameter); + String defaultValue = parameter.getDefaultValue(); + if (defaultValue == null) + { + argument.setValue("" + parameter.getName() + "_value"); + } + newChildDescriptors.add(createChildParameter(SetupPackage.Literals.MACRO_TASK__ARGUMENTS, argument)); + } + } + } + } + + @Override + public String getCreateChildText(Object owner, Object feature, Object child, Collection<?> selection) + { + String result = super.getCreateChildText(owner, feature, child, selection); + if (feature == SetupPackage.Literals.MACRO_TASK__ARGUMENTS) + { + Argument argument = (Argument)child; + Parameter parameter = argument.getParameter(); + if (parameter != null) + { + String name = parameter.getName(); + if (!StringUtil.isEmpty(name)) + { + return result += " for " + name; + } + } + } + + return result; + } + + private static class RecursionSafeDelegatingWrapper extends DelegatingWrapperItemProvider + { + private static final URI FOREGROUND_COLOR = URI.createURI("color://rgb/138/110/85"); + + @SuppressWarnings("deprecation") + public RecursionSafeDelegatingWrapper(Object value, Object owner, AdapterFactory adapterFactory) + { + super(value, owner, adapterFactory); + } + + @Override + protected IWrapperItemProvider createWrapper(Object value, Object owner, AdapterFactory adapterFactory) + { + return new RecursionSafeDelegatingWrapper(value, owner, adapterFactory); + } + + @Override + public Object getFont(Object object) + { + return ITALIC_FONT; + } + + @Override + public Object getForeground(Object object) + { + return FOREGROUND_COLOR; + } + + @Override + public Object getImage(Object object) + { + Object image = super.getImage(object); + return getRecursiveOverlayImage(isRecursive(), true, image); + } + + public boolean isRecursive() + { + Object unwrappedValue = AdapterFactoryEditingDomain.unwrap(value); + boolean isRecursive = isRecursive(owner, unwrappedValue); + if (!isRecursive && unwrappedValue instanceof EObject) + { + EObject eContainer = ((EObject)unwrappedValue).eContainer(); + if (eContainer instanceof Macro) + { + Macro macro = (Macro)eContainer; + isRecursive = isRecursive(owner, macro.getLogicalContainer()); + } + } + + return isRecursive; + } + + protected boolean isRecursive(Object parent, Object guard) + { + Object unwrap = AdapterFactoryEditingDomain.unwrap(parent); + if (unwrap == guard) + { + return true; + } + + if (parent instanceof ITreeItemContentProvider) + { + Object grandParent = ((ITreeItemContentProvider)parent).getParent(parent); + return isRecursive(grandParent, guard); + } + + return false; + } + + @Override + public boolean hasChildren(Object object) + { + return !isRecursive() && super.hasChildren(object); + } + + @Override + protected void updateChildren() + { + if (!isRecursive()) + { + super.updateChildren(); + } + else + { + delegateChildren = Collections.emptyList(); + } + } + + @Override + public Collection<?> getChildren(Object object) + { + Collection<?> children = super.getChildren(object); + for (Iterator<?> it = children.iterator(); it.hasNext();) + { + Object child = it.next(); + Object value = ((RecursionSafeDelegatingWrapper)child).getValue(); + if (value instanceof PreviewDelegatingWrapper) + { + it.remove(); + break; + } + } + return children; + } + } + + private static class PreviewDelegatingWrapper extends DelegatingWrapperItemProvider + { + private static final URI FOREGROUND_COLOR = URI.createURI("color://rgb/85/113/138"); + + @SuppressWarnings("deprecation") + public PreviewDelegatingWrapper(Object value, Object owner, AdapterFactory adapterFactory) + { + super(value, owner, adapterFactory); + } + + @Override + public Object getFont(Object object) + { + return ITALIC_FONT; + } + + @Override + public Object getForeground(Object object) + { + return FOREGROUND_COLOR; + } + + @Override + public Object getImage(Object object) + { + Object image = super.getImage(object); + List<Object> images = new ArrayList<Object>(2); + images.add(image); + images.add(SetupEditPlugin.INSTANCE.getImage("PreviewOverlay.png")); + return new ComposedImage(images); + } + + @Override + protected IWrapperItemProvider createWrapper(Object value, Object owner, AdapterFactory adapterFactory) + { + return new PreviewDelegatingWrapper(value, owner, adapterFactory); + } + } +} diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/ParameterItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/ParameterItemProvider.java new file mode 100644 index 000000000..6dcb62be7 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/ParameterItemProvider.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.provider; + +import org.eclipse.oomph.base.provider.ModelElementItemProvider; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupPackage; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; +import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; +import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; +import org.eclipse.emf.edit.provider.ViewerNotification; + +import java.util.Collection; +import java.util.List; + +/** + * This is the item provider adapter for a {@link org.eclipse.oomph.setup.Parameter} object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ +public class ParameterItemProvider extends ModelElementItemProvider +{ + /** + * This constructs an instance from a factory and a notifier. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public ParameterItemProvider(AdapterFactory adapterFactory) + { + super(adapterFactory); + } + + /** + * This returns the property descriptors for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) + { + if (itemPropertyDescriptors == null) + { + super.getPropertyDescriptors(object); + + addNamePropertyDescriptor(object); + addDescriptionPropertyDescriptor(object); + addDefaultValuePropertyDescriptor(object); + } + return itemPropertyDescriptors; + } + + /** + * This adds a property descriptor for the Name feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void addNamePropertyDescriptor(Object object) + { + itemPropertyDescriptors.add(createItemPropertyDescriptor(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(), getResourceLocator(), + getString("_UI_Parameter_name_feature"), getString("_UI_PropertyDescriptor_description", "_UI_Parameter_name_feature", "_UI_Parameter_type"), + SetupPackage.Literals.PARAMETER__NAME, true, false, false, ItemPropertyDescriptor.GENERIC_VALUE_IMAGE, null, null)); + } + + /** + * This adds a property descriptor for the Description feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void addDescriptionPropertyDescriptor(Object object) + { + itemPropertyDescriptors.add(createItemPropertyDescriptor(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(), getResourceLocator(), + getString("_UI_Parameter_description_feature"), + getString("_UI_PropertyDescriptor_description", "_UI_Parameter_description_feature", "_UI_Parameter_type"), + SetupPackage.Literals.PARAMETER__DESCRIPTION, true, false, false, ItemPropertyDescriptor.GENERIC_VALUE_IMAGE, null, null)); + } + + /** + * This adds a property descriptor for the Default Value feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected void addDefaultValuePropertyDescriptor(Object object) + { + itemPropertyDescriptors.add(createItemPropertyDescriptor(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(), getResourceLocator(), + getString("_UI_Parameter_defaultValue_feature"), + getString("_UI_PropertyDescriptor_description", "_UI_Parameter_defaultValue_feature", "_UI_Parameter_type"), + SetupPackage.Literals.PARAMETER__DEFAULT_VALUE, true, false, false, ItemPropertyDescriptor.GENERIC_VALUE_IMAGE, null, null)); + } + + /** + * This returns Parameter.gif. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object getImage(Object object) + { + return overlayImage(object, getResourceLocator().getImage("full/obj16/Parameter")); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected boolean shouldComposeCreationImage() + { + return true; + } + + /** + * This returns the label text for the adapted class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + @Override + public String getText(Object object) + { + Parameter parameter = (Parameter)object; + String label = parameter.getName(); + String defaultValue = parameter.getDefaultValue(); + String defaultValueLabel = defaultValue == null ? "" : " (default: " + defaultValue + ")"; + return (label == null || label.length() == 0 ? getString("_UI_Parameter_type") : label) + defaultValueLabel; + } + + /** + * This handles model notifications by calling {@link #updateChildren} to update any cached + * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void notifyChanged(Notification notification) + { + updateChildren(notification); + + switch (notification.getFeatureID(Parameter.class)) + { + case SetupPackage.PARAMETER__NAME: + case SetupPackage.PARAMETER__DESCRIPTION: + case SetupPackage.PARAMETER__DEFAULT_VALUE: + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true)); + return; + } + super.notifyChanged(notification); + } + + /** + * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children + * that can be created under this object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected void collectNewChildDescriptors(Collection<Object> newChildDescriptors, Object object) + { + super.collectNewChildDescriptors(newChildDescriptors, object); + } + +} diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupItemProviderAdapterFactory.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupItemProviderAdapterFactory.java index 358df821f..139f98295 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupItemProviderAdapterFactory.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupItemProviderAdapterFactory.java @@ -652,6 +652,106 @@ public class SetupItemProviderAdapterFactory extends SetupAdapterFactory } /** + * This keeps track of the one adapter used for all {@link org.eclipse.oomph.setup.Macro} instances. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected MacroItemProvider macroItemProvider; + + /** + * This creates an adapter for a {@link org.eclipse.oomph.setup.Macro}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Adapter createMacroAdapter() + { + if (macroItemProvider == null) + { + macroItemProvider = new MacroItemProvider(this); + } + + return macroItemProvider; + } + + /** + * This keeps track of the one adapter used for all {@link org.eclipse.oomph.setup.Parameter} instances. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ParameterItemProvider parameterItemProvider; + + /** + * This creates an adapter for a {@link org.eclipse.oomph.setup.Parameter}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Adapter createParameterAdapter() + { + if (parameterItemProvider == null) + { + parameterItemProvider = new ParameterItemProvider(this); + } + + return parameterItemProvider; + } + + /** + * This keeps track of the one adapter used for all {@link org.eclipse.oomph.setup.MacroTask} instances. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected MacroTaskItemProvider macroTaskItemProvider; + + /** + * This creates an adapter for a {@link org.eclipse.oomph.setup.MacroTask}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Adapter createMacroTaskAdapter() + { + if (macroTaskItemProvider == null) + { + macroTaskItemProvider = new MacroTaskItemProvider(this); + } + + return macroTaskItemProvider; + } + + /** + * This keeps track of the one adapter used for all {@link org.eclipse.oomph.setup.Argument} instances. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ArgumentItemProvider argumentItemProvider; + + /** + * This creates an adapter for a {@link org.eclipse.oomph.setup.Argument}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Adapter createArgumentAdapter() + { + if (argumentItemProvider == null) + { + argumentItemProvider = new ArgumentItemProvider(this); + } + + return argumentItemProvider; + } + + /** * This keeps track of the one adapter used for all {@link org.eclipse.oomph.setup.StringSubstitutionTask} instances. * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -1170,6 +1270,22 @@ public class SetupItemProviderAdapterFactory extends SetupAdapterFactory { workspaceToInstallationsMapEntryItemProvider.dispose(); } + if (macroItemProvider != null) + { + macroItemProvider.dispose(); + } + if (parameterItemProvider != null) + { + parameterItemProvider.dispose(); + } + if (macroTaskItemProvider != null) + { + macroTaskItemProvider.dispose(); + } + if (argumentItemProvider != null) + { + argumentItemProvider.dispose(); + } } /** @@ -1292,6 +1408,14 @@ public class SetupItemProviderAdapterFactory extends SetupAdapterFactory newChildDescriptors.add(createChildParameter(BasePackage.Literals.ANNOTATION__CONTENTS, SetupFactory.eINSTANCE.create(SetupPackage.Literals.WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY))); + newChildDescriptors.add(createChildParameter(BasePackage.Literals.ANNOTATION__CONTENTS, SetupFactory.eINSTANCE.createMacro())); + + newChildDescriptors.add(createChildParameter(BasePackage.Literals.ANNOTATION__CONTENTS, SetupFactory.eINSTANCE.createParameter())); + + newChildDescriptors.add(createChildParameter(BasePackage.Literals.ANNOTATION__CONTENTS, SetupFactory.eINSTANCE.createMacroTask())); + + newChildDescriptors.add(createChildParameter(BasePackage.Literals.ANNOTATION__CONTENTS, SetupFactory.eINSTANCE.createArgument())); + return null; } diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java index 78dc823f7..390d9dcbd 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java @@ -11,22 +11,35 @@ package org.eclipse.oomph.setup.provider; import org.eclipse.oomph.base.provider.ModelElementItemProvider; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.InstallationTask; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.ProductCatalog; import org.eclipse.oomph.setup.ProjectCatalog; import org.eclipse.oomph.setup.SetupFactory; import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.oomph.setup.SetupTaskContainer; import org.eclipse.oomph.setup.WorkspaceTask; +import org.eclipse.oomph.util.StringUtil; +import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.command.CommandParameter; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.provider.ViewerNotification; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -150,7 +163,7 @@ public class SetupTaskContainerItemProvider extends ModelElementItemProvider * <!-- end-user-doc --> * @generated */ - protected void collectNewChildDescriptorsGen(Collection<Object> newChildDescriptors, Object object) + private void collectNewChildDescriptorsGen(Collection<Object> newChildDescriptors, Object object) { super.collectNewChildDescriptors(newChildDescriptors, object); @@ -178,6 +191,8 @@ public class SetupTaskContainerItemProvider extends ModelElementItemProvider newChildDescriptors.add(createChildParameter(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS, SetupFactory.eINSTANCE.createResourceCreationTask())); newChildDescriptors.add(createChildParameter(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS, SetupFactory.eINSTANCE.createTextModifyTask())); + + newChildDescriptors.add(createChildParameter(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS, SetupFactory.eINSTANCE.createMacroTask())); } @Override @@ -226,4 +241,113 @@ public class SetupTaskContainerItemProvider extends ModelElementItemProvider return false; } + @Override + protected Command factorAddCommand(EditingDomain domain, CommandParameter commandParameter) + { + return super.factorAddCommand(domain, transformCommandParameter(domain, commandParameter)); + } + + public static CommandParameter transformCommandParameter(EditingDomain domain, CommandParameter commandParameter) + { + Collection<?> collection = commandParameter.getCollection(); + if (collection != null && !collection.isEmpty()) + { + EObject eOwner = commandParameter.getEOwner(); + if (eOwner != null) + { + List<Object> augmentedCollection = new ArrayList<Object>(); + for (Object object : collection) + { + Object unwrappedObject = AdapterFactoryEditingDomain.unwrap(object); + if (unwrappedObject instanceof Macro) + { + Macro macro = (Macro)unwrappedObject; + if (macro.eResource() != null) + { + MacroTask macroTask = SetupFactory.eINSTANCE.createMacroTask(); + macroTask.setMacro(macro); + + String id = getID(macro.getName()); + String uniqueID = id; + Resource resource = eOwner.eResource(); + if (resource != null) + { + int count = 0; + while (resource.getEObject(uniqueID) != null) + { + if (Character.isDigit(id.charAt(id.length() - 1))) + { + uniqueID = id + "_" + ++count; + } + else + { + uniqueID = id + ++count; + } + } + } + + macroTask.setID(uniqueID); + + EList<Parameter> parameters = macro.getParameters(); + if (!parameters.isEmpty()) + { + List<Argument> arguments = macroTask.getArguments(); + for (Parameter parameter : parameters) + { + Argument argument = SetupFactory.eINSTANCE.createArgument(); + argument.setParameter(parameter); + if (parameter.getDefaultValue() == null) + { + String parameterName = parameter.getName(); + argument.setValue(parameterName + "_value"); + } + + arguments.add(argument); + } + } + + augmentedCollection.add(macroTask); + } + else + { + augmentedCollection.add(macro); + } + } + else + { + augmentedCollection.add(object); + } + } + + return new CommandParameter(commandParameter.getOwner(), commandParameter.getFeature(), commandParameter.getValue(), augmentedCollection, + commandParameter.getIndex()); + } + } + + return commandParameter; + } + + private static String getID(String label) + { + if (StringUtil.isEmpty(label)) + { + return "macro"; + } + + String lowerCaseLabel = label.toLowerCase(); + List<String> explode = StringUtil.explode(lowerCaseLabel.replaceAll("[^\\p{IsAlphabetic}\\p{Digit}]", "."), "."); + explode.removeAll(Collections.singleton("")); + String implode = StringUtil.implode(explode, '.'); + if (StringUtil.isEmpty(implode)) + { + return "macro"; + } + + if (!Character.isAlphabetic(implode.charAt(0))) + { + return "_" + implode; + } + + return implode; + } } diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskItemProvider.java index a00992638..f8bcff8d7 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskItemProvider.java @@ -26,9 +26,11 @@ import org.eclipse.oomph.setup.VariableTask; import org.eclipse.oomph.setup.Workspace; import org.eclipse.oomph.util.PropertiesUtil; +import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator; import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; import org.eclipse.emf.edit.provider.IItemLabelProvider; @@ -491,7 +493,8 @@ public class SetupTaskItemProvider extends ModelElementItemProvider * <!-- end-user-doc --> * @generated */ - public void notifyChangedGen(Notification notification) + @SuppressWarnings("unused") + private void notifyChangedGen(Notification notification) { updateChildren(notification); @@ -543,4 +546,39 @@ public class SetupTaskItemProvider extends ModelElementItemProvider { super.collectNewChildDescriptors(newChildDescriptors, object); } + + @Override + protected Command createPrimaryDragAndDropCommand(EditingDomain domain, Object owner, float location, int operations, int operation, Collection<?> collection) + { + return new BaseDragAndDropCommand(domain, owner, location, operations, operation, collection) + { + protected boolean preparingDropLinkInsert; + + @Override + protected boolean prepareDropLinkInsert(Object parent, Collection<?> children, int index) + { + try + { + preparingDropLinkInsert = true; + return super.prepareDropLinkInsert(parent, children, index); + } + finally + { + preparingDropLinkInsert = false; + } + } + + @Override + protected boolean analyzeForNonContainment(Command command) + { + if (preparingDropLinkInsert) + { + return true; + } + + return super.analyzeForNonContainment(command); + } + }; + } + } diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/WorkspaceItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/WorkspaceItemProvider.java index e0c1bfa3f..574777b35 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/WorkspaceItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/WorkspaceItemProvider.java @@ -10,6 +10,7 @@ */ package org.eclipse.oomph.setup.provider; +import org.eclipse.oomph.edit.NoChildrenDelegatingWrapperItemProvider; import org.eclipse.oomph.setup.Project; import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.oomph.setup.Stream; @@ -20,6 +21,8 @@ import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.CommandParameter; @@ -28,6 +31,7 @@ import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.provider.ViewerNotification; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -84,6 +88,75 @@ public class WorkspaceItemProvider extends ScopeItemProvider } /** + * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an + * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or + * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private Collection<? extends EStructuralFeature> getChildrenFeaturesGen(Object object) + { + if (childrenFeatures == null) + { + super.getChildrenFeatures(object); + childrenFeatures.add(SetupPackage.Literals.WORKSPACE__STREAMS); + } + return childrenFeatures; + } + + @Override + public Collection<? extends EStructuralFeature> getChildrenFeatures(Object object) + { + if (childrenFeatures == null) + { + getChildrenFeaturesGen(object); + childrenFeatures.remove(SetupPackage.Literals.WORKSPACE__STREAMS); + childrenFeatures.add(0, SetupPackage.Literals.WORKSPACE__STREAMS); + } + + return childrenFeatures; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EStructuralFeature getChildFeature(Object object, Object child) + { + // Check the type of the specified child object and return the proper feature to use for + // adding (see {@link AddCommand}) it as a child. + + return super.getChildFeature(object, child); + } + + @Override + protected boolean isWrappingNeeded(Object object) + { + return true; + } + + @Override + protected Object createWrapper(EObject object, EStructuralFeature feature, Object value, int index) + { + if (feature == SetupPackage.Literals.WORKSPACE__STREAMS) + { + return new NoChildrenDelegatingWrapperItemProvider(value, object, feature, index, adapterFactory) + { + @Override + public String getText(Object object) + { + return ((Stream)value).getQualifiedLabel(); + } + }; + } + + return null; + } + + /** * This returns Workspace.gif. * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -154,7 +227,7 @@ public class WorkspaceItemProvider extends ScopeItemProvider switch (notification.getFeatureID(Workspace.class)) { case SetupPackage.WORKSPACE__STREAMS: - fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true)); + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false)); return; } super.notifyChanged(notification); @@ -164,24 +237,32 @@ public class WorkspaceItemProvider extends ScopeItemProvider protected Command factorAddCommand(EditingDomain domain, CommandParameter commandParameter) { Collection<?> collection = commandParameter.getCollection(); + Collection<Object> streams = new ArrayList<Object>(); if (collection != null) { for (Object object : collection) { if (object instanceof Stream) { - return AddCommand.create(domain, commandParameter.getOwner(), SetupPackage.Literals.WORKSPACE__STREAMS, object); + streams.add(object); } else if (object instanceof Project) { Project project = (Project)object; - EList<Stream> streams = project.getStreams(); - if (!streams.isEmpty()) + EList<Stream> projectStreams = project.getStreams(); + if (!projectStreams.isEmpty()) { - return AddCommand.create(domain, commandParameter.getOwner(), SetupPackage.Literals.WORKSPACE__STREAMS, streams.get(0)); + streams.add(projectStreams.get(0)); } } } + + Workspace workspace = (Workspace)commandParameter.getOwner(); + streams.removeAll(workspace.getStreams()); + if (!streams.isEmpty()) + { + return AddCommand.create(domain, workspace, SetupPackage.Literals.WORKSPACE__STREAMS, streams); + } } return super.factorAddCommand(domain, commandParameter); diff --git a/plugins/org.eclipse.oomph.setup.editor/icons/locate_value.gif b/plugins/org.eclipse.oomph.setup.editor/icons/locate_value.gif Binary files differnew file mode 100644 index 000000000..7ab849f11 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.editor/icons/locate_value.gif diff --git a/plugins/org.eclipse.oomph.setup.editor/icons/preview.png b/plugins/org.eclipse.oomph.setup.editor/icons/preview.png Binary files differnew file mode 100644 index 000000000..4ccd82e52 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.editor/icons/preview.png diff --git a/plugins/org.eclipse.oomph.setup.editor/plugin.properties b/plugins/org.eclipse.oomph.setup.editor/plugin.properties index 8ec319ccc..07893b7a2 100644 --- a/plugins/org.eclipse.oomph.setup.editor/plugin.properties +++ b/plugins/org.eclipse.oomph.setup.editor/plugin.properties @@ -74,3 +74,7 @@ _UI_SetupModelWizard_description5 = Create a new product catalog setup model _UI_SetupModelWizard_label6 = Setup Project Catalog Model _UI_SetupModelWizard_description6 = Create a new project catalog setup model +_UI_SetupModelWizard_label7 = Setup Macro Model +_UI_SetupModelWizard_description7 = Create a new macro setup model with the camel case name of the macro + + diff --git a/plugins/org.eclipse.oomph.setup.editor/plugin.xml b/plugins/org.eclipse.oomph.setup.editor/plugin.xml index e22105b67..100ab1839 100644 --- a/plugins/org.eclipse.oomph.setup.editor/plugin.xml +++ b/plugins/org.eclipse.oomph.setup.editor/plugin.xml @@ -75,6 +75,15 @@ <description>%_UI_SetupModelWizard_description6</description> <selection class="org.eclipse.core.resources.IResource"/> </wizard> + <wizard + id="org.eclipse.oomph.setup.presentation.SetupModelMacroWizardID" + name="%_UI_SetupModelWizard_label7" + class="org.eclipse.oomph.setup.presentation.SetupModelWizard$NewMacroWizard" + category="org.eclipse.oomph" + icon="icons/full/obj16/SetupModelFile.gif"> + <description>%_UI_SetupModelWizard_description7</description> + <selection class="org.eclipse.core.resources.IResource"/> + </wizard> </extension> diff --git a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java index 3312f8b90..7f6fd2f15 100644 --- a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java +++ b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java @@ -11,16 +11,26 @@ package org.eclipse.oomph.setup.presentation; import org.eclipse.oomph.base.Annotation; +import org.eclipse.oomph.base.BaseFactory; +import org.eclipse.oomph.base.BasePackage; +import org.eclipse.oomph.base.ModelElement; import org.eclipse.oomph.base.provider.BaseEditUtil.IconReflectiveItemProvider; import org.eclipse.oomph.base.util.EAnnotations; import org.eclipse.oomph.internal.ui.OomphEditingDomainActionBarContributor; +import org.eclipse.oomph.setup.AnnotationConstants; import org.eclipse.oomph.setup.CompoundTask; +import org.eclipse.oomph.setup.EAnnotationConstants; import org.eclipse.oomph.setup.InstallationTask; +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.Scope; import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.oomph.setup.SetupTask; +import org.eclipse.oomph.setup.VariableChoice; import org.eclipse.oomph.setup.VariableTask; import org.eclipse.oomph.setup.WorkspaceTask; import org.eclipse.oomph.setup.impl.DynamicSetupTaskImpl; @@ -42,7 +52,9 @@ import org.eclipse.oomph.workingsets.presentation.WorkingSetsActionBarContributo import org.eclipse.emf.common.ui.viewer.IViewerProvider; import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; @@ -128,6 +140,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Queue; @@ -547,7 +560,7 @@ public class SetupActionBarContributor extends OomphEditingDomainActionBarContri protected Collection<IAction> generateCreateChildActions(Collection<?> descriptors, ISelection selection) { Collection<IAction> actions = generateCreateChildActionsGen(descriptors, selection); - return addEnablementActions(descriptors, selection, false, actions); + return addSpecializedAnnotationCreationActions(descriptors, selection, false, addEnablementActions(descriptors, selection, false, actions)); } /** @@ -573,7 +586,155 @@ public class SetupActionBarContributor extends OomphEditingDomainActionBarContri protected Collection<IAction> generateCreateSiblingActions(Collection<?> descriptors, ISelection selection) { Collection<IAction> actions = generateCreateSiblingActionsGen(descriptors, selection); - return addEnablementActions(descriptors, selection, true, actions); + return addSpecializedAnnotationCreationActions(descriptors, selection, true, addEnablementActions(descriptors, selection, true, actions)); + } + + private Collection<IAction> addSpecializedAnnotationCreationActions(Collection<?> descriptors, ISelection selection, boolean sibling, + Collection<IAction> actions) + { + actions = new ArrayList<IAction>(actions); + if (selection instanceof IStructuredSelection && ((IStructuredSelection)selection).size() == 1) + { + EditingDomain domain = ((IEditingDomainProvider)activeEditorPart).getEditingDomain(); + Object object = ((IStructuredSelection)selection).getFirstElement(); + if (sibling) + { + object = domain.getParent(object); + } + + if (object instanceof VariableTask) + { + VariableTask variable = (VariableTask)object; + if (variable.getAnnotation(AnnotationConstants.ANNOTATION_GLOBAL_VARIABLE) == null) + { + String name = variable.getName(); + if (name != null && !name.startsWith("*")) + { + Annotation annotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_GLOBAL_VARIABLE); + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.MODEL_ELEMENT__ANNOTATIONS, annotation); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + AnnotationConstants.ANNOTATION_GLOBAL_VARIABLE); + actions.add(action); + } + } + + if (variable.getAnnotation(AnnotationConstants.ANNOTATION_INHERITED_CHOICES) == null) + { + Annotation annotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_INHERITED_CHOICES); + annotation.getDetails().put(AnnotationConstants.KEY_INHERIT, ""); + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.MODEL_ELEMENT__ANNOTATIONS, annotation); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + AnnotationConstants.ANNOTATION_INHERITED_CHOICES); + actions.add(action); + } + } + else if (object instanceof ModelElement) + { + ModelElement modelElement = (ModelElement)object; + if (modelElement.getAnnotation(AnnotationConstants.ANNOTATION_FEATURE_SUBSTITUTION) == null + && !getFeatureSubstitutionAttributes(modelElement).isEmpty()) + { + Annotation annotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_FEATURE_SUBSTITUTION); + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.MODEL_ELEMENT__ANNOTATIONS, annotation); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + AnnotationConstants.ANNOTATION_FEATURE_SUBSTITUTION); + actions.add(action); + } + + if (modelElement instanceof Annotation) + { + Annotation annotation = (Annotation)modelElement; + if (AnnotationConstants.ANNOTATION_FEATURE_SUBSTITUTION.equals(annotation.getSource())) + { + EMap<String, String> details = annotation.getDetails(); + Set<EAttribute> featureSubstitutionAttributes = getFeatureSubstitutionAttributes(annotation.getModelElement()); + for (EAttribute eAttribute : featureSubstitutionAttributes) + { + String name = eAttribute.getName(); + if (!details.containsKey(name)) + { + Map.Entry<String, String> detail = BaseFactory.eINSTANCE.createStringToStringMapEntry(); + ((EObject)detail).eSet(BasePackage.Literals.STRING_TO_STRING_MAP_ENTRY__KEY, name); + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.ANNOTATION__DETAILS, detail); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + name); + actions.add(action); + } + } + } + } + else if (modelElement instanceof SetupTask) + { + if (modelElement.getAnnotation(AnnotationConstants.ANNOTATION_INDUCED_CHOICES) == null) + { + Annotation annotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_INDUCED_CHOICES); + annotation.getDetails().put(AnnotationConstants.KEY_INHERIT, ""); + annotation.getDetails().put(AnnotationConstants.KEY_LABEL, ""); + annotation.getDetails().put(AnnotationConstants.KEY_TARGET, ""); + annotation.getDetails().put(AnnotationConstants.KEY_DESCRIPTION, ""); + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.MODEL_ELEMENT__ANNOTATIONS, annotation); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + AnnotationConstants.ANNOTATION_INDUCED_CHOICES); + actions.add(action); + } + } + else if (modelElement instanceof VariableChoice) + { + if (modelElement.getAnnotation(AnnotationConstants.ANNOTATION_MATCH_CHOICE) == null) + { + Annotation annotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_MATCH_CHOICE); + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.MODEL_ELEMENT__ANNOTATIONS, annotation); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + AnnotationConstants.ANNOTATION_MATCH_CHOICE); + actions.add(action); + } + } + else if (modelElement instanceof ProjectCatalog || modelElement instanceof Project || modelElement instanceof ProductCatalog + || modelElement instanceof Product || modelElement instanceof ProductVersion) + { + if (modelElement.getAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO) == null) + { + Annotation annotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_BRANDING_INFO); + + EMap<String, String> details = annotation.getDetails(); + if (modelElement instanceof ProductCatalog || modelElement instanceof Product || modelElement instanceof ProductVersion) + { + details.put(AnnotationConstants.KEY_README_PATH, null); + details.put(AnnotationConstants.KEY_FOLDER_NAME, null); + } + + details.put(AnnotationConstants.KEY_IMAGE_URI, null); + details.put(AnnotationConstants.KEY_SITE_URI, null); + + CommandParameter descriptor = new CommandParameter(null, BasePackage.Literals.MODEL_ELEMENT__ANNOTATIONS, annotation); + Action action = sibling ? new CreateSiblingAction(domain, selection, descriptor) : new CreateChildAction(domain, selection, descriptor); + action.setText(action.getText() + " - " + AnnotationConstants.ANNOTATION_BRANDING_INFO); + actions.add(action); + } + } + } + } + + return actions; + } + + private Set<EAttribute> getFeatureSubstitutionAttributes(ModelElement modelElement) + { + Set<EAttribute> result = new LinkedHashSet<EAttribute>(); + + for (EAttribute eAttribute : modelElement.eClass().getEAllAttributes()) + { + if (eAttribute.isChangeable() && eAttribute.getEAnnotation(EAnnotationConstants.ANNOTATION_NO_EXPAND) == null) + { + String instanceClassName = eAttribute.getEAttributeType().getInstanceClassName(); + if (!"java.lang.String".equals(instanceClassName) && !"org.eclipse.emf.common.util.URI".equals(instanceClassName)) + { + result.add(eAttribute); + } + } + } + + return result; } private Collection<IAction> addEnablementActions(Collection<?> descriptors, ISelection selection, boolean sibling, Collection<IAction> actions) diff --git a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java index 764c2ab64..1ee75b9a7 100644 --- a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java +++ b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java @@ -14,16 +14,21 @@ import org.eclipse.oomph.base.provider.BaseEditUtil; import org.eclipse.oomph.base.provider.BaseEditUtil.IconReflectiveItemProvider; import org.eclipse.oomph.base.provider.BaseItemProviderAdapterFactory; import org.eclipse.oomph.base.util.BaseResourceImpl; +import org.eclipse.oomph.edit.NoChildrenDelegatingWrapperItemProvider; import org.eclipse.oomph.internal.base.BasePlugin; import org.eclipse.oomph.internal.setup.SetupPrompter; import org.eclipse.oomph.internal.ui.FindAndReplaceTarget; import org.eclipse.oomph.internal.ui.IRevertablePart; import org.eclipse.oomph.internal.ui.OomphEditingDomain; import org.eclipse.oomph.internal.ui.OomphPropertySheetPage; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.CompoundTask; import org.eclipse.oomph.setup.Configuration; import org.eclipse.oomph.setup.Index; import org.eclipse.oomph.setup.Installation; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; import org.eclipse.oomph.setup.ProductVersion; @@ -35,6 +40,7 @@ import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.oomph.setup.SetupTask; import org.eclipse.oomph.setup.Stream; import org.eclipse.oomph.setup.Trigger; +import org.eclipse.oomph.setup.User; import org.eclipse.oomph.setup.VariableTask; import org.eclipse.oomph.setup.Workspace; import org.eclipse.oomph.setup.internal.core.SetupContext; @@ -81,12 +87,16 @@ import org.eclipse.emf.common.ui.viewer.IViewerProvider; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.common.util.ECollections; import org.eclipse.emf.common.util.EList; 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.EAttribute; import org.eclipse.emf.ecore.EClass; 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.InternalEObject; import org.eclipse.emf.ecore.plugin.EcorePlugin; @@ -96,6 +106,7 @@ import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EContentAdapter; 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.EMFEditPlugin; import org.eclipse.emf.edit.command.AbstractOverrideableCommand; @@ -114,6 +125,7 @@ import org.eclipse.emf.edit.provider.IDisposable; import org.eclipse.emf.edit.provider.IItemFontProvider; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.provider.IItemPropertySource; +import org.eclipse.emf.edit.provider.ITreeItemContentProvider; import org.eclipse.emf.edit.provider.IWrapperItemProvider; import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; import org.eclipse.emf.edit.provider.ItemPropertyDescriptorDecorator; @@ -127,6 +139,7 @@ import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor; import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; import org.eclipse.emf.edit.ui.provider.DecoratingColumLabelProvider; import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator; +import org.eclipse.emf.edit.ui.provider.ExtendedColorRegistry; import org.eclipse.emf.edit.ui.provider.ExtendedFontRegistry; import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; import org.eclipse.emf.edit.ui.provider.UnwrappingSelectionProvider; @@ -184,9 +197,13 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; @@ -267,14 +284,16 @@ import java.util.Collections; import java.util.Comparator; import java.util.EventObject; 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.Map.Entry; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -297,6 +316,8 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private static final Pattern IMAGE_PATTERN = Pattern.compile("(<img )(src=)"); + private static final URI COMPOSITE_OUTLINE_COLOR = URI.createURI("color://rgb/138/110/85"); + private static final Object UNDECLARED_VARIABLE_GROUP_IMAGE; static @@ -756,7 +777,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } }; - private ResourceMirror resourceMirror; + private AtomicReference<ResourceMirror> resourceMirror; private final ItemProvider loadingResourceInput = new ItemProvider(Collections.singleton(new ItemProvider("Loading resource..."))); @@ -770,6 +791,8 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr protected SetupActionBarContributor.SetupWorkingSetsProvider workingSetsProvider = new SetupActionBarContributor.SetupWorkingSetsProvider(); + private AdapterFactoryContentProvider selectionViewerContentProvider; + /** * This creates a model editor. * <!-- begin-user-doc --> @@ -838,7 +861,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { ResourceSet resourceSet = editingDomain.getResourceSet(); URIConverter uriConverter = resourceSet.getURIConverter(); - final Set<IFile> files = new HashSet<IFile>(); + final Set<IFile> files = new LinkedHashSet<IFile>(); for (Resource resource : resourceSet.getResources()) { @@ -924,7 +947,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr if (!changedResources.isEmpty()) { - // Only the first resource is modifiable, so if other resources are removed, we can just unload them, an ignore them form further dirty handling. + // Only the first resource is modifiable, so if other resources are removed, we can just unload them, an ignore them from further dirty handling. List<Resource> changedResources = new ArrayList<Resource>(this.changedResources); if (!changedResources.remove(resourceSet.getResources().get(0))) { @@ -956,6 +979,10 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr updateProblemIndication = true; updateProblemIndication(); + + // Force updates such a revalidation and content out update. + ReflectUtil.invokeMethod("notifyListeners", editingDomain.getCommandStack()); + selectionViewer.refresh(); } } @@ -1151,7 +1178,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr for (Iterator<PropertySheetPage> i = propertySheetPages.iterator(); i.hasNext();) { PropertySheetPage propertySheetPage = i.next(); - if (propertySheetPage.getControl().isDisposed()) + if (propertySheetPage.getControl() == null || propertySheetPage.getControl().isDisposed()) { i.remove(); } @@ -1205,11 +1232,23 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr ResourceSet resourceSet = resource.getResourceSet(); if (resourceSet != null && resourceSet.getResources().get(0) != resource) { + if (children != null) + { + for (DelegatingWrapperItemProvider child : children) + { + if (((EObject)child.getValue()).eIsProxy()) + { + children = null; + break; + } + } + } + if (children == null) { children = new ArrayList<DelegatingWrapperItemProvider>(); int index = 0; - for (Object child : contents) + for (EObject child : contents) { children.add(new DelegatingWrapperItemProvider(child, resource, null, index++, resourceItemProviderAdapterFactory)); } @@ -1414,7 +1453,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr // Create the editing domain with a special command stack. // - Map<Resource, Boolean> readOnlyMap = new HashMap<Resource, Boolean>() + Map<Resource, Boolean> readOnlyMap = new LinkedHashMap<Resource, Boolean>() { private static final long serialVersionUID = 1L; @@ -1504,14 +1543,35 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr // If we're trying to select a resource in the selection viewer, make sure resources are visible there. if (currentViewer == selectionViewer) { + List<Object> effectiveCollection = new ArrayList<Object>(); + boolean selectResource = false; for (Object object : collection) { if (object instanceof Resource) { - toggleInput(true); - break; + selectResource = true; + Object[] children = selectionViewerContentProvider.getChildren(object); + if (children.length == 0) + { + effectiveCollection.add(object); + } + else + { + effectiveCollection.add(children[0]); + } + } + else + { + effectiveCollection.add(object); } } + + if (selectResource) + { + toggleInput(true); + } + + collection = effectiveCollection; } setSelectionToViewerGen(collection); @@ -1742,7 +1802,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr // If the index's folder is redirected to the local file system... URIConverter uriConverter = resourceSet.getURIConverter(); Map<URI, URI> uriMap = uriConverter.getURIMap(); - Map<URI, URI> workspaceMappings = new HashMap<URI, URI>(); + Map<URI, URI> workspaceMappings = new LinkedHashMap<URI, URI>(); for (URI uri : uriMap.values()) { if (uri.isFile() && !uri.isRelative()) @@ -1787,7 +1847,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr uriMap.putAll(workspaceMappings); URI resourceURI = SetupEditorSupport.getURI(getEditorInput(), resourceSet.getURIConverter()); - resourceMirror.perform(resourceURI); + resourceMirror.get().perform(resourceURI); final Resource mainResource = resourceSet.getResource(resourceURI, false); EList<EObject> contents = mainResource.getContents(); @@ -1912,7 +1972,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr }; } - resourceMirror.perform(SetupContext.INDEX_SETUP_URI); + resourceMirror.get().perform(SetupContext.INDEX_SETUP_URI); } } @@ -1927,7 +1987,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr editingDomain.getResourceSet().eAdapters().add(problemIndicationAdapter); - if (!resourceMirror.isCanceled() && rootObject != null) + if (!resourceMirror.get().isCanceled() && rootObject != null) { Display display = getSite().getShell().getDisplay(); display.asyncExec(new Runnable() @@ -2005,7 +2065,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } } - private void configure(ColumnViewer viewer, final boolean foreignResourceDecoration) + private void configure(ColumnViewer viewer, final Set<Resource> primaryResources, final Set<EObject> syntheticEObjects) { final SetupLocationListener locationListener = new SetupLocationListener(true); locationListener.setEditor(this); @@ -2110,6 +2170,16 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr }; @Override + protected void decorate(Map<Object, BasicDiagnostic> objects) + { + // Don't decorate the outline. + if (primaryResources == null) + { + super.decorate(objects); + } + } + + @Override protected BasicDiagnostic decorate(Map<Object, BasicDiagnostic> decorations, Object object, Diagnostic diagnostic, List<Integer> path) { if (diagnostic != null) @@ -2409,6 +2479,9 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } }; + // private static final URI FOREGROUND_COLOR = URI.createURI("color://rgb/85/113/138"); + + final Color syntheticColor = ExtendedColorRegistry.INSTANCE.getColor(null, null, URI.createURI("color://rgb/85/113/138")); final Font font = viewer.getControl().getFont(); viewer.setLabelProvider(new DecoratingColumLabelProvider(setupLabelProvider, diagnosticDecorator) { @@ -2458,17 +2531,25 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } @Override + public Color getForeground(Object element) + { + Color foreground = super.getForeground(element); + if (foreground == null && syntheticEObjects != null && syntheticEObjects.contains(element)) + { + foreground = syntheticColor; + } + + return foreground; + } + + @Override public Font getFont(Object object) { Font result = super.getFont(object); - if (foreignResourceDecoration && object instanceof SetupTask) + Object unwrappedObject = AdapterFactoryEditingDomain.unwrap(object); + if (primaryResources != null && unwrappedObject instanceof EObject && !primaryResources.contains(((EObject)unwrappedObject).eResource())) { - SetupTask setupTask = (SetupTask)object; - Resource resource = setupTask.eResource(); - if (resource == null || !editingDomain.getResourceSet().getResources().get(0).getURI().equals(resource.getURI())) - { - result = ExtendedFontRegistry.INSTANCE.getFont(result != null ? result : font, IItemFontProvider.ITALIC_FONT); - } + result = ExtendedFontRegistry.INSTANCE.getFont(result != null ? result : font, IItemFontProvider.ITALIC_FONT); } return result; @@ -2547,9 +2628,9 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr selectionViewer = new TreeViewer(tree); setCurrentViewer(selectionViewer); - configure(selectionViewer, false); + configure(selectionViewer, null, null); - selectionViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory) + selectionViewerContentProvider = new AdapterFactoryContentProvider(adapterFactory) { @Override public Object getParent(Object object) @@ -2566,7 +2647,9 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr return super.getParent(object); } - }); + }; + + selectionViewer.setContentProvider(selectionViewerContentProvider); selectionViewer.setInput(loadingResourceInput); @@ -2611,6 +2694,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr protected void doLoad() { + resourceMirror = new AtomicReference<ResourceMirror>(); final Tree tree = selectionViewer.getTree(); Job job = new Job("Loading Model") { @@ -2631,7 +2715,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr @Override protected void run(String taskName, IProgressMonitor monitor) { - SetupEditor.this.resourceMirror = this; + SetupEditor.this.resourceMirror.set(this); createModel(); resolveProxies(); dialogSettings.setLiveValidation(true); @@ -2821,13 +2905,29 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private Trigger trigger; - private Map<Object, Set<Object>> copyMap = new HashMap<Object, Set<Object>>(); + private final Map<Object, Set<Object>> copyMap = new LinkedHashMap<Object, Set<Object>>(); + + private final Map<Object, Set<Object>> inverseCopyMap = new LinkedHashMap<Object, Set<Object>>(); + + private final Map<SetupTask, Set<VariableTask>> inducedIDVariables = new LinkedHashMap<SetupTask, Set<VariableTask>>(); + + private final List<Notifier> notifiers = new ArrayList<Notifier>(); + + private final Set<EObject> syntheticObjects = new LinkedHashSet<EObject>(); + + private final Map<Object, Object> parents = new LinkedHashMap<Object, Object>(); - private Map<Object, Set<Object>> inverseCopyMap = new HashMap<Object, Set<Object>>(); + private final List<Scope> previewableScopes = new UniqueEList<Scope>(); - private List<Notifier> notifiers = new ArrayList<Notifier>(); + private final Set<Resource> primaryResources = new LinkedHashSet<Resource>(); - private Map<Object, Object> parents = new HashMap<Object, Object>(); + private final Stream compositeStream = SetupFactory.eINSTANCE.createStream(); + + private final Configuration compositeConfiguration = SetupFactory.eINSTANCE.createConfiguration(); + + private final Macro compositeMacro = SetupFactory.eINSTANCE.createMacro(); + + private OutlineItemProvider root; private AdapterFactoryEditingDomain.EditingDomainProvider editingDomainProvider = new AdapterFactoryEditingDomain.EditingDomainProvider(editingDomain); @@ -2835,10 +2935,28 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private AdapterFactoryItemDelegator itemDelegator; + private PreviewAction previewAction; + + public OutlinePreviewPage() + { + compositeStream.setLabel("Composite Stream"); + compositeStream.setName("composite"); + compositeStream.setDescription("This is a stream to represent the composition of all the workspace's streams"); + + compositeConfiguration.setLabel("Configurations"); + compositeConfiguration.setDescription("All available configurations"); + + compositeMacro.setName("macros"); + compositeMacro.setLabel("Macros"); + compositeMacro.setDescription("All available macros"); + } + private class VariableContainer extends ItemProvider { private SetupTaskPerformer setupTaskPerformer; + private Map<Pair<Object, Object>, IWrapperItemProvider> wrappers = new LinkedHashMap<Pair<Object, Object>, IWrapperItemProvider>(); + public VariableContainer(SetupTaskPerformer setupTaskPerformer, String text, Object image) { super(text, image); @@ -2849,6 +2967,42 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { return setupTaskPerformer; } + + public IWrapperItemProvider wrapper(Object variable, Object child) + { + Pair<Object, Object> key = Pair.create(variable, child); + IWrapperItemProvider wrapper = wrappers.get(key); + if (wrapper == null) + { + wrapper = new NoChildrenDelegatingWrapperItemProvider(child, variable, SetupEditor.this.adapterFactory); + add(inverseCopyMap, wrapper, child); + wrappers.put(key, wrapper); + } + + return wrapper; + } + } + + public List<Scope> getPreviewableScopes() + { + for (ListIterator<Scope> it = previewableScopes.listIterator(); it.hasNext();) + { + Scope scope = it.next(); + if (scope.eIsProxy()) + { + EObject resolvedScope = EcoreUtil.resolve(scope, editingDomain.getResourceSet()); + if (!resolvedScope.eIsProxy() && resolvedScope instanceof Scope) + { + it.set((Scope)resolvedScope); + } + else + { + it.remove(); + } + } + } + + return previewableScopes; } @Override @@ -2865,6 +3019,9 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr }); contentOutlineViewer = getTreeViewer(); + + previewAction = new PreviewAction(); + contentOutlineViewer.addSelectionChangedListener(this); contentOutlineViewer.addDoubleClickListener(new IDoubleClickListener() @@ -2886,42 +3043,129 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr @Override public boolean hasChildren(Object object) { - return object instanceof VariableTask && parents.get(object) instanceof VariableContainer || super.hasChildren(object); + return getVariableContainer(object) != null || super.hasChildren(object); + } + + private VariableContainer getVariableContainer(Object object) + { + if (object instanceof VariableTask) + { + Object parent = parents.get(object); + if (parent instanceof VariableContainer) + { + return (VariableContainer)parent; + } + } + + return null; } @Override public Object[] getChildren(Object object) { - if (object instanceof VariableTask && parents.get(object) instanceof VariableContainer) + VariableContainer variableContainer = getVariableContainer(object); + if (variableContainer != null) { - Resource resource = editingDomain.getResourceSet().getResources().get(0); - SetupTaskPerformer setupTaskPerformer = ((VariableContainer)parents.get(object)).getSetupTaskPerformer(); VariableTask contextVariableTask = (VariableTask)object; String name = contextVariableTask.getName(); - List<EObject> variableUsages = new ArrayList<EObject>(); - for (Object o : copyMap.keySet()) + if (!StringUtil.isEmpty(name)) { - if (o instanceof EObject) + boolean isMacro = false; + List<Object> variableUsages = new UniqueEList<Object>(); + Set<Object> inverses = inverseCopyMap.get(object); + if (inverses != null) { - EObject eObject = (EObject)o; - if (eObject.eResource() == resource - && (setupTaskPerformer.isVariableUsed(name, eObject, false) || setupTaskPerformer.isFilterUsed(name, eObject))) + for (Object inverse : inverses) { - variableUsages.add(eObject); + Object unwrappedInverse = AdapterFactoryEditingDomain.unwrap(inverse); + if (unwrappedInverse instanceof Parameter) + { + String actualName = ((Parameter)unwrappedInverse).getName(); + Object unwrappedParent = AdapterFactoryEditingDomain.unwrap(selectionViewerContentProvider.getParent(inverse)); + if (unwrappedParent instanceof Macro) + { + isMacro = true; + Macro macro = (Macro)unwrappedParent; + variableUsages.addAll(getMatchingUsages(variableContainer, object, macro, actualName)); + } + } + else if (unwrappedInverse instanceof VariableTask) + { + VariableTask variableTask = (VariableTask)unwrappedInverse; + String actualName = variableTask.getName(); + if (!name.equals(actualName)) + { + EObject rootContainer = EcoreUtil.getRootContainer(variableTask); + if (rootContainer instanceof Macro) + { + isMacro = true; + variableUsages.addAll(getMatchingUsages(variableContainer, object, rootContainer, actualName)); + } + } + } } } + + if (!isMacro) + { + variableUsages.addAll(getMatchingUsages(variableContainer, object, null, name)); + } + + return variableUsages.toArray(); } + } - variableUsages.addAll(contextVariableTask.getChoices()); - for (EObject eObject : variableUsages) + return super.getChildren(object); + } + + private List<Object> getMatchingUsages(VariableContainer variableContainer, Object object, EObject context, String actualName) + { + List<Object> variableUsages = new ArrayList<Object>(); + SetupTaskPerformer setupTaskPerformer = variableContainer.getSetupTaskPerformer(); + for (Object original : copyMap.keySet()) + { + Object unwrappedOriginal = AdapterFactoryEditingDomain.unwrap(original); + if (unwrappedOriginal instanceof EObject) { - parents.put(eObject, object); + EObject unwrappedOriginalEObject = (EObject)unwrappedOriginal; + if (context == null) + { + Macro containingMacro = getContainingMacro(original); + if (containingMacro != null && !setupTaskPerformer.getMacroCopyMap().containsKey(original)) + { + continue; + } + } + else if (!EcoreUtil.isAncestor(context, unwrappedOriginalEObject)) + { + continue; + } + + if (SetupTaskPerformer.isVariableUsed(actualName, unwrappedOriginalEObject, false) + || SetupTaskPerformer.isFilterUsed(actualName, unwrappedOriginalEObject)) + { + variableUsages.add(variableContainer.wrapper(object, original)); + } } + } + + return variableUsages; + } - return variableUsages.toArray(); + private Macro getContainingMacro(Object object) + { + if (object instanceof EObject) + { + for (EObject eContainer = ((EObject)object).eContainer(); eContainer != null; eContainer = eContainer.eContainer()) + { + if (eContainer instanceof Macro) + { + return (Macro)eContainer; + } + } } - return super.getChildren(object); + return null; } @Override @@ -2934,16 +3178,26 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr contentOutlineViewer.setContentProvider(contentProvider); - configure(contentOutlineViewer, true); + configure(contentOutlineViewer, primaryResources, syntheticObjects); + Menu menu = contentOutlineViewer.getControl().getMenu(); + IMenuManager menuManager = (IMenuManager)menu.getData(MenuManager.MANAGER_KEY); + menuManager.addMenuListener(new IMenuListener() + { + public void menuAboutToShow(IMenuManager manager) + { + manager.insertBefore("edit", previewAction); + } + }); labelProvider = (ILabelProvider)contentOutlineViewer.getLabelProvider(); + root = new OutlineItemProvider(null, false); selectionViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection)event.getSelection(); - if (selectionViewer != null && !selection.isEmpty() && contentOutlinePage != null) + if (selectionViewer != null && selectionViewer.getControl().isFocusControl() && !selection.isEmpty() && contentOutlinePage != null) { ArrayList<Object> selectionList = new ArrayList<Object>(); for (Object object : selection.toArray()) @@ -2962,19 +3216,30 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private void collectSelection(List<Object> selection, Object object) { - if (object instanceof CompoundTask) + Object unwrappedObject = AdapterFactoryEditingDomain.unwrap(object); + if (unwrappedObject instanceof CompoundTask || unwrappedObject instanceof Macro) { - for (SetupTask setupTask : ((CompoundTask)object).getSetupTasks()) + Collection<?> children = object instanceof ITreeItemContentProvider ? ((ITreeItemContentProvider)object).getChildren(object) + : ((EObject)unwrappedObject).eContents(); + for (Object child : children) { - collectSelection(selection, setupTask); + collectSelection(selection, child); } } else { Set<Object> copies = contentOutlinePage.getCopies(object); - if (copies != null) + for (Object copy : copies) { - selection.addAll(copies); + Object unwrappedCopy = AdapterFactoryEditingDomain.unwrap(copy); + if (unwrappedCopy instanceof CompoundTask) + { + collectSelection(selection, copy); + } + else + { + selection.add(copy); + } } } } @@ -2985,13 +3250,44 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr public Set<Object> getOriginals(Object object) { - Set<Object> result = inverseCopyMap.get(object); - return result == null ? Collections.singleton(object) : result; + Set<Object> originals = inverseCopyMap.get(object); + if (originals == null) + { + return copyMap.containsKey(object) ? Collections.singleton(object) : Collections.emptySet(); + } + + return originals; } public Set<Object> getCopies(Object object) { - return copyMap.get(object); + Set<Object> copies = copyMap.get(object); + if (copies == null) + { + return inverseCopyMap.containsKey(object) ? Collections.singleton(object) : Collections.emptySet(); + + } + return copies; + } + + private boolean isPreviewableScope(Object scope) + { + return scope instanceof Macro || scope instanceof Workspace || scope instanceof Installation || scope instanceof Stream || scope instanceof ProductVersion + || scope instanceof User; + } + + protected Index getIndex() + { + for (Resource resource : editingDomain.getResourceSet().getResources()) + { + Index index = (Index)EcoreUtil.getObjectByType(resource.getContents(), SetupPackage.Literals.INDEX); + if (index != null) + { + return index; + } + } + + return null; } public void update(int expandLevel) @@ -3000,6 +3296,9 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { copyMap.clear(); inverseCopyMap.clear(); + inducedIDVariables.clear(); + primaryResources.clear(); + syntheticObjects.clear(); ResourceSet resourceSet = editingDomain.getResourceSet(); if (resourceLocator != null) @@ -3021,11 +3320,80 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr EList<Resource> resources = resourceSet.getResources(); if (!resources.isEmpty()) { - Project project = (Project)EcoreUtil.getObjectByType(resources.get(0).getContents(), SetupPackage.Literals.PROJECT); - if (project != null) + Resource resource = resources.get(0); + primaryResources.add(resource); + EList<EObject> contents = resource.getContents(); + if (!contents.isEmpty()) { - ItemProvider input = getTriggeredTasks(project); - getTreeViewer().setInput(input); + EObject rootEObject = contents.get(0); + boolean hasEmptyInput = getTreeViewer().getInput() == null; + if (hasEmptyInput) + { + if (isPreviewableScope(rootEObject)) + { + previewableScopes.add((Scope)rootEObject); + } + else if (rootEObject instanceof Project) + { + previewableScopes.addAll(((Project)rootEObject).getStreams()); + } + else if (rootEObject instanceof Product) + { + previewableScopes.addAll(((Product)rootEObject).getVersions()); + } + } + + List<Object> newRootChildren = new ArrayList<Object>(); + newRootChildren.add(reconcileOutline(root, null, rootEObject)); + if (rootEObject instanceof Workspace || rootEObject instanceof Installation || rootEObject instanceof Configuration) + { + Index index = getIndex(); + if (index != null) + { + newRootChildren.add(reconcileOutline(root, null, index)); + } + } + + OutlineItemProvider macroOutline = reconcileCompositeOutline(root, compositeMacro); + if (macroOutline != null) + { + newRootChildren.add(macroOutline); + } + + if (rootEObject instanceof Configuration || rootEObject instanceof Index) + { + OutlineItemProvider configurationOutline = reconcileCompositeOutline(root, compositeConfiguration); + if (configurationOutline != null) + { + newRootChildren.add(configurationOutline); + } + } + + ECollections.setEList(root.getChildren(), newRootChildren); + + if (hasEmptyInput) + { + getTreeViewer().setInput(root); + if (!previewableScopes.isEmpty()) + { + Set<Object> elements = copyMap.get(previewableScopes.get(0)); + if (elements != null) + { + for (Object object : elements) + { + if (object instanceof OutlineItemProvider) + { + getTreeViewer().setExpandedState(object, true); + break; + } + } + } + } + } + else + { + getTreeViewer().refresh(); + } } } } @@ -3034,19 +3402,29 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr SetupEditorPlugin.INSTANCE.log(ex); } + // Invert the copy map. for (Map.Entry<Object, Set<Object>> entry : copyMap.entrySet()) { - Set<Object> values = entry.getValue(); - for (Object value : values) + Object original = entry.getKey(); + Set<Object> copies = entry.getValue(); + for (Object value : copies) + { + add(inverseCopyMap, value, original); + } + } + + // Map induced variables back to the task from which they are induced. + for (Map.Entry<SetupTask, Set<VariableTask>> entry : inducedIDVariables.entrySet()) + { + SetupTask setupTask = entry.getKey(); + Set<VariableTask> variables = entry.getValue(); + Set<Object> inverses = inverseCopyMap.get(setupTask); + if (inverses != null) { - Set<Object> eObjects = inverseCopyMap.get(value); - if (eObjects == null) + for (VariableTask variable : variables) { - eObjects = new HashSet<Object>(); - inverseCopyMap.put(value, eObjects); + addAll(inverseCopyMap, variable, inverses); } - - eObjects.add(entry.getKey()); } } @@ -3054,6 +3432,43 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } } + private OutlineItemProvider reconcileCompositeOutline(OutlineItemProvider parent, EObject composite) + { + EClass eClass = composite.eClass(); + EList<Resource> resources = editingDomain.getResourceSet().getResources(); + OutlineItemProvider compositeOutline = null; + List<OutlineItemProvider> newChildren = new ArrayList<OutlineItemProvider>(); + for (int i = 1, size = resources.size(); i < size; ++i) + { + Resource otherResource = resources.get(i); + EObject instance = (EObject)EcoreUtil.getObjectByType(otherResource.getContents(), eClass); + if (instance != null) + { + if (compositeOutline == null) + { + compositeOutline = reconcileOutline(parent, null, composite); + } + + newChildren.add(reconcileOutline(compositeOutline, null, instance)); + } + } + + if (compositeOutline != null) + { + Collections.sort(newChildren, new Comparator<OutlineItemProvider>() + { + public int compare(OutlineItemProvider o1, OutlineItemProvider o2) + { + return CommonPlugin.INSTANCE.getComparator().compare(o1.getText(), o2.getText()); + } + }); + + ECollections.setEList(compositeOutline.getChildren(), newChildren); + } + + return compositeOutline; + } + private List<String> sortStrings(Collection<? extends String> strings) { EList<Pair<SegmentSequence, String>> pairs = new BasicEList<Pair<SegmentSequence, String>>(); @@ -3135,282 +3550,747 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr return result; } - private ItemProvider getTriggeredTasks(final Project project) + private OutlineItemProvider reconcileOutline(OutlineItemProvider parentItemProvider, Scope context, EObject scope) { - class ProjectItemProvider extends ItemProvider implements IWrapperItemProvider + OutlineItemProvider outlineItemProvider = parentItemProvider.getOutlineItemProvider(scope); + if (outlineItemProvider == null) + { + outlineItemProvider = new OutlineItemProvider(scope, context != null); + } + else { - public ProjectItemProvider() + outlineItemProvider.update(); + } + + add(copyMap, scope, outlineItemProvider); + + List<Object> newChildren = new ArrayList<Object>(); + if (getPreviewableScopes().contains(scope)) + { + newChildren.addAll(gatherSetupTasks(outlineItemProvider, context, (Scope)scope)); + } + + EClass eClass = scope.eClass(); + for (EReference eReference : eClass.getEAllContainments()) + { + if (SetupPackage.Literals.SCOPE.isSuperTypeOf(eReference.getEReferenceType())) { - super(labelProvider.getText(project), labelProvider.getImage(project)); + if (eReference.isMany()) + { + @SuppressWarnings("unchecked") + List<Scope> scopes = (List<Scope>)scope.eGet(eReference); + for (Scope childScope : scopes) + { + newChildren.add(reconcileOutline(outlineItemProvider, null, childScope)); + } + } + else + { + Scope childScope = (Scope)scope.eGet(eReference); + if (childScope != null) + { + newChildren.add(reconcileOutline(outlineItemProvider, null, childScope)); + } + } } + } - public Object getValue() + for (EReference eReference : eClass.getEAllReferences()) + { + if (eReference == SetupPackage.Literals.WORKSPACE__STREAMS || eReference == SetupPackage.Literals.INSTALLATION__PRODUCT_VERSION) { - return project; + if (eReference.isMany()) + { + @SuppressWarnings("unchecked") + List<Scope> scopes = (List<Scope>)scope.eGet(eReference); + if (!scopes.isEmpty()) + { + newChildren.add(reconcileOutline(outlineItemProvider, (Scope)scope, compositeStream)); + + for (Scope childScope : scopes) + { + newChildren.add(reconcileOutline(outlineItemProvider, (Scope)scope, childScope)); + } + } + } + else + { + Scope childScope = (Scope)scope.eGet(eReference); + if (childScope != null) + { + newChildren.add(reconcileOutline(outlineItemProvider, (Scope)scope, childScope)); + } + } } + } + + ECollections.setEList(outlineItemProvider.getChildren(), newChildren); + + return outlineItemProvider; + } + + private class OutlineItemProvider extends ItemProvider implements IWrapperItemProvider, IItemPropertySource + { + private final EObject eObject; + + private boolean qualified; - public Object getOwner() + public OutlineItemProvider(EObject eObject, boolean qualified) + { + super(qualified ? ((Scope)eObject).getQualifiedLabel() : labelProvider.getText(eObject), labelProvider.getImage(eObject)); + this.eObject = eObject; + this.qualified = qualified; + } + + public void update() + { + setText(qualified ? ((Scope)eObject).getQualifiedLabel() : labelProvider.getText(eObject)); + } + + public OutlineItemProvider getOutlineItemProvider(EObject eObject) + { + for (Object child : getChildren()) { - return project; + if (child instanceof OutlineItemProvider && ((OutlineItemProvider)child).eObject == eObject) + { + return (OutlineItemProvider)child; + } } - public EStructuralFeature getFeature() + return null; + } + + @Override + public Object getFont(Object object) + { + if (eObject == compositeStream || eObject == compositeConfiguration || eObject == compositeMacro) { - return null; + return ITALIC_FONT; + } + + return super.getFont(object); + } + + @Override + public Object getForeground(Object object) + { + if (eObject == compositeStream || eObject == compositeConfiguration || eObject == compositeMacro) + { + return COMPOSITE_OUTLINE_COLOR; } - public int getIndex() + return super.getForeground(object); + } + + public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) + { + List<IItemPropertyDescriptor> descriptors = itemDelegator.getPropertyDescriptors(eObject); + + List<IItemPropertyDescriptor> result = new ArrayList<IItemPropertyDescriptor>(); + for (IItemPropertyDescriptor descriptor : descriptors) { - return 0; + result.add(new ItemPropertyDescriptorDecorator(eObject, descriptor)); } - public void setIndex(int index) + return result; + } + + public IItemPropertyDescriptor getPropertyDescriptor(Object object, Object propertyID) + { + IItemPropertyDescriptor descriptor = itemDelegator.getPropertyDescriptor(eObject, propertyID); + if (descriptor != null) { + return new ItemPropertyDescriptorDecorator(eObject, descriptor); } + + return null; } - final ItemProvider projectItem = new ProjectItemProvider(); + public Object getEditableValue(Object object) + { + return itemDelegator.getEditableValue(eObject); + } - EList<Object> projectItemChildren = projectItem.getChildren(); - EList<Stream> streams = project.getStreams(); - for (final Stream stream : streams) + public Object getValue() { - class BranchItemProvider extends ItemProvider implements IItemPropertySource + return eObject; + } + + public Object getOwner() + { + return getParent(); + } + + public EStructuralFeature getFeature() + { + return null; + } + + public int getIndex() + { + return 0; + } + + public void setIndex(int index) + { + } + } + + private List<Object> gatherSetupTasks(OutlineItemProvider container, Scope context, Scope scope) + { + List<Object> result = new ArrayList<Object>(); + ProductVersion version = scope instanceof ProductVersion ? (ProductVersion)scope : null; + Stream stream = scope instanceof Stream ? (Stream)scope : null; + Macro macro = scope instanceof Macro ? (Macro)scope : null; + + if (version == null) + { + EObject rootContainer = null; + if (stream != null) { - public BranchItemProvider() + Project project = stream.getProject(); + if (project != null) { - super(labelProvider.getText(stream), labelProvider.getImage(stream)); + ProjectCatalog projectCatalog = project.getProjectCatalog(); + rootContainer = EcoreUtil.getRootContainer(projectCatalog); } + } - public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) + if (!(rootContainer instanceof Index)) + { + Index index = getIndex(); + if (index != null) { - List<IItemPropertyDescriptor> descriptors = itemDelegator.getPropertyDescriptors(stream); + rootContainer = index; + } + } - List<IItemPropertyDescriptor> result = new ArrayList<IItemPropertyDescriptor>(); - for (IItemPropertyDescriptor descriptor : descriptors) + if (rootContainer instanceof Index) + { + Index index = (Index)rootContainer; + for (ProductCatalog productCatalog : index.getProductCatalogs()) + { + // The first should be the self product catalog, so find the last version which should be the empty version. + for (Product product : productCatalog.getProducts()) { - result.add(new ItemPropertyDescriptorDecorator(stream, descriptor)); + // This should be the self product, so find the last version which should be the empty version. + for (ProductVersion productVersion : product.getVersions()) + { + version = productVersion; + } } - return result; + break; } + } + + if (version == null) + { + return result; + } + } + + SetupContext setupContext = SetupContext.create(version, stream); - public IItemPropertyDescriptor getPropertyDescriptor(Object object, Object propertyID) + EcoreUtil.Copier copier = new EcoreUtil.Copier(); + if (scope instanceof Workspace) + { + Workspace workspaceCopy = (Workspace)copier.copy(scope); + copier.copyReferences(); + workspaceCopy.getStreams().clear(); + + Resource fakeWorkspaceResource = new BaseResourceImpl(scope.eResource().getURI()); + fakeWorkspaceResource.getContents().add(workspaceCopy); + setupContext = SetupContext.create(setupContext.getInstallation(), workspaceCopy, setupContext.getUser()); + } + else if (scope instanceof Installation) + { + Installation installationCopy = (Installation)copier.copy(scope); + copier.copyReferences(); + installationCopy.setProductVersion(version); + + Resource fakeInstallationResource = new BaseResourceImpl(scope.eResource().getURI()); + fakeInstallationResource.getContents().add(installationCopy); + setupContext = SetupContext.create(installationCopy, setupContext.getWorkspace(), setupContext.getUser()); + } + else if (scope instanceof User) + { + User userCopy = (User)copier.copy(scope); + copier.copyReferences(); + + Resource fakeUserResource = new BaseResourceImpl(scope.eResource().getURI()); + fakeUserResource.getContents().add(userCopy); + setupContext = SetupContext.create(setupContext.getInstallation(), setupContext.getWorkspace(), userCopy); + } + + if (context instanceof Installation) + { + Installation installationCopy = (Installation)copier.copy(context); + copier.copyReferences(); + installationCopy.setProductVersion(version); + + Resource fakeInstallationResource = new BaseResourceImpl(context.eResource().getURI()); + fakeInstallationResource.getContents().add(installationCopy); + setupContext = SetupContext.create(installationCopy, setupContext.getWorkspace(), setupContext.getUser()); + } + else if (context instanceof Workspace) + { + Installation installation = setupContext.getInstallation(); + Workspace workspaceCopy = (Workspace)copier.copy(context); + if (stream == compositeStream) + { + EObject eContainer = context.eContainer(); + if (eContainer instanceof Configuration) { - IItemPropertyDescriptor descriptor = itemDelegator.getPropertyDescriptor(stream, propertyID); - if (descriptor != null) + Configuration configuration = (Configuration)eContainer; + Installation configurationInstallation = configuration.getInstallation(); + if (configurationInstallation != null) { - return new ItemPropertyDescriptorDecorator(stream, descriptor); + Installation configurationInstallationCopy = (Installation)copier.copy(configurationInstallation); + installation = configurationInstallationCopy; + Resource fakeInstallationResource = new BaseResourceImpl(context.eResource().getURI()); + fakeInstallationResource.getContents().add(configurationInstallationCopy); } - - return null; } - public Object getEditableValue(Object object) - { - return itemDelegator.getEditableValue(stream); - } + copier.copyReferences(); + } + else + { + copier.copyReferences(); + workspaceCopy.getStreams().clear(); + workspaceCopy.getStreams().add(stream); + } + + Resource fakeWorkspaceResource = new BaseResourceImpl(context.eResource().getURI()); + fakeWorkspaceResource.getContents().add(workspaceCopy); + setupContext = SetupContext.create(installation, workspaceCopy, setupContext.getUser()); + } + + MacroTask macroTask = null; + List<VariableTask> macroTaskVariables = new ArrayList<VariableTask>(); + if (macro != null) + { + Workspace workspace = setupContext.getWorkspace(); + macroTask = SetupFactory.eINSTANCE.createMacroTask(); + macroTask.setMacro(macro); + workspace.getSetupTasks().add(macroTask); + + String id = macro.getName(); + macroTask.setID(StringUtil.isEmpty(id) ? "macro" : id); + EList<Parameter> parameters = macro.getParameters(); + EList<Argument> arguments = macroTask.getArguments(); + for (Parameter parameter : parameters) + { + VariableTask variable = SetupFactory.eINSTANCE.createVariableTask(); + String parameterName = parameter.getName(); + variable.setName(parameterName); + workspace.getSetupTasks().add(variable); + macroTaskVariables.add(variable); + + Argument argument = SetupFactory.eINSTANCE.createArgument(); + argument.setParameter(parameter); + argument.setValue("${" + parameterName + "}"); + arguments.add(argument); + } + + Resource resource = workspace.eResource(); + if (resource == null) + { + Resource fakeWorkspaceResource = new BaseResourceImpl(macro.eResource().getURI()); + fakeWorkspaceResource.getContents().add(workspace); + resource = fakeWorkspaceResource; + } + + primaryResources.add(resource); + } + + ResourceSet resourceSet = getEditingDomain().getResourceSet(); + URIConverter uriConverter = resourceSet.getURIConverter(); + + SetupTaskPerformer setupTaskPerformer; + + try + { + setupTaskPerformer = SetupTaskPerformer.create(uriConverter, SetupPrompter.OK, trigger, setupContext, false, true); + } + catch (Exception ex) + { + return result; + } + + List<SetupTask> triggeredSetupTasks = new ArrayList<SetupTask>(setupTaskPerformer.getTriggeredSetupTasks()); + + if (!triggeredSetupTasks.isEmpty()) + { + // Propagate the copied mappings to the performer's copy map. + final Map<EObject, Set<EObject>> performerCopyMap = setupTaskPerformer.getCopyMap(); + for (Map.Entry<EObject, EObject> entry : copier.entrySet()) + { + EObject key = entry.getKey(); + EObject value = entry.getValue(); + performerCopyMap.put(key, performerCopyMap.get(value)); + } + + URI baseURI = URI.createURI("performer:/" + scope.getQualifiedName()); + URI uri = baseURI.appendSegment("tasks.setup"); + URI scopeURI = context == null ? scope.eResource().getURI() : context.eResource().getURI(); + + Resource fakeResource = new BaseResourceImpl(uri); + fakeResource.eAdapters().add(editingDomainProvider); + EList<EObject> fakeResourceContents = fakeResource.getContents(); + resourceLocator.map(uri, fakeResource); + + Set<EObject> eObjects = new LinkedHashSet<EObject>(); + for (Set<EObject> copies : performerCopyMap.values()) + { + eObjects.addAll(copies); } - final ItemProvider branchItem = new BranchItemProvider(); - projectItemChildren.add(branchItem); + Map<EObject, Set<EObject>> performerMacroCopyMap = setupTaskPerformer.getMacroCopyMap(); + for (Set<EObject> copies : performerMacroCopyMap.values()) + { + eObjects.addAll(copies); + } - ProductVersion version = null; - ProjectCatalog projectCatalog = project.getProjectCatalog(); - if (projectCatalog != null) + for (EObject eObject : eObjects) { - EObject rootContainer = EcoreUtil.getRootContainer(projectCatalog); - if (!(rootContainer instanceof Index)) + notifiers.add(eObject); + + Resource resource = ((InternalEObject)eObject).eDirectResource(); + if (resource != null && !resource.eAdapters().contains(editingDomainProvider)) { - for (Resource resource : editingDomain.getResourceSet().getResources()) + resource.eAdapters().add(editingDomainProvider); + notifiers.add(resource); + + URI originalURI = resource.getURI(); + URI newURI = baseURI.appendSegment(originalURI.scheme() + ":").appendSegments(originalURI.segments()); + resource.setURI(newURI); + + if (scopeURI.equals(originalURI)) { - Object index = EcoreUtil.getObjectByType(resource.getContents(), SetupPackage.Literals.INDEX); - if (index != null) - { - rootContainer = (EObject)index; - } + primaryResources.add(resource); } + + resourceLocator.map(newURI, resource); } - if (rootContainer instanceof Index) + resource = eObject.eResource(); + if (resource == null || resource == fakeResource) { - Index index = (Index)rootContainer; - LOOP: for (ProductCatalog productCatalog : index.getProductCatalogs()) + EClass eClass = eObject.eClass(); + EAttribute eIDAttribute = eClass.getEIDAttribute(); + if (eIDAttribute != null) { - for (Product product : productCatalog.getProducts()) - { - for (ProductVersion productVersion : product.getVersions()) - { - version = productVersion; - break LOOP; - } - } + eObject.eUnset(eIDAttribute); } + + if (eObject.eContainer() == null) + { + fakeResourceContents.add(eObject); + } + + syntheticObjects.add(eObject); } } - if (version != null) + ItemProvider undeclaredVariablesItem = new VariableContainer(setupTaskPerformer, "Undeclared Variables", UNDECLARED_VARIABLE_GROUP_IMAGE); + EList<Object> undeclaredVariablesItemChildren = undeclaredVariablesItem.getChildren(); + Set<String> undeclaredVariables = setupTaskPerformer.getUndeclaredVariables(); + for (String key : sortStrings(undeclaredVariables)) + { + VariableTask contextVariableTask = SetupFactory.eINSTANCE.createVariableTask(); + fakeResourceContents.add(contextVariableTask); + contextVariableTask.setName(key); + undeclaredVariablesItemChildren.add(contextVariableTask); + parents.put(contextVariableTask, undeclaredVariablesItem); + } + + if (!undeclaredVariablesItemChildren.isEmpty()) + { + result.add(undeclaredVariablesItem); + } + + Map<String, VariableTask> variablesMap = new LinkedHashMap<String, VariableTask>(); + + ItemProvider unresolvedVariablesItem = new VariableContainer(setupTaskPerformer, "Unresolved Variables", VARIABLE_GROUP_IMAGE); + EList<Object> unresolvedVariablesItemChildren = unresolvedVariablesItem.getChildren(); + List<VariableTask> unresolvedVariables = setupTaskPerformer.getUnresolvedVariables(); + for (VariableTask variable : sortVariables(unresolvedVariables)) { - // Clear out the self induced installation location. - for (SetupTask setupTask : version.getProduct().getSetupTasks()) + if (variable.eContainer() == null && variable.eResource() == null) { - if (setupTask instanceof VariableTask) - { - VariableTask variable = (VariableTask)setupTask; - if ("installation.location".equals(variable.getName())) - { - EcoreUtil.delete(variable); - break; - } - } + fakeResourceContents.add(variable); } - version.getSetupTasks().clear(); - - SetupContext setupContext = SetupContext.create(version, stream); - ResourceSet resourceSet = getEditingDomain().getResourceSet(); - URIConverter uriConverter = resourceSet.getURIConverter(); + unresolvedVariablesItemChildren.add(variable); + parents.put(variable, unresolvedVariablesItem); + variablesMap.put(variable.getName(), variable); + } - SetupTaskPerformer setupTaskPerformer = new SetupTaskPerformer(uriConverter, SetupPrompter.CANCEL, trigger, setupContext, stream); - List<SetupTask> triggeredSetupTasks = new ArrayList<SetupTask>(setupTaskPerformer.getTriggeredSetupTasks()); - setupTaskPerformer.redirectTriggeredSetupTasks(); + if (!unresolvedVariablesItemChildren.isEmpty()) + { + result.add(unresolvedVariablesItem); + } - if (!triggeredSetupTasks.isEmpty()) + ItemProvider resolvedVariablesItem = new VariableContainer(setupTaskPerformer, "Resolved Variables", VARIABLE_GROUP_IMAGE); + EList<Object> resolvedVariablesItemChildren = resolvedVariablesItem.getChildren(); + List<VariableTask> resolvedVariables = setupTaskPerformer.getResolvedVariables(); + for (VariableTask variable : sortVariables(resolvedVariables)) + { + if (variable.eContainer() == null && variable.eResource() == null) { - URI baseURI = URI.createURI("performer:/" + stream.getQualifiedName()); - URI uri = baseURI.appendSegment("tasks.setup"); + fakeResourceContents.add(variable); + } - Resource fakeResource = new BaseResourceImpl(uri); - fakeResource.eAdapters().add(editingDomainProvider); - EList<EObject> fakeResourceContents = fakeResource.getContents(); - resourceLocator.map(uri, fakeResource); + resolvedVariablesItemChildren.add(variable); + parents.put(variable, resolvedVariablesItem); + variablesMap.put(variable.getName(), variable); + } - for (EObject eObject : setupTaskPerformer.getCopyMap().values()) - { - notifiers.add(eObject); + if (!resolvedVariablesItemChildren.isEmpty()) + { + result.add(resolvedVariablesItem); + } - Resource resource = ((InternalEObject)eObject).eDirectResource(); - if (resource != null && !resource.eAdapters().contains(editingDomainProvider)) - { - resource.eAdapters().add(editingDomainProvider); - notifiers.add(resource); + result.addAll(triggeredSetupTasks); - URI originalURI = resource.getURI(); - URI newURI = baseURI.appendSegment(originalURI.scheme() + ":").appendSegments(originalURI.segments()); - resource.setURI(newURI); - resourceLocator.map(newURI, resource); - } + for (SetupTask setupTask : triggeredSetupTasks) + { + parents.put(setupTask, container); + } - resource = eObject.eResource(); - if (resource == null || resource == fakeResource) + // Establish a mapping from wrapper item providers for macro tasks to their underlying wrapped objects. + Map<Object, Set<Object>> macroTaskMap = new LinkedHashMap<Object, Set<Object>>(); + Map<Object, Set<Object>> argumentBindingMap = new LinkedHashMap<Object, Set<Object>>(); + for (EObject eObject : performerCopyMap.keySet()) + { + if (eObject instanceof MacroTask) + { + MacroTask originalMacroTask = (MacroTask)eObject; + String id = originalMacroTask.getID(); + if (id != null) + { + if (originalMacroTask == macroTask) { - try - { - EcoreUtil.setID(eObject, null); - } - catch (IllegalArgumentException ex) + // Start directly from the macro we are previewing. + gatherMacroChild(macroTaskMap, argumentBindingMap, true, id, macro); + for (VariableTask variableTask : macroTaskVariables) { - // Ignore. - } - - if (eObject.eContainer() == null) - { - fakeResourceContents.add(eObject); + String name = variableTask.getName(); + String qualifiedName = SetupTaskPerformer.createQualifiedName(macroTask.getID(), name); + Set<Object> argumentsVariables = macroTaskMap.get(qualifiedName); + if (argumentsVariables != null) + { + addAll(macroTaskMap, variableTask, argumentsVariables); + } } } + else if (macroTask == null || !EcoreUtil.isAncestor(macroTask, originalMacroTask)) + { + // The above guard ensures that we don't walk nested macro task children multiple times, but only once starting from the root. + Object[] children = selectionViewerContentProvider.getChildren(originalMacroTask); + gatherMacroChildren(macroTaskMap, argumentBindingMap, false, id, children); + } } + } + } - ItemProvider undeclaredVariablesItem = new VariableContainer(setupTaskPerformer, "Undeclared Variables", UNDECLARED_VARIABLE_GROUP_IMAGE); - EList<Object> undeclaredVariablesItemChildren = undeclaredVariablesItem.getChildren(); - Set<String> undeclaredVariables = setupTaskPerformer.getUndeclaredVariables(); - for (String key : sortStrings(undeclaredVariables)) + // Propagate the performer's macro copy map to the macro task map. + for (Map.Entry<EObject, Set<EObject>> entry : performerMacroCopyMap.entrySet()) + { + EObject original = entry.getKey(); + Set<Object> macroTaskMappings = macroTaskMap.get(original); + if (macroTaskMappings != null) + { + Set<EObject> copies = entry.getValue(); + for (EObject copy : copies) { - VariableTask contextVariableTask = SetupFactory.eINSTANCE.createVariableTask(); - fakeResourceContents.add(contextVariableTask); - contextVariableTask.setName(key); - undeclaredVariablesItemChildren.add(contextVariableTask); - parents.put(contextVariableTask, undeclaredVariablesItem); + addAll(macroTaskMap, copy, macroTaskMappings); } + } + } - if (!undeclaredVariablesItemChildren.isEmpty()) + // Copy over the performer's copy map into the overall copy map. + for (Map.Entry<EObject, Set<EObject>> entry : performerCopyMap.entrySet()) + { + EObject original = entry.getKey(); + Set<EObject> copies = entry.getValue(); + addAll(copyMap, original, copies); + + Set<Object> macroTaskMappings = macroTaskMap.get(original); + if (macroTaskMappings != null) + { + // Include any mappings from the macro task map. + for (Object object : macroTaskMappings) { - branchItem.getChildren().add(undeclaredVariablesItem); + addAll(copyMap, object, copies); } + } - ItemProvider unresolvedVariablesItem = new VariableContainer(setupTaskPerformer, "Unresolved Variables", VARIABLE_GROUP_IMAGE); - EList<Object> unresolvedVariablesItemChildren = unresolvedVariablesItem.getChildren(); - List<VariableTask> unresolvedVariables = setupTaskPerformer.getUnresolvedVariables(); - for (VariableTask contextVariableTask : sortVariables(unresolvedVariables)) + if (original instanceof VariableTask) + { + VariableTask variableTask = (VariableTask)original; + String name = variableTask.getName(); + Set<Object> variableMappings = macroTaskMap.get(name); + if (variableMappings != null) { - if (contextVariableTask.eContainer() == null && contextVariableTask.eResource() == null) + // Include mappings from the parameter wrappers to the copies of the induced parameter variables. + for (Object object : variableMappings) { - fakeResourceContents.add(contextVariableTask); + addAll(copyMap, object, copies); } - - unresolvedVariablesItemChildren.add(contextVariableTask); - parents.put(contextVariableTask, unresolvedVariablesItem); } + } + } + + // Copy the performer's macro copy map to the overall copy map. + for (Map.Entry<EObject, Set<EObject>> entry : performerMacroCopyMap.entrySet()) + { + EObject key = entry.getKey(); + Set<EObject> copies = entry.getValue(); + addAll(copyMap, key, copies); - if (!unresolvedVariablesItemChildren.isEmpty()) + for (EObject eObject : copies) + { + // Also propagate any subsequent copies to flatten the map's indirections. + Set<Object> otherCopies = copyMap.get(eObject); + if (otherCopies != null) { - branchItem.getChildren().add(unresolvedVariablesItem); + addAll(copyMap, key, otherCopies); } + } + } - ItemProvider resolvedVariablesItem = new VariableContainer(setupTaskPerformer, "Resolved Variables", VARIABLE_GROUP_IMAGE); - EList<Object> resolvedVariablesItemChildren = resolvedVariablesItem.getChildren(); - List<VariableTask> resolvedVariables = setupTaskPerformer.getResolvedVariables(); - for (VariableTask contextVariableTask : sortVariables(resolvedVariables)) + // Copy over all the argument bindings to the overall copy map. + for (Map.Entry<Object, Set<Object>> entry : argumentBindingMap.entrySet()) + { + Object argument = entry.getKey(); + Set<Object> bindings = entry.getValue(); + for (Object binding : bindings) + { + Set<Object> copiedBindings = copyMap.get(binding); + if (copiedBindings != null) { - if (contextVariableTask.eContainer() == null && contextVariableTask.eResource() == null) + for (Object copiedBinding : copiedBindings) { - fakeResourceContents.add(contextVariableTask); + add(copyMap, argument, AdapterFactoryEditingDomain.unwrap(copiedBinding)); } - - resolvedVariablesItemChildren.add(contextVariableTask); - parents.put(contextVariableTask, resolvedVariablesItem); } + } + } - if (!resolvedVariablesItemChildren.isEmpty()) + for (SetupTask setupTask : triggeredSetupTasks) + { + String id = setupTask.getID(); + if (!StringUtil.isEmpty(id)) + { + for (EAttribute eAttribute : setupTask.eClass().getEAllAttributes()) { - branchItem.getChildren().add(resolvedVariablesItem); + if (eAttribute != SetupPackage.Literals.SETUP_TASK__ID && !eAttribute.isMany() && eAttribute.getEType().getInstanceClass() == String.class) + { + String variableName = id + "." + ExtendedMetaData.INSTANCE.getName(eAttribute); + VariableTask variable = variablesMap.get(variableName); + if (variable != null) + { + add(inducedIDVariables, setupTask, variable); + } + } } + } + } + } + + return result; + } + + private void gatherMacroChildren(Map<Object, Set<Object>> macroTaskMap, Map<Object, Set<Object>> argumentBindingMap, boolean handleParameters, String id, + Object children[]) + { + for (Object child : children) + { + gatherMacroChild(macroTaskMap, argumentBindingMap, handleParameters, id, child); + } + } - branchItem.getChildren().addAll(triggeredSetupTasks); + private void gatherMacroChild(Map<Object, Set<Object>> macroTaskMap, Map<Object, Set<Object>> argumentBindingMap, boolean handleParameters, String id, + Object object) + { + Object unwrappedObject = AdapterFactoryEditingDomain.unwrap(object); + if (unwrappedObject instanceof EObject) + { + EObject eObject = (EObject)unwrappedObject; + if (eObject.eResource() != null) + { + add(macroTaskMap, eObject, object); - for (SetupTask setupTask : triggeredSetupTasks) + Object[] children = selectionViewerContentProvider.getChildren(object); + if (eObject instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)eObject; + String macroTaskID = macroTask.getID(); + if (macroTaskID != null) { - parents.put(setupTask, branchItem); + String qualifiedTaskID = id == null ? macroTaskID : id + "*" + macroTaskID; + gatherMacroChildren(macroTaskMap, argumentBindingMap, false, qualifiedTaskID, children); } - - for (Map.Entry<EObject, EObject> entry : setupTaskPerformer.getCopyMap().entrySet()) + } + else if (eObject instanceof Parameter) + { + Parameter parameter = (Parameter)eObject; + String parameterName = parameter.getName(); + String qualifiedParameterName = SetupTaskPerformer.createQualifiedName(id, parameterName); + Set<Object> argumentBindings = macroTaskMap.get(qualifiedParameterName); + if (argumentBindings != null) { - add(copyMap, entry.getKey(), entry.getValue()); + addAll(argumentBindingMap, object, argumentBindings); } - add(copyMap, stream, branchItem); + add(macroTaskMap, qualifiedParameterName, parameter); + gatherMacroChildren(macroTaskMap, argumentBindingMap, false, id, children); + } + else if (eObject instanceof Argument) + { + Argument argument = (Argument)eObject; + Parameter parameter = argument.getParameter(); + if (parameter != null) + { + String parameterName = parameter.getName(); + String qualifiedParameterName = SetupTaskPerformer.createQualifiedName(id, parameterName); + add(macroTaskMap, qualifiedParameterName, argument); + } + gatherMacroChildren(macroTaskMap, argumentBindingMap, false, id, children); + } + else + { + gatherMacroChildren(macroTaskMap, argumentBindingMap, eObject instanceof Macro, id, children); } } - - add(copyMap, project, projectItem); } + } - for (Project subproject : project.getProjects()) + private <K, V> void add(Map<K, Set<V>> map, K key, V value) + { + Set<V> set = map.get(key); + if (set == null) { - projectItemChildren.add(getTriggeredTasks(subproject)); + set = new LinkedHashSet<V>(); + map.put(key, set); } - return projectItem; + set.add(value); } - private <K, V> void add(Map<K, Set<V>> map, K key, V value) + private <K, V> void addAll(Map<K, Set<V>> map, K key, Set<? extends V> values) { Set<V> set = map.get(key); if (set == null) { - set = new HashSet<V>(); + set = new LinkedHashSet<V>(); map.put(key, set); } - set.add(value); + + set.addAll(values); } @Override @@ -3425,7 +4305,11 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { super.setActionBars(actionBars); - actionBars.getToolBarManager().add(new Action("Show tasks for all triggers", IAction.AS_RADIO_BUTTON) + IToolBarManager toolBarManager = actionBars.getToolBarManager(); + + toolBarManager.add(previewAction); + + toolBarManager.add(new Action("Show tasks for all triggers", IAction.AS_RADIO_BUTTON) { { setChecked(true); @@ -3443,7 +4327,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr for (final Trigger trigger : Trigger.VALUES) { final String label = trigger.getLiteral().toLowerCase(); - actionBars.getToolBarManager().add(new Action("Show tasks for the " + label + " trigger", IAction.AS_RADIO_BUTTON) + toolBarManager.add(new Action("Show tasks for the " + label + " trigger", IAction.AS_RADIO_BUTTON) { { setImageDescriptor(ExtendedImageRegistry.INSTANCE.getImageDescriptor(SetupEditorPlugin.INSTANCE.getImage(StringUtil.cap(label) + "Trigger"))); @@ -3491,6 +4375,82 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr super.dispose(); } } + + protected class PreviewAction extends Action implements ISelectionChangedListener + { + final List<Scope> selectedPeviewableScopes = new ArrayList<Scope>(); + + final Map<Scope, Object> scopes = new LinkedHashMap<Scope, Object>(); + + public PreviewAction() + { + super("Preview Triggered Tasks", IAction.AS_CHECK_BOX); + setImageDescriptor(ExtendedImageRegistry.INSTANCE.getImageDescriptor(SetupEditorPlugin.INSTANCE.getImage("preview.png"))); + contentOutlineViewer.addPostSelectionChangedListener(this); + } + + public void selectionChanged(SelectionChangedEvent event) + { + update((ITreeSelection)event.getSelection()); + } + + protected void update() + { + update((ITreeSelection)contentOutlineViewer.getSelection()); + } + + protected void update(ITreeSelection treeSelection) + { + selectedPeviewableScopes.clear(); + scopes.clear(); + + for (TreePath treePath : treeSelection.getPaths()) + { + Object object = treePath.getLastSegment(); + Object unwrappedObject = AdapterFactoryEditingDomain.unwrap(object); + if (isPreviewableScope(unwrappedObject)) + { + Scope scope = (Scope)unwrappedObject; + selectedPeviewableScopes.add(scope); + scopes.put(scope, treePath); + } + } + + if (selectedPeviewableScopes.isEmpty()) + { + setEnabled(false); + setChecked(false); + } + else + { + List<Scope> previewableScopes = getPreviewableScopes(); + boolean disjoint = Collections.disjoint(selectedPeviewableScopes, previewableScopes); + setEnabled(true); + setChecked(!disjoint); + } + } + + @Override + public void run() + { + List<Scope> previewableScopes = getPreviewableScopes(); + if (!previewableScopes.containsAll(selectedPeviewableScopes)) + { + previewableScopes.addAll(selectedPeviewableScopes); + OutlinePreviewPage.this.update(2); + + for (Scope scope : selectedPeviewableScopes) + { + contentOutlineViewer.setExpandedState(scopes.get(scope), true); + } + } + else + { + previewableScopes.removeAll(selectedPeviewableScopes); + OutlinePreviewPage.this.update(2); + } + } + } } /** @@ -3573,28 +4533,90 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr */ public void handleContentOutlineSelection(ISelection selection) { - if (contentOutlinePage != null && selectionViewer != null && !selection.isEmpty() && selection instanceof IStructuredSelection) + if (contentOutlinePage != null && contentOutlineViewer.getControl().isFocusControl() && selectionViewer != null && !selection.isEmpty() + && selection instanceof IStructuredSelection) { Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator(); if (selectedElements.hasNext()) { Object selectedElement = selectedElements.next(); - ArrayList<Object> selectionList = new ArrayList<Object>(); + List<Object> selectionList = new ArrayList<Object>(); selectionList.addAll(contentOutlinePage.getOriginals(selectedElement)); while (selectedElements.hasNext()) { selectionList.addAll(contentOutlinePage.getOriginals(selectedElements.next())); } - TreeViewer oldSectionViewer = selectionViewer; - selectionViewer = null; - oldSectionViewer.setSelection(new StructuredSelection(selectionList)); - selectionViewer = oldSectionViewer; + if (!selectionList.isEmpty()) + { + TreeViewer oldSectionViewer = selectionViewer; + IStructuredSelection structuredSelection = createSelection(selectionList); + selectionViewer = null; + oldSectionViewer.setSelection(structuredSelection, true); + selectionViewer = oldSectionViewer; + } } } } + protected IStructuredSelection createSelection(List<Object> objects) + { + // If we're only showing the one resource we can just use a structured selection. + Object input = selectionViewer.getInput(); + if (input instanceof Resource) + { + return new StructuredSelection(objects); + } + + // All but the first resource use delegating wrappers for children, so we need to find those wrappers and create a tree path based on those. + List<TreePath> treePaths = new ArrayList<TreePath>(); + ITreeContentProvider treeContentProvider = (ITreeContentProvider)selectionViewer.getContentProvider(); + for (Object object : objects) + { + List<Object> path = new ArrayList<Object>(); + computePath(path, treeContentProvider, object); + treePaths.add(new TreePath(path.toArray())); + } + + return new TreeSelection(treePaths.toArray(new TreePath[treePaths.size()])); + } + + protected Object computePath(List<Object> path, ITreeContentProvider treeContentProvider, Object object) + { + if (object instanceof Resource) + { + path.add(object); + return object; + } + + Object parent = treeContentProvider.getParent(object); + if (parent == null) + { + // This is a root object, so we can't do anything else with it. + path.add(object); + return object; + } + + // Compute the past recursively for the parent, using the wrapper for the parent when determining children. + Object actualParent = computePath(path, treeContentProvider, parent); + if (actualParent != null) + { + Object[] children = treeContentProvider.getChildren(actualParent); + for (Object child : children) + { + // Find the corresponding wrapper, add it to the path, and return it. + if (child == object || child instanceof IWrapperItemProvider && ((IWrapperItemProvider)child).getValue() == object) + { + path.add(child); + return child; + } + } + } + + return null; + } + /** * This is for implementing {@link IEditorPart} and simply tests the command stack. * <!-- begin-user-doc --> @@ -3637,7 +4659,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { // Save only resources that have actually changed. // - final Map<Object, Object> saveOptions = new HashMap<Object, Object>(); + final Map<Object, Object> saveOptions = new LinkedHashMap<Object, Object>(); saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER); saveOptions.put(Resource.OPTION_LINE_DELIMITER, Resource.OPTION_LINE_DELIMITER_UNSPECIFIED); @@ -3830,7 +4852,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private void toggleInput(boolean forceResourceSet) { - ISelection selection = selectionViewer.getSelection(); + Object[] selection = ((IStructuredSelection)selectionViewer.getSelection()).toArray(); Object[] expandedElements = selectionViewer.getExpandedElements(); Object input = selectionViewer.getInput(); if (input instanceof ResourceSet) @@ -3862,7 +4884,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } selectionViewer.setExpandedElements(expandedElements); - selectionViewer.setSelection(selection); + selectionViewer.setSelection(new StructuredSelection(selection)); } /** @@ -4273,6 +5295,8 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private ToolItem editSetupItem; + private ToolItem showSetupItem; + private ToolItem showToolTipsItem; private ToolItem liveValidationItem; @@ -4293,7 +5317,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr private boolean editorSpecific; - private final Map<SetupEditor, DisposeListener> editorDisposeListeners = new HashMap<SetupEditor, DisposeListener>(); + private final Map<SetupEditor, DisposeListener> editorDisposeListeners = new LinkedHashMap<SetupEditor, DisposeListener>(); private ColumnViewerInformationControlToolTipSupport toolTipSupport; @@ -4648,6 +5672,35 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr new ToolItem(toolBar, SWT.SEPARATOR); + if (editorSpecific) + { + showSetupItem = createItem(SWT.PUSH, "locate_value", "Show in this Setup Editor", new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + Object unwrappedObject = ToolTipObject.unwrap(toolTipObject); + Object selectionViewerInput = setupEditor.selectionViewer.getInput(); + if (selectionViewerInput instanceof Resource) + { + if (unwrappedObject instanceof EObject) + { + EObject eObject = (EObject)unwrappedObject; + Resource resource = eObject.eResource(); + if (resource != selectionViewerInput) + { + setupEditor.toggleInput(true); + } + } + } + + IStructuredSelection structuredSelection = setupEditor.createSelection(Collections.singletonList(unwrappedObject)); + setupEditor.selectionViewer.setSelection(structuredSelection, true); + setupEditor.selectionViewer.getControl().setFocus(); + } + }); + } + editSetupItem = createItem(SWT.PUSH, "edit_setup", "Open in Setup Editor", new SelectionAdapter() { @Override @@ -4805,11 +5858,14 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { backwardItem.setEnabled(toolTipIndex > 0); forwardItem.setEnabled(toolTipIndex + 1 < toolTipObjects.size()); - editSetupItem.setEnabled(SetupActionBarContributor.getEditURI(ToolTipObject.unwrap(toolTipObject), !editorSpecific) != null); - editTextItem.setEnabled(SetupActionBarContributor.getEditURI(ToolTipObject.unwrap(toolTipObject), true) != null); + Object unwrappedToolTipObject = ToolTipObject.unwrap(toolTipObject); + editSetupItem.setEnabled(SetupActionBarContributor.getEditURI(unwrappedToolTipObject, !editorSpecific) != null); + boolean enabled = SetupActionBarContributor.getEditURI(unwrappedToolTipObject, true) != null; + editTextItem.setEnabled(enabled); if (editorSpecific) { + showSetupItem.setEnabled(enabled); showToolTipsItem.setSelection(SetupActionBarContributor.isShowTooltips()); liveValidationItem.setSelection(setupEditor.getActionBarContributor().isLiveValidation()); } @@ -4874,7 +5930,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } URI uri = originalURI; - Map<Object, Object> options = new HashMap<Object, Object>(); + Map<Object, Object> options = new LinkedHashMap<Object, Object>(); uri = ECFURIHandlerImpl.transform(uri, options); event.location = uri.toString(); diff --git a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupModelWizard.java b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupModelWizard.java index 2b8d3fc20..919953c77 100644 --- a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupModelWizard.java +++ b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupModelWizard.java @@ -981,4 +981,17 @@ public abstract class SetupModelWizard extends Wizard implements INewWizard templateUsagePage.addTemplate("Simple User Product", "@UserProductTemplate@.setup"); } } + + /** + * @author Ed Merks + */ + public static class NewMacroWizard extends SetupModelWizard + { + @Override + protected void configureTemplateUsagePage(TemplateUsagePage templateUsagePage) + { + templateUsagePage.setTitle(SetupEditorPlugin.INSTANCE.getString("_UI_SetupModelWizard_label7")); + templateUsagePage.addTemplate("Macro", "@MacroTemplate@.setup"); + } + } } diff --git a/plugins/org.eclipse.oomph.setup.editor/templates/@MacroTemplate@.setup b/plugins/org.eclipse.oomph.setup.editor/templates/@MacroTemplate@.setup new file mode 100644 index 000000000..1560d1254 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.editor/templates/@MacroTemplate@.setup @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<setup:Macro + xmi:version="2.0" + xmlns:xmi="http://www.omg.org/XMI" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:setup="http://www.eclipse.org/oomph/setup/1.0" + name="${macro.name}" + label="${macro.label}"> + <annotation> + <content + xsi:type="setup:CompoundTask" + id="template.variables" + name="@TemplateVariables@"> + <setupTask + xsi:type="setup:VariableTask" + name="macro.label" + value="My" + label="Macro Label"> + <description>The title case name of the macro, including spaces.</description> + </setupTask> + <setupTask + xsi:type="setup:VariableTask" + name="macro.name" + value="${macro.label|qualifiedName}" + label="Name"> + <description>The lower case name of the macro</description> + </setupTask> + <setupTask + xsi:type="setup:VariableTask" + type="TEXT" + name="macro.description" + value="The ${macro.label} macro provides cool stuff." + label="Macro Description"> + <description>An informative multi-line description of what the macro does.</description> + </setupTask> + <setupTask + xsi:type="setup:VariableTask" + type="CONTAINER" + name="setup.location" + label="Folder"> + <description>The workspace folder of the new macro setup model.</description> + </setupTask> + <setupTask + xsi:type="setup:VariableTask" + name="setup.filename" + value="${macro.label|camel}Macro.setup" + label="Filename"> + <description>The camel case filename of the new macro setup model.</description> + </setupTask> + </content> + </annotation> + <description>${macro.description}</description> +</setup:Macro> diff --git a/plugins/org.eclipse.oomph.setup.git/src/org/eclipse/oomph/setup/git/impl/GitCloneTaskImpl.java b/plugins/org.eclipse.oomph.setup.git/src/org/eclipse/oomph/setup/git/impl/GitCloneTaskImpl.java index 09be1911e..7999e47fd 100644 --- a/plugins/org.eclipse.oomph.setup.git/src/org/eclipse/oomph/setup/git/impl/GitCloneTaskImpl.java +++ b/plugins/org.eclipse.oomph.setup.git/src/org/eclipse/oomph/setup/git/impl/GitCloneTaskImpl.java @@ -956,6 +956,7 @@ public class GitCloneTaskImpl extends SetupTaskImpl implements GitCloneTask command.setURI(remoteURI); command.setRemote(remoteName); command.setCloneAllBranches(!restrictToCheckoutBranch); + command.setCloneSubmodules(recursive); if (restrictToCheckoutBranch) { command.setBranchesToClone(Collections.singleton(Constants.R_HEADS + checkoutBranch)); diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java index 1e5c0a123..bf1f2d3ca 100644 --- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java +++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java @@ -55,6 +55,7 @@ import org.eclipse.oomph.setup.ui.wizards.SetupWizardPage; import org.eclipse.oomph.ui.FilteredTreeWithoutWorkbench; import org.eclipse.oomph.ui.PersistentButton; import org.eclipse.oomph.ui.PersistentButton.DialogSettingsPersistence; +import org.eclipse.oomph.ui.StatusDialog; import org.eclipse.oomph.ui.ToolButton; import org.eclipse.oomph.ui.UIUtil; import org.eclipse.oomph.util.OS; @@ -67,6 +68,7 @@ import org.eclipse.emf.common.command.UnexecutableCommand; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.ui.dialogs.ResourceDialog; +import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.URI; @@ -873,7 +875,7 @@ public class ProductPage extends SetupWizardPage IStatus status = configurationProcessor.getStatus(); if (!status.isOK()) { - ErrorDialog.openError(getShell(), "Installation Problems", null, status); + new StatusDialog(getShell(), "Installation Problems", null, status, Diagnostic.ERROR).open(); } } }; diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java index 83f82ce67..6198bdc89 100644 --- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java +++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java @@ -35,6 +35,7 @@ import org.eclipse.oomph.setup.ui.wizards.ConfigurationProcessor; import org.eclipse.oomph.setup.ui.wizards.ProjectPage; import org.eclipse.oomph.setup.ui.wizards.SetupWizard.SelectionMemento; import org.eclipse.oomph.ui.ErrorDialog; +import org.eclipse.oomph.ui.StatusDialog; import org.eclipse.oomph.ui.UIUtil; import org.eclipse.oomph.util.ExceptionHandler; import org.eclipse.oomph.util.IOExceptionWithCause; @@ -44,6 +45,7 @@ import org.eclipse.oomph.util.OomphPlugin.Preference; import org.eclipse.oomph.util.PropertiesUtil; import org.eclipse.oomph.util.StringUtil; +import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; @@ -204,7 +206,7 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements IStatus status = configurationProcessor.getStatus(); if (!status.isOK()) { - org.eclipse.jface.dialogs.ErrorDialog.openError(getShell(), "Confirgation Problems", null, status); + new StatusDialog(getShell(), "Configuration Problems", null, status, Diagnostic.ERROR).open(); } } diff --git a/plugins/org.eclipse.oomph.setup.ui/icons/inline.gif b/plugins/org.eclipse.oomph.setup.ui/icons/inline.gif Binary files differnew file mode 100644 index 000000000..641de0a66 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.ui/icons/inline.gif diff --git a/plugins/org.eclipse.oomph.setup.ui/plugin.xml b/plugins/org.eclipse.oomph.setup.ui/plugin.xml index 1136ae09c..c4dc1c868 100644 --- a/plugins/org.eclipse.oomph.setup.ui/plugin.xml +++ b/plugins/org.eclipse.oomph.setup.ui/plugin.xml @@ -58,6 +58,18 @@ tooltip="Changes the enablement of the task"> </action> </objectContribution> + <objectContribution + id="org.eclipse.oomph.setup.contribution2" + objectClass="org.eclipse.oomph.setup.MacroTask"> + <action + class="org.eclipse.oomph.setup.ui.actions.InlineMacroTaskAction" + enablesFor="multiple" + id="org.eclipse.oomph.setup.InlineMacroTaskAction" + label="Inline" + style="push" + tooltip="Replace the macro task with an inline copy"> + </action> + </objectContribution> </extension> <extension diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java new file mode 100644 index 000000000..1de3ecb90 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.ui.actions; + +import org.eclipse.oomph.setup.CompoundTask; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer; +import org.eclipse.oomph.setup.ui.SetupUIPlugin; +import org.eclipse.oomph.util.StringUtil; + +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.command.ReplaceCommand; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.domain.EditingDomain; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Ed Merks + */ +public class InlineMacroTaskAction implements IObjectActionDelegate +{ + private final Set<MacroTask> macroTasks = new HashSet<MacroTask>(); + + public InlineMacroTaskAction() + { + } + + public void setActivePart(IAction action, IWorkbenchPart targetPart) + { + } + + public void selectionChanged(IAction action, ISelection selection) + { + macroTasks.clear(); + if (selection instanceof IStructuredSelection) + { + for (Object element : ((IStructuredSelection)selection).toArray()) + { + if (element instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)element; + Macro macro = macroTask.getMacro(); + if (macro != null && macroTask.getArguments().size() == macro.getParameters().size() && !StringUtil.isEmpty(macroTask.getID())) + { + macroTasks.add(macroTask); + } + } + } + } + + action.setEnabled(!macroTasks.isEmpty()); + action.setImageDescriptor(SetupUIPlugin.INSTANCE.getImageDescriptor("inline")); + } + + public void run(IAction action) + { + MacroTask firstTask = macroTasks.iterator().next(); + EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(firstTask); + CompoundCommand compoundCommand = new CompoundCommand("Inline"); + + EObject rootContainer = EcoreUtil.getRootContainer(firstTask, true); + EList<Adapter> eAdapters = rootContainer.eAdapters(); + ECrossReferenceAdapter eCrossReferenceAdapter = new ECrossReferenceAdapter(); + eAdapters.add(eCrossReferenceAdapter); + + for (MacroTask macroTask : macroTasks) + { + CompoundTask replacement = SetupTaskPerformer.expand(macroTask); + Collection<EStructuralFeature.Setting> inverseReferences = eCrossReferenceAdapter.getInverseReferences(macroTask); + for (EStructuralFeature.Setting setting : inverseReferences) + { + compoundCommand + .append(ReplaceCommand.create(domain, setting.getEObject(), setting.getEStructuralFeature(), macroTask, Collections.singleton(replacement))); + } + } + + eAdapters.remove(eCrossReferenceAdapter); + + domain.getCommandStack().execute(compoundCommand); + } +} diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ConfigurationProcessor.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ConfigurationProcessor.java index fbbd42e37..1fe6f7a07 100644 --- a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ConfigurationProcessor.java +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ConfigurationProcessor.java @@ -23,6 +23,7 @@ import org.eclipse.oomph.setup.ProjectCatalog; import org.eclipse.oomph.setup.ProjectContainer; import org.eclipse.oomph.setup.Scope; 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.Stream; @@ -35,9 +36,12 @@ import org.eclipse.oomph.util.StringUtil; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMIException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; @@ -152,18 +156,7 @@ public class ConfigurationProcessor { if (configuration == null && setupWizard.isSimple()) { - StringBuilder uris = new StringBuilder(); - for (Resource resource : setupWizard.getUnappliedConfigurationResources()) - { - if (uris.length() != 0) - { - uris.append(' '); - } - - uris.append(resource.getURI()); - } - - installationStatus.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "No configuration could be loaded " + uris)); + installationStatus.add(createResourceStatus(setupWizard.getUnappliedConfigurationResources(), SetupPackage.Literals.CONFIGURATION)); return false; } @@ -326,13 +319,7 @@ public class ConfigurationProcessor { if (configuration == null && !setupWizard.isSimple()) { - StringBuilder uris = new StringBuilder(); - for (Resource resource : setupWizard.getUnappliedConfigurationResources()) - { - uris.append(resource.getURI()); - } - - workspaceStatus.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "No configuration could be loaded " + uris)); + workspaceStatus.add(createResourceStatus(setupWizard.getUnappliedConfigurationResources(), SetupPackage.Literals.CONFIGURATION)); return false; } @@ -345,6 +332,66 @@ public class ConfigurationProcessor return true; } + protected IStatus createResourceStatus(Collection<? extends Resource> resources, EClass expectedEClass) + { + StringBuilder uris = new StringBuilder(); + List<IStatus> childStatuses = new ArrayList<IStatus>(); + for (Resource resource : resources) + { + if (uris.length() != 0) + { + uris.append(' '); + } + + uris.append(resource.getURI()); + + EList<Resource.Diagnostic> errors = resource.getErrors(); + if (errors.isEmpty()) + { + EList<EObject> contents = resource.getContents(); + if (contents.isEmpty()) + { + childStatuses.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "The resource is empty")); + } + else + { + childStatuses.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "The resource contains a " + contents.get(0).eClass().getName())); + } + } + else + { + for (Resource.Diagnostic diagnostic : errors) + { + String message = diagnostic.getMessage(); + Throwable throwable = null; + if (diagnostic instanceof Throwable) + { + throwable = (Throwable)diagnostic; + if (throwable instanceof XMIException) + { + Throwable cause = throwable.getCause(); + if (cause != null) + { + XMIException xmiException = (XMIException)throwable; + message = cause.getMessage(); + int line = xmiException.getLine(); + if (line != 0) + { + message += " (" + line + ", " + xmiException.getColumn() + ")"; + } + } + } + } + + childStatuses.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, message, throwable)); + } + } + } + + return new MultiStatus(SetupUIPlugin.PLUGIN_ID, 0, childStatuses.toArray(new IStatus[childStatuses.size()]), + "No " + expectedEClass.getName() + " could be loaded from " + uris, null); + } + protected boolean handleWorkspace() { if (setupWizard.isSimple()) diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java index 2a1658ac5..17de2cc5e 100644 --- a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java @@ -43,6 +43,7 @@ import org.eclipse.oomph.setup.ui.wizards.SetupWizard.IndexLoader; import org.eclipse.oomph.setup.ui.wizards.SetupWizard.SelectionMemento; import org.eclipse.oomph.ui.ButtonAnimator; import org.eclipse.oomph.ui.FilteredTreeWithoutWorkbench; +import org.eclipse.oomph.ui.StatusDialog; import org.eclipse.oomph.ui.UIUtil; import org.eclipse.oomph.util.OS; import org.eclipse.oomph.util.StringUtil; @@ -57,6 +58,7 @@ import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.ui.dialogs.ResourceDialog; import org.eclipse.emf.common.ui.dialogs.WorkspaceResourceDialog; import org.eclipse.emf.common.ui.viewer.ColumnViewerInformationControlToolTipSupport; +import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.URI; @@ -1053,7 +1055,7 @@ public class ProjectPage extends SetupWizardPage IStatus status = configurationProcessor.getStatus(); if (!status.isOK()) { - ErrorDialog.openError(getShell(), "Workspace Problems", null, status); + new StatusDialog(getShell(), "Workspace Problems", null, status, Diagnostic.ERROR).open(); } } }; @@ -1895,6 +1897,18 @@ public class ProjectPage extends SetupWizardPage } @Override + protected boolean isWrappingNeeded(Object object) + { + return false; + } + + @Override + protected Object createWrapper(EObject object, EStructuralFeature feature, Object value, int index) + { + return null; + } + + @Override public void notifyChanged(Notification notification) { switch (notification.getFeatureID(Workspace.class)) diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/VariablePage.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/VariablePage.java index b8b5e223d..72ba1c03d 100644 --- a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/VariablePage.java +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/VariablePage.java @@ -271,7 +271,7 @@ public class VariablePage extends SetupWizardPage implements SetupPrompter boolean isUsedInActualTriggeredTask = false; for (SetupTask setupTask : setupTaskPerformer.getTriggeredSetupTasks()) { - if (setupTask.getTriggers().contains(trigger) && setupTaskPerformer.isVariableUsed(name, setupTask, true)) + if (setupTask.getTriggers().contains(trigger) && SetupTaskPerformer.isVariableUsed(name, setupTask, true)) { isUsedInActualTriggeredTask = true; break; @@ -548,9 +548,9 @@ public class VariablePage extends SetupWizardPage implements SetupPrompter @Override protected Dialog createDialog() { - return createDialog(getShell(), SETUP_TASK_ANALYSIS_TITLE, null, - "Analyzing the needed setup tasks has taken more than " + (System.currentTimeMillis() - getStart()) / 1000 - + " seconds. The Next button will be disabled, though animated, until it completes. You may continue to modify the values of the variables.", + return createDialog(getShell(), SETUP_TASK_ANALYSIS_TITLE, null, "Analyzing the needed setup tasks has taken more than " + + (System.currentTimeMillis() - getStart()) / 1000 + + " seconds. The Next button will be disabled, though animated, until it completes. You may continue to modify the values of the variables.", MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0); } diff --git a/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF index 7f8ed310d..37c8b7632 100644 --- a/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF @@ -12,7 +12,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)", org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.edit;bundle-version="[2.10.0,3.0.0)", - org.eclipse.oomph.base;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.base;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, org.eclipse.emf.ecore;bundle-version="[2.10.0,3.0.0)";visibility:=reexport Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.oomph.setup/model/Setup.ecore b/plugins/org.eclipse.oomph.setup/model/Setup.ecore index 505551e8f..c5afc9434 100644 --- a/plugins/org.eclipse.oomph.setup/model/Setup.ecore +++ b/plugins/org.eclipse.oomph.setup/model/Setup.ecore @@ -28,7 +28,9 @@ changeable="false" volatile="true" transient="true" derived="true"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="excludedTriggers" lowerBound="1" eType="#//TriggerSet" defaultValueLiteral=""/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabled" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabled" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> + </eStructuralFeatures> <eStructuralFeatures xsi:type="ecore:EReference" name="predecessors" upperBound="-1" eType="#//SetupTask"> <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> @@ -63,6 +65,7 @@ <eClassifiers xsi:type="ecore:EClass" name="Scope" abstract="true" eSuperTypes="#//SetupTaskContainer"> <eOperations name="getParentScope" eType="#//Scope"/> <eOperations name="getType" lowerBound="1" eType="#//ScopeType"/> + <eOperations name="getQualifiedLabel" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType ../../org.eclipse.oomph.base/model/Base.ecore#//Text"> @@ -337,22 +340,27 @@ </eClassifiers> <eClassifiers xsi:type="ecore:EClass" name="VariableTask" eSuperTypes="#//SetupTask"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" lowerBound="1" eType="#//VariableType" - defaultValueLiteral="STRING"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"> + defaultValueLiteral="STRING"> <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="storePromptedValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" volatile="true" transient="true" defaultValueLiteral="true" derived="true"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel"> <details key="suppressedSetVisibility" value="true"/> <details key="suppressedGetVisibility" value="true"/> </eAnnotations> </eStructuralFeatures> <eStructuralFeatures xsi:type="ecore:EAttribute" name="storageURI" eType="ecore:EDataType ../../org.eclipse.oomph.base/model/Base.ecore#//URI" - defaultValueLiteral="scope://"/> - <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + defaultValueLiteral="scope://"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> + </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> + </eStructuralFeatures> <eStructuralFeatures xsi:type="ecore:EReference" name="choices" upperBound="-1" eType="#//VariableChoice" containment="true"> <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> @@ -472,6 +480,52 @@ <eStructuralFeatures xsi:type="ecore:EReference" name="value" upperBound="-1" eType="#//Installation"/> </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Macro" eSuperTypes="#//Scope"> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore"> + <details key="constraints" value="NoRecursion"/> + </eAnnotations> + <eStructuralFeatures xsi:type="ecore:EReference" name="logicalContainer" eType="#//MacroTask" + transient="true" resolveProxies="false"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="parameters" upperBound="-1" + eType="#//Parameter" containment="true" resolveProxies="false" eKeys="#//Parameter/name"> + <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> + <details key="kind" value="element"/> + <details key="name" value="parameter"/> + </eAnnotations> + </eStructuralFeatures> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Parameter" eSuperTypes="../../org.eclipse.oomph.base/model/Base.ecore#//ModelElement"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"> + <eAnnotations source="http://www.eclipse.org/oomph/setup/NoExpand"/> + </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType ../../org.eclipse.oomph.base/model/Base.ecore#//Text"> + <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> + <details key="kind" value="element"/> + </eAnnotations> + </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="MacroTask" eSuperTypes="#//SetupTask"> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore"> + <details key="constraints" value="IDRequired ArgumentsCorrespondToParameters"/> + </eAnnotations> + <eStructuralFeatures xsi:type="ecore:EReference" name="arguments" upperBound="-1" + eType="#//Argument" containment="true" resolveProxies="false"> + <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"> + <details key="kind" value="element"/> + <details key="name" value="argument"/> + </eAnnotations> + </eStructuralFeatures> + <eStructuralFeatures xsi:type="ecore:EReference" name="macro" lowerBound="1" eType="#//Macro"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Argument" eSuperTypes="../../org.eclipse.oomph.base/model/Base.ecore#//ModelElement"> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore"> + <details key="constraints" value="ConsistentParameterBinding"/> + </eAnnotations> + <eStructuralFeatures xsi:type="ecore:EReference" name="parameter" lowerBound="1" + eType="#//Parameter"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + </eClassifiers> <eClassifiers xsi:type="ecore:EEnum" name="ScopeType"> <eLiterals name="None"/> <eLiterals name="ProductCatalog" value="1"/> @@ -483,6 +537,7 @@ <eLiterals name="Installation" value="7"/> <eLiterals name="Workspace" value="8"/> <eLiterals name="User" value="9"/> + <eLiterals name="Macro" value="10"/> </eClassifiers> <eClassifiers xsi:type="ecore:EEnum" name="Trigger"> <eLiterals name="BOOTSTRAP"/> diff --git a/plugins/org.eclipse.oomph.setup/model/Setup.genmodel b/plugins/org.eclipse.oomph.setup/model/Setup.genmodel index f0655535f..770cec5f2 100644 --- a/plugins/org.eclipse.oomph.setup/model/Setup.genmodel +++ b/plugins/org.eclipse.oomph.setup/model/Setup.genmodel @@ -25,6 +25,7 @@ <genEnumLiterals ecoreEnumLiteral="Setup.ecore#//ScopeType/Installation"/> <genEnumLiterals ecoreEnumLiteral="Setup.ecore#//ScopeType/Workspace"/> <genEnumLiterals ecoreEnumLiteral="Setup.ecore#//ScopeType/User"/> + <genEnumLiterals ecoreEnumLiteral="Setup.ecore#//ScopeType/Macro"/> </genEnums> <genEnums typeSafeEnumCompatible="false" ecoreEnum="Setup.ecore#//Trigger"> <genEnumLiterals ecoreEnumLiteral="Setup.ecore#//Trigger/BOOTSTRAP"/> @@ -96,6 +97,7 @@ <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//Scope/qualifiedName"/> <genOperations ecoreOperation="Setup.ecore#//Scope/getParentScope"/> <genOperations ecoreOperation="Setup.ecore#//Scope/getType"/> + <genOperations ecoreOperation="Setup.ecore#//Scope/getQualifiedLabel"/> </genClasses> <genClasses ecoreClass="Setup.ecore#//Index"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//Index/name"/> @@ -167,14 +169,16 @@ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Setup.ecore#//LocationCatalog/workspaces"/> </genClasses> <genClasses ecoreClass="Setup.ecore#//Installation"> - <genFeatures createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Setup.ecore#//Installation/productVersion"/> + <genFeatures children="true" createChild="false" propertySortChoices="true" + ecoreFeature="ecore:EReference Setup.ecore#//Installation/productVersion"/> </genClasses> <genClasses ecoreClass="Setup.ecore#//InstallationTask" labelFeature="#//setup/InstallationTask/location"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//InstallationTask/location"/> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//InstallationTask/relativeProductFolder"/> </genClasses> <genClasses ecoreClass="Setup.ecore#//Workspace"> - <genFeatures createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Setup.ecore#//Workspace/streams"/> + <genFeatures children="true" createChild="false" propertySortChoices="true" + ecoreFeature="ecore:EReference Setup.ecore#//Workspace/streams"/> </genClasses> <genClasses ecoreClass="Setup.ecore#//WorkspaceTask" labelFeature="#//setup/WorkspaceTask/location"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//WorkspaceTask/location"/> @@ -265,5 +269,25 @@ <genFeatures children="true" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Setup.ecore#//WorkspaceToInstallationsMapEntry/value"/> </genClasses> + <genClasses ecoreClass="Setup.ecore#//Macro"> + <genFeatures property="None" notify="false" createChild="false" propertySortChoices="true" + ecoreFeature="ecore:EReference Setup.ecore#//Macro/logicalContainer"/> + <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Setup.ecore#//Macro/parameters"/> + </genClasses> + <genClasses ecoreClass="Setup.ecore#//Parameter"> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//Parameter/name"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//Parameter/description"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//Parameter/defaultValue"/> + </genClasses> + <genClasses ecoreClass="Setup.ecore#//MacroTask"> + <genFeatures property="None" children="true" createChild="true" propertyMultiLine="true" + ecoreFeature="ecore:EReference Setup.ecore#//MacroTask/arguments"/> + <genFeatures children="true" createChild="false" propertySortChoices="true" + ecoreFeature="ecore:EReference Setup.ecore#//MacroTask/macro"/> + </genClasses> + <genClasses ecoreClass="Setup.ecore#//Argument"> + <genFeatures createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Setup.ecore#//Argument/parameter"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Setup.ecore#//Argument/value"/> + </genClasses> </genPackages> </genmodel:GenModel> diff --git a/plugins/org.eclipse.oomph.setup/plugin.properties b/plugins/org.eclipse.oomph.setup/plugin.properties index 9424a3d13..1d90440c1 100644 --- a/plugins/org.eclipse.oomph.setup/plugin.properties +++ b/plugins/org.eclipse.oomph.setup/plugin.properties @@ -12,3 +12,10 @@ providerName = Eclipse Oomph Project _UI_Setup_content_type = Oomph Setup File + +_UI_MacroTaskDRequired_diagnostic = A macro task must specify an ID +_UI_ArgumentParameterAlreadyBound_diagnostic = An argument may not bind to a parameter that is already bound +_UI_ArgumentParameterOutOfScope_diagnostic = An argument may only refer to a parameter of the containing macro expansion's macro +_UI_ArgumentValueMustBeSpecified_diagnostic = An argument bound to a parameter without a default value must specify a value +_UI_MacroTaskMissingArgument_diagnostic = Arguments must be specified for the parameter(s) {0} +_UI_MacroNoRecursion_diagnostic = A macro must not recursively expand so the cycle {0} is invalid diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/AnnotationConstants.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/AnnotationConstants.java index 5d6fd5a3b..c67f42b2d 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/AnnotationConstants.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/AnnotationConstants.java @@ -17,8 +17,6 @@ public final class AnnotationConstants { public static final String ANNOTATION_BRANDING_INFO = "http://www.eclipse.org/oomph/setup/BrandingInfo"; - public static final String KEY_URI = "uri"; - public static final String KEY_IMAGE_URI = "imageURI"; public static final String KEY_README_PATH = "readmePath"; @@ -29,6 +27,8 @@ public final class AnnotationConstants public static final String ANNOTATION_STATS_SENDING = "http://www.eclipse.org/oomph/setup/StatsSending"; + public static final String KEY_URI = "uri"; + public static final String ANNOTATION_USER_PREFERENCES = "http://www.eclipse.org/oomph/setup/UserPreferences"; public static final String ANNOTATION_INHERITED_CHOICES = "http://www.eclipse.org/oomph/setup/InheritedChoices"; diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Argument.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Argument.java new file mode 100644 index 000000000..3360ffbc4 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Argument.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup; + +import org.eclipse.oomph.base.ModelElement; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Argument</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.Argument#getParameter <em>Parameter</em>}</li> + * <li>{@link org.eclipse.oomph.setup.Argument#getValue <em>Value</em>}</li> + * </ul> + * + * @see org.eclipse.oomph.setup.SetupPackage#getArgument() + * @model annotation="http://www.eclipse.org/emf/2002/Ecore constraints='ConsistentParameterBinding'" + * @generated + */ +public interface Argument extends ModelElement +{ + /** + * Returns the value of the '<em><b>Parameter</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Parameter</em>' reference. + * @see #setParameter(Parameter) + * @see org.eclipse.oomph.setup.SetupPackage#getArgument_Parameter() + * @model required="true" + * @generated + */ + Parameter getParameter(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.Argument#getParameter <em>Parameter</em>}' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Parameter</em>' reference. + * @see #getParameter() + * @generated + */ + void setParameter(Parameter value); + + /** + * Returns the value of the '<em><b>Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Value</em>' attribute. + * @see #setValue(String) + * @see org.eclipse.oomph.setup.SetupPackage#getArgument_Value() + * @model + * @generated + */ + String getValue(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.Argument#getValue <em>Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Value</em>' attribute. + * @see #getValue() + * @generated + */ + void setValue(String value); + +} // Argument diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Macro.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Macro.java new file mode 100644 index 000000000..a4918f9a3 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Macro.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup; + +import org.eclipse.emf.common.util.EList; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Macro</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.Macro#getLogicalContainer <em>Logical Container</em>}</li> + * <li>{@link org.eclipse.oomph.setup.Macro#getParameters <em>Parameters</em>}</li> + * </ul> + * + * @see org.eclipse.oomph.setup.SetupPackage#getMacro() + * @model annotation="http://www.eclipse.org/emf/2002/Ecore constraints='NoRecursion'" + * @generated + */ +public interface Macro extends Scope +{ + /** + * Returns the value of the '<em><b>Logical Container</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Logical Container</em>' reference. + * @see #setLogicalContainer(MacroTask) + * @see org.eclipse.oomph.setup.SetupPackage#getMacro_LogicalContainer() + * @model resolveProxies="false" transient="true" + * @generated + */ + MacroTask getLogicalContainer(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.Macro#getLogicalContainer <em>Logical Container</em>}' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Logical Container</em>' reference. + * @see #getLogicalContainer() + * @generated + */ + void setLogicalContainer(MacroTask value); + + /** + * Returns the value of the '<em><b>Parameters</b></em>' containment reference list. + * The list contents are of type {@link org.eclipse.oomph.setup.Parameter}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Parameters</em>' containment reference list. + * @see org.eclipse.oomph.setup.SetupPackage#getMacro_Parameters() + * @model containment="true" keys="name" + * extendedMetaData="kind='element' name='parameter'" + * @generated + */ + EList<Parameter> getParameters(); + +} // Macro diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/MacroTask.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/MacroTask.java new file mode 100644 index 000000000..1a7c71e55 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/MacroTask.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup; + +import org.eclipse.emf.common.util.EList; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Macro Task</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.MacroTask#getArguments <em>Arguments</em>}</li> + * <li>{@link org.eclipse.oomph.setup.MacroTask#getMacro <em>Macro</em>}</li> + * </ul> + * + * @see org.eclipse.oomph.setup.SetupPackage#getMacroTask() + * @model annotation="http://www.eclipse.org/emf/2002/Ecore constraints='IDRequired ArgumentsCorrespondToParameters'" + * @generated + */ +public interface MacroTask extends SetupTask +{ + /** + * Returns the value of the '<em><b>Arguments</b></em>' containment reference list. + * The list contents are of type {@link org.eclipse.oomph.setup.Argument}. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Arguments</em>' containment reference list. + * @see org.eclipse.oomph.setup.SetupPackage#getMacroTask_Arguments() + * @model containment="true" + * extendedMetaData="kind='element' name='argument'" + * @generated + */ + EList<Argument> getArguments(); + + /** + * Returns the value of the '<em><b>Macro</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Macro</em>' reference. + * @see #setMacro(Macro) + * @see org.eclipse.oomph.setup.SetupPackage#getMacroTask_Macro() + * @model required="true" + * @generated + */ + Macro getMacro(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.MacroTask#getMacro <em>Macro</em>}' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Macro</em>' reference. + * @see #getMacro() + * @generated + */ + void setMacro(Macro value); + +} // MacroTask diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Parameter.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Parameter.java new file mode 100644 index 000000000..b8389d4e9 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Parameter.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup; + +import org.eclipse.oomph.base.ModelElement; + +/** + * <!-- begin-user-doc --> + * A representation of the model object '<em><b>Parameter</b></em>'. + * <!-- end-user-doc --> + * + * <p> + * The following features are supported: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.Parameter#getName <em>Name</em>}</li> + * <li>{@link org.eclipse.oomph.setup.Parameter#getDescription <em>Description</em>}</li> + * <li>{@link org.eclipse.oomph.setup.Parameter#getDefaultValue <em>Default Value</em>}</li> + * </ul> + * + * @see org.eclipse.oomph.setup.SetupPackage#getParameter() + * @model + * @generated + */ +public interface Parameter extends ModelElement +{ + /** + * Returns the value of the '<em><b>Name</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Name</em>' attribute. + * @see #setName(String) + * @see org.eclipse.oomph.setup.SetupPackage#getParameter_Name() + * @model required="true" + * annotation="http://www.eclipse.org/oomph/setup/NoExpand" + * @generated + */ + String getName(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.Parameter#getName <em>Name</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Name</em>' attribute. + * @see #getName() + * @generated + */ + void setName(String value); + + /** + * Returns the value of the '<em><b>Description</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Description</em>' attribute. + * @see #setDescription(String) + * @see org.eclipse.oomph.setup.SetupPackage#getParameter_Description() + * @model dataType="org.eclipse.oomph.base.Text" + * extendedMetaData="kind='element'" + * @generated + */ + String getDescription(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.Parameter#getDescription <em>Description</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Description</em>' attribute. + * @see #getDescription() + * @generated + */ + void setDescription(String value); + + /** + * Returns the value of the '<em><b>Default Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the value of the '<em>Default Value</em>' attribute. + * @see #setDefaultValue(String) + * @see org.eclipse.oomph.setup.SetupPackage#getParameter_DefaultValue() + * @model + * @generated + */ + String getDefaultValue(); + + /** + * Sets the value of the '{@link org.eclipse.oomph.setup.Parameter#getDefaultValue <em>Default Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @param value the new value of the '<em>Default Value</em>' attribute. + * @see #getDefaultValue() + * @generated + */ + void setDefaultValue(String value); + +} // Parameter diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Scope.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Scope.java index c701cb227..66ad081b7 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Scope.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/Scope.java @@ -141,4 +141,12 @@ public interface Scope extends SetupTaskContainer */ ScopeType getType(); + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @model kind="operation" + * @generated + */ + String getQualifiedLabel(); + } // Scope diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/ScopeType.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/ScopeType.java index bf9accf1c..070c91d55 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/ScopeType.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/ScopeType.java @@ -116,7 +116,16 @@ public enum ScopeType implements Enumerator * @generated * @ordered */ - USER(9, "User", "User"); + USER(9, "User", "User"), + /** + * The '<em><b>Macro</b></em>' literal object. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #MACRO_VALUE + * @generated + * @ordered + */ + MACRO(10, "Macro", "Macro"); /** * The '<em><b>None</b></em>' literal value. @@ -269,13 +278,24 @@ public enum ScopeType implements Enumerator public static final int USER_VALUE = 9; /** + * The '<em><b>Macro</b></em>' literal value. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #MACRO + * @model name="Macro" + * @generated + * @ordered + */ + public static final int MACRO_VALUE = 10; + + /** * An array of all the '<em><b>Scope Type</b></em>' enumerators. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ private static final ScopeType[] VALUES_ARRAY = new ScopeType[] { NONE, PRODUCT_CATALOG, PRODUCT, PRODUCT_VERSION, PROJECT_CATALOG, PROJECT, STREAM, - INSTALLATION, WORKSPACE, USER, }; + INSTALLATION, WORKSPACE, USER, MACRO, }; /** * A public read-only list of all the '<em><b>Scope Type</b></em>' enumerators. @@ -359,6 +379,8 @@ public enum ScopeType implements Enumerator return WORKSPACE; case USER_VALUE: return USER; + case MACRO_VALUE: + return MACRO; } return null; } diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupFactory.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupFactory.java index 7062df433..592cda275 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupFactory.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupFactory.java @@ -195,6 +195,42 @@ public interface SetupFactory extends EFactory TextModification createTextModification(); /** + * Returns a new object of class '<em>Macro</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return a new object of class '<em>Macro</em>'. + * @generated + */ + Macro createMacro(); + + /** + * Returns a new object of class '<em>Parameter</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return a new object of class '<em>Parameter</em>'. + * @generated + */ + Parameter createParameter(); + + /** + * Returns a new object of class '<em>Macro Task</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return a new object of class '<em>Macro Task</em>'. + * @generated + */ + MacroTask createMacroTask(); + + /** + * Returns a new object of class '<em>Argument</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return a new object of class '<em>Argument</em>'. + * @generated + */ + Argument createArgument(); + + /** * Returns a new object of class '<em>String Substitution Task</em>'. * <!-- begin-user-doc --> * <!-- end-user-doc --> diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupPackage.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupPackage.java index 09e09c028..9d7814e32 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupPackage.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupPackage.java @@ -3374,6 +3374,325 @@ public interface SetupPackage extends EPackage int WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY_FEATURE_COUNT = 2; /** + * The meta object id for the '{@link org.eclipse.oomph.setup.impl.MacroImpl <em>Macro</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.MacroImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getMacro() + * @generated + */ + int MACRO = 36; + + /** + * The feature id for the '<em><b>Annotations</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__ANNOTATIONS = SCOPE__ANNOTATIONS; + + /** + * The feature id for the '<em><b>Setup Tasks</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__SETUP_TASKS = SCOPE__SETUP_TASKS; + + /** + * The feature id for the '<em><b>Name</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__NAME = SCOPE__NAME; + + /** + * The feature id for the '<em><b>Label</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__LABEL = SCOPE__LABEL; + + /** + * The feature id for the '<em><b>Description</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__DESCRIPTION = SCOPE__DESCRIPTION; + + /** + * The feature id for the '<em><b>Qualified Name</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__QUALIFIED_NAME = SCOPE__QUALIFIED_NAME; + + /** + * The feature id for the '<em><b>Logical Container</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__LOGICAL_CONTAINER = SCOPE_FEATURE_COUNT + 0; + + /** + * The feature id for the '<em><b>Parameters</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO__PARAMETERS = SCOPE_FEATURE_COUNT + 1; + + /** + * The number of structural features of the '<em>Macro</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_FEATURE_COUNT = SCOPE_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link org.eclipse.oomph.setup.impl.ParameterImpl <em>Parameter</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.ParameterImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getParameter() + * @generated + */ + int PARAMETER = 37; + + /** + * The feature id for the '<em><b>Annotations</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int PARAMETER__ANNOTATIONS = BasePackage.MODEL_ELEMENT__ANNOTATIONS; + + /** + * The feature id for the '<em><b>Name</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int PARAMETER__NAME = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 0; + + /** + * The feature id for the '<em><b>Description</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int PARAMETER__DESCRIPTION = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 1; + + /** + * The feature id for the '<em><b>Default Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int PARAMETER__DEFAULT_VALUE = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 2; + + /** + * The number of structural features of the '<em>Parameter</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int PARAMETER_FEATURE_COUNT = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 3; + + /** + * The meta object id for the '{@link org.eclipse.oomph.setup.impl.MacroTaskImpl <em>Macro Task</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.MacroTaskImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getMacroTask() + * @generated + */ + int MACRO_TASK = 38; + + /** + * The feature id for the '<em><b>Annotations</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__ANNOTATIONS = SETUP_TASK__ANNOTATIONS; + + /** + * The feature id for the '<em><b>ID</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__ID = SETUP_TASK__ID; + + /** + * The feature id for the '<em><b>Description</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__DESCRIPTION = SETUP_TASK__DESCRIPTION; + + /** + * The feature id for the '<em><b>Scope Type</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__SCOPE_TYPE = SETUP_TASK__SCOPE_TYPE; + + /** + * The feature id for the '<em><b>Excluded Triggers</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__EXCLUDED_TRIGGERS = SETUP_TASK__EXCLUDED_TRIGGERS; + + /** + * The feature id for the '<em><b>Disabled</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__DISABLED = SETUP_TASK__DISABLED; + + /** + * The feature id for the '<em><b>Predecessors</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__PREDECESSORS = SETUP_TASK__PREDECESSORS; + + /** + * The feature id for the '<em><b>Successors</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__SUCCESSORS = SETUP_TASK__SUCCESSORS; + + /** + * The feature id for the '<em><b>Restrictions</b></em>' reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__RESTRICTIONS = SETUP_TASK__RESTRICTIONS; + + /** + * The feature id for the '<em><b>Filter</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__FILTER = SETUP_TASK__FILTER; + + /** + * The feature id for the '<em><b>Arguments</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__ARGUMENTS = SETUP_TASK_FEATURE_COUNT + 0; + + /** + * The feature id for the '<em><b>Macro</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK__MACRO = SETUP_TASK_FEATURE_COUNT + 1; + + /** + * The number of structural features of the '<em>Macro Task</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int MACRO_TASK_FEATURE_COUNT = SETUP_TASK_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link org.eclipse.oomph.setup.impl.ArgumentImpl <em>Argument</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.ArgumentImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getArgument() + * @generated + */ + int ARGUMENT = 39; + + /** + * The feature id for the '<em><b>Annotations</b></em>' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ARGUMENT__ANNOTATIONS = BasePackage.MODEL_ELEMENT__ANNOTATIONS; + + /** + * The feature id for the '<em><b>Parameter</b></em>' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ARGUMENT__PARAMETER = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 0; + + /** + * The feature id for the '<em><b>Value</b></em>' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ARGUMENT__VALUE = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 1; + + /** + * The number of structural features of the '<em>Argument</em>' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + * @ordered + */ + int ARGUMENT_FEATURE_COUNT = BasePackage.MODEL_ELEMENT_FEATURE_COUNT + 2; + + /** * The meta object id for the '{@link org.eclipse.oomph.setup.ScopeType <em>Scope Type</em>}' enum. * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -3381,7 +3700,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getScopeType() * @generated */ - int SCOPE_TYPE = 36; + int SCOPE_TYPE = 40; /** * The meta object id for the '{@link org.eclipse.oomph.setup.Trigger <em>Trigger</em>}' enum. @@ -3391,7 +3710,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getTrigger() * @generated */ - int TRIGGER = 37; + int TRIGGER = 41; /** * The meta object id for the '{@link org.eclipse.oomph.setup.VariableType <em>Variable Type</em>}' enum. @@ -3401,7 +3720,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getVariableType() * @generated */ - int VARIABLE_TYPE = 38; + int VARIABLE_TYPE = 42; /** * The meta object id for the '{@link org.eclipse.oomph.setup.UnsignedPolicy <em>Unsigned Policy</em>}' enum. @@ -3411,7 +3730,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getUnsignedPolicy() * @generated */ - int UNSIGNED_POLICY = 39; + int UNSIGNED_POLICY = 43; /** * The meta object id for the '<em>License Info</em>' data type. @@ -3421,7 +3740,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getLicenseInfo() * @generated */ - int LICENSE_INFO = 41; + int LICENSE_INFO = 45; /** * The meta object id for the '<em>Filter</em>' data type. @@ -3431,7 +3750,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getFilter() * @generated */ - int FILTER = 42; + int FILTER = 46; /** * Returns the meta object for class '{@link org.eclipse.oomph.setup.Index <em>Index</em>}'. @@ -3560,7 +3879,7 @@ public interface SetupPackage extends EPackage * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getTriggerSet() * @generated */ - int TRIGGER_SET = 40; + int TRIGGER_SET = 44; /** * Returns the meta object for class '{@link org.eclipse.oomph.setup.Project <em>Project</em>}'. @@ -4382,6 +4701,145 @@ public interface SetupPackage extends EPackage EReference getWorkspaceToInstallationsMapEntry_Value(); /** + * Returns the meta object for class '{@link org.eclipse.oomph.setup.Macro <em>Macro</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Macro</em>'. + * @see org.eclipse.oomph.setup.Macro + * @generated + */ + EClass getMacro(); + + /** + * Returns the meta object for the reference '{@link org.eclipse.oomph.setup.Macro#getLogicalContainer <em>Logical Container</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference '<em>Logical Container</em>'. + * @see org.eclipse.oomph.setup.Macro#getLogicalContainer() + * @see #getMacro() + * @generated + */ + EReference getMacro_LogicalContainer(); + + /** + * Returns the meta object for the containment reference list '{@link org.eclipse.oomph.setup.Macro#getParameters <em>Parameters</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the containment reference list '<em>Parameters</em>'. + * @see org.eclipse.oomph.setup.Macro#getParameters() + * @see #getMacro() + * @generated + */ + EReference getMacro_Parameters(); + + /** + * Returns the meta object for class '{@link org.eclipse.oomph.setup.Parameter <em>Parameter</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Parameter</em>'. + * @see org.eclipse.oomph.setup.Parameter + * @generated + */ + EClass getParameter(); + + /** + * Returns the meta object for the attribute '{@link org.eclipse.oomph.setup.Parameter#getName <em>Name</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Name</em>'. + * @see org.eclipse.oomph.setup.Parameter#getName() + * @see #getParameter() + * @generated + */ + EAttribute getParameter_Name(); + + /** + * Returns the meta object for the attribute '{@link org.eclipse.oomph.setup.Parameter#getDescription <em>Description</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Description</em>'. + * @see org.eclipse.oomph.setup.Parameter#getDescription() + * @see #getParameter() + * @generated + */ + EAttribute getParameter_Description(); + + /** + * Returns the meta object for the attribute '{@link org.eclipse.oomph.setup.Parameter#getDefaultValue <em>Default Value</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Default Value</em>'. + * @see org.eclipse.oomph.setup.Parameter#getDefaultValue() + * @see #getParameter() + * @generated + */ + EAttribute getParameter_DefaultValue(); + + /** + * Returns the meta object for class '{@link org.eclipse.oomph.setup.MacroTask <em>Macro Task</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Macro Task</em>'. + * @see org.eclipse.oomph.setup.MacroTask + * @generated + */ + EClass getMacroTask(); + + /** + * Returns the meta object for the containment reference list '{@link org.eclipse.oomph.setup.MacroTask#getArguments <em>Arguments</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the containment reference list '<em>Arguments</em>'. + * @see org.eclipse.oomph.setup.MacroTask#getArguments() + * @see #getMacroTask() + * @generated + */ + EReference getMacroTask_Arguments(); + + /** + * Returns the meta object for class '{@link org.eclipse.oomph.setup.Argument <em>Argument</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for class '<em>Argument</em>'. + * @see org.eclipse.oomph.setup.Argument + * @generated + */ + EClass getArgument(); + + /** + * Returns the meta object for the reference '{@link org.eclipse.oomph.setup.Argument#getParameter <em>Parameter</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference '<em>Parameter</em>'. + * @see org.eclipse.oomph.setup.Argument#getParameter() + * @see #getArgument() + * @generated + */ + EReference getArgument_Parameter(); + + /** + * Returns the meta object for the attribute '{@link org.eclipse.oomph.setup.Argument#getValue <em>Value</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the attribute '<em>Value</em>'. + * @see org.eclipse.oomph.setup.Argument#getValue() + * @see #getArgument() + * @generated + */ + EAttribute getArgument_Value(); + + /** + * Returns the meta object for the reference '{@link org.eclipse.oomph.setup.MacroTask#getMacro <em>Macro</em>}'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @return the meta object for the reference '<em>Macro</em>'. + * @see org.eclipse.oomph.setup.MacroTask#getMacro() + * @see #getMacroTask() + * @generated + */ + EReference getMacroTask_Macro(); + + /** * Returns the meta object for the reference '{@link java.util.Map.Entry <em>Key</em>}'. * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -5726,6 +6184,118 @@ public interface SetupPackage extends EPackage EReference WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY__VALUE = eINSTANCE.getWorkspaceToInstallationsMapEntry_Value(); /** + * The meta object literal for the '{@link org.eclipse.oomph.setup.impl.MacroImpl <em>Macro</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.MacroImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getMacro() + * @generated + */ + EClass MACRO = eINSTANCE.getMacro(); + + /** + * The meta object literal for the '<em><b>Logical Container</b></em>' reference feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference MACRO__LOGICAL_CONTAINER = eINSTANCE.getMacro_LogicalContainer(); + + /** + * The meta object literal for the '<em><b>Parameters</b></em>' containment reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference MACRO__PARAMETERS = eINSTANCE.getMacro_Parameters(); + + /** + * The meta object literal for the '{@link org.eclipse.oomph.setup.impl.ParameterImpl <em>Parameter</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.ParameterImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getParameter() + * @generated + */ + EClass PARAMETER = eINSTANCE.getParameter(); + + /** + * The meta object literal for the '<em><b>Name</b></em>' attribute feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EAttribute PARAMETER__NAME = eINSTANCE.getParameter_Name(); + + /** + * The meta object literal for the '<em><b>Description</b></em>' attribute feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EAttribute PARAMETER__DESCRIPTION = eINSTANCE.getParameter_Description(); + + /** + * The meta object literal for the '<em><b>Default Value</b></em>' attribute feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EAttribute PARAMETER__DEFAULT_VALUE = eINSTANCE.getParameter_DefaultValue(); + + /** + * The meta object literal for the '{@link org.eclipse.oomph.setup.impl.MacroTaskImpl <em>Macro Task</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.MacroTaskImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getMacroTask() + * @generated + */ + EClass MACRO_TASK = eINSTANCE.getMacroTask(); + + /** + * The meta object literal for the '<em><b>Arguments</b></em>' containment reference list feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference MACRO_TASK__ARGUMENTS = eINSTANCE.getMacroTask_Arguments(); + + /** + * The meta object literal for the '{@link org.eclipse.oomph.setup.impl.ArgumentImpl <em>Argument</em>}' class. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see org.eclipse.oomph.setup.impl.ArgumentImpl + * @see org.eclipse.oomph.setup.impl.SetupPackageImpl#getArgument() + * @generated + */ + EClass ARGUMENT = eINSTANCE.getArgument(); + + /** + * The meta object literal for the '<em><b>Parameter</b></em>' reference feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference ARGUMENT__PARAMETER = eINSTANCE.getArgument_Parameter(); + + /** + * The meta object literal for the '<em><b>Value</b></em>' attribute feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EAttribute ARGUMENT__VALUE = eINSTANCE.getArgument_Value(); + + /** + * The meta object literal for the '<em><b>Macro</b></em>' reference feature. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + EReference MACRO_TASK__MACRO = eINSTANCE.getMacroTask_Macro(); + + /** * The meta object literal for the '<em><b>Key</b></em>' reference feature. * <!-- begin-user-doc --> * <!-- end-user-doc --> diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupTask.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupTask.java index 57d128fb6..1ee300981 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupTask.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/SetupTask.java @@ -247,7 +247,7 @@ public interface SetupTask extends ModelElement * @return the value of the '<em>Disabled</em>' attribute. * @see #setDisabled(boolean) * @see org.eclipse.oomph.setup.SetupPackage#getSetupTask_Disabled() - * @model + * @model annotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ boolean isDisabled(); diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/VariableTask.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/VariableTask.java index 1f9c11e67..b28e37159 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/VariableTask.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/VariableTask.java @@ -34,6 +34,7 @@ import org.eclipse.emf.common.util.URI; * @see org.eclipse.oomph.setup.SetupPackage#getVariableTask() * @model features="storePromptedValue" * storePromptedValueDefault="true" storePromptedValueDataType="org.eclipse.emf.ecore.EBoolean" storePromptedValueTransient="true" storePromptedValueVolatile="true" storePromptedValueDerived="true" storePromptedValueSuppressedGetVisibility="true" storePromptedValueSuppressedSetVisibility="true" + * storePromptedValueAnnotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ public interface VariableTask extends SetupTask @@ -59,6 +60,7 @@ public interface VariableTask extends SetupTask * @see #setType(VariableType) * @see org.eclipse.oomph.setup.SetupPackage#getVariableTask_Type() * @model default="STRING" required="true" + * annotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ VariableType getType(); @@ -86,7 +88,6 @@ public interface VariableTask extends SetupTask * @see #setName(String) * @see org.eclipse.oomph.setup.SetupPackage#getVariableTask_Name() * @model required="true" - * annotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ String getName(); @@ -166,6 +167,7 @@ public interface VariableTask extends SetupTask * @see #setStorageURI(URI) * @see org.eclipse.oomph.setup.SetupPackage#getVariableTask_StorageURI() * @model default="scope://" dataType="org.eclipse.oomph.base.URI" + * annotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ URI getStorageURI(); @@ -191,7 +193,7 @@ public interface VariableTask extends SetupTask * @return the value of the '<em>Label</em>' attribute. * @see #setLabel(String) * @see org.eclipse.oomph.setup.SetupPackage#getVariableTask_Label() - * @model + * @model annotation="http://www.eclipse.org/oomph/setup/NoExpand" * @generated */ String getLabel(); diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ArgumentImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ArgumentImpl.java new file mode 100644 index 000000000..52fd1ac83 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ArgumentImpl.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.impl; + +import org.eclipse.oomph.base.impl.ModelElementImpl; +import org.eclipse.oomph.setup.Argument; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Argument</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.impl.ArgumentImpl#getParameter <em>Parameter</em>}</li> + * <li>{@link org.eclipse.oomph.setup.impl.ArgumentImpl#getValue <em>Value</em>}</li> + * </ul> + * + * @generated + */ +public class ArgumentImpl extends ModelElementImpl implements Argument +{ + /** + * The cached value of the '{@link #getParameter() <em>Parameter</em>}' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getParameter() + * @generated + * @ordered + */ + protected Parameter parameter; + + /** + * The default value of the '{@link #getValue() <em>Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getValue() + * @generated + * @ordered + */ + protected static final String VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getValue() <em>Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getValue() + * @generated + * @ordered + */ + protected String value = VALUE_EDEFAULT; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ArgumentImpl() + { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() + { + return SetupPackage.Literals.ARGUMENT; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Parameter getParameter() + { + if (parameter != null && parameter.eIsProxy()) + { + InternalEObject oldParameter = (InternalEObject)parameter; + parameter = (Parameter)eResolveProxy(oldParameter); + if (parameter != oldParameter) + { + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.RESOLVE, SetupPackage.ARGUMENT__PARAMETER, oldParameter, parameter)); + } + } + } + return parameter; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Parameter basicGetParameter() + { + return parameter; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setParameter(Parameter newParameter) + { + Parameter oldParameter = parameter; + parameter = newParameter; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.ARGUMENT__PARAMETER, oldParameter, parameter)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String getValue() + { + return value; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setValue(String newValue) + { + String oldValue = value; + value = newValue; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.ARGUMENT__VALUE, oldValue, value)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case SetupPackage.ARGUMENT__PARAMETER: + if (resolve) + { + return getParameter(); + } + return basicGetParameter(); + case SetupPackage.ARGUMENT__VALUE: + return getValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case SetupPackage.ARGUMENT__PARAMETER: + setParameter((Parameter)newValue); + return; + case SetupPackage.ARGUMENT__VALUE: + setValue((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case SetupPackage.ARGUMENT__PARAMETER: + setParameter((Parameter)null); + return; + case SetupPackage.ARGUMENT__VALUE: + setValue(VALUE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case SetupPackage.ARGUMENT__PARAMETER: + return parameter != null; + case SetupPackage.ARGUMENT__VALUE: + return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value); + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) + { + return super.toString(); + } + + StringBuilder result = new StringBuilder(super.toString()); + result.append(" (value: "); + result.append(value); + result.append(')'); + return result.toString(); + } + +} // ArgumentImpl diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/MacroImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/MacroImpl.java new file mode 100644 index 000000000..6976c7298 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/MacroImpl.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.impl; + +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.Scope; +import org.eclipse.oomph.setup.ScopeType; +import org.eclipse.oomph.setup.SetupPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +import java.util.Collection; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Macro</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.impl.MacroImpl#getLogicalContainer <em>Logical Container</em>}</li> + * <li>{@link org.eclipse.oomph.setup.impl.MacroImpl#getParameters <em>Parameters</em>}</li> + * </ul> + * + * @generated + */ +public class MacroImpl extends ScopeImpl implements Macro +{ + /** + * The cached value of the '{@link #getLogicalContainer() <em>Logical Container</em>}' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getLogicalContainer() + * @generated + * @ordered + */ + protected MacroTask logicalContainer; + + /** + * The cached value of the '{@link #getParameters() <em>Parameters</em>}' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getParameters() + * @generated + * @ordered + */ + protected EList<Parameter> parameters; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected MacroImpl() + { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() + { + return SetupPackage.Literals.MACRO; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public MacroTask getLogicalContainer() + { + return logicalContainer; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setLogicalContainer(MacroTask newLogicalContainer) + { + MacroTask oldLogicalContainer = logicalContainer; + logicalContainer = newLogicalContainer; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.MACRO__LOGICAL_CONTAINER, oldLogicalContainer, logicalContainer)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EList<Parameter> getParameters() + { + if (parameters == null) + { + parameters = new EObjectContainmentEList<Parameter>(Parameter.class, this, SetupPackage.MACRO__PARAMETERS); + } + return parameters; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case SetupPackage.MACRO__PARAMETERS: + return ((InternalEList<?>)getParameters()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case SetupPackage.MACRO__LOGICAL_CONTAINER: + return getLogicalContainer(); + case SetupPackage.MACRO__PARAMETERS: + return getParameters(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case SetupPackage.MACRO__LOGICAL_CONTAINER: + setLogicalContainer((MacroTask)newValue); + return; + case SetupPackage.MACRO__PARAMETERS: + getParameters().clear(); + getParameters().addAll((Collection<? extends Parameter>)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case SetupPackage.MACRO__LOGICAL_CONTAINER: + setLogicalContainer((MacroTask)null); + return; + case SetupPackage.MACRO__PARAMETERS: + getParameters().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case SetupPackage.MACRO__LOGICAL_CONTAINER: + return logicalContainer != null; + case SetupPackage.MACRO__PARAMETERS: + return parameters != null && !parameters.isEmpty(); + } + return super.eIsSet(featureID); + } + + @Override + public ScopeType getType() + { + return ScopeType.MACRO; + } + + @Override + public Scope getParentScope() + { + MacroTask logicalContainer = getLogicalContainer(); + if (logicalContainer != null) + { + return logicalContainer.getScope(); + } + + return null; + } + + @Override + public String getQualifiedName() + { + Scope parentScope = getParentScope(); + if (parentScope != null) + { + return parentScope.getQualifiedName(); + } + + return super.getQualifiedName(); + } + +} // MacroImpl diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/MacroTaskImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/MacroTaskImpl.java new file mode 100644 index 000000000..014c3dbdb --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/MacroTaskImpl.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.impl; + +import org.eclipse.oomph.setup.Argument; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.oomph.setup.SetupTaskContext; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +import java.util.Collection; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Macro Task</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.impl.MacroTaskImpl#getArguments <em>Arguments</em>}</li> + * <li>{@link org.eclipse.oomph.setup.impl.MacroTaskImpl#getMacro <em>Macro</em>}</li> + * </ul> + * + * @generated + */ +public class MacroTaskImpl extends SetupTaskImpl implements MacroTask +{ + /** + * The cached value of the '{@link #getArguments() <em>Arguments</em>}' containment reference list. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getArguments() + * @generated + * @ordered + */ + protected EList<Argument> arguments; + + /** + * The cached value of the '{@link #getMacro() <em>Macro</em>}' reference. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getMacro() + * @generated + * @ordered + */ + protected Macro macro; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected MacroTaskImpl() + { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() + { + return SetupPackage.Literals.MACRO_TASK; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EList<Argument> getArguments() + { + if (arguments == null) + { + arguments = new EObjectContainmentEList<Argument>(Argument.class, this, SetupPackage.MACRO_TASK__ARGUMENTS); + } + return arguments; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) + { + switch (featureID) + { + case SetupPackage.MACRO_TASK__ARGUMENTS: + return ((InternalEList<?>)getArguments()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Macro getMacro() + { + if (macro != null && macro.eIsProxy()) + { + InternalEObject oldMacro = (InternalEObject)macro; + macro = (Macro)eResolveProxy(oldMacro); + if (macro != oldMacro) + { + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.RESOLVE, SetupPackage.MACRO_TASK__MACRO, oldMacro, macro)); + } + } + } + return macro; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Macro basicGetMacro() + { + return macro; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setMacro(Macro newMacro) + { + Macro oldMacro = macro; + macro = newMacro; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.MACRO_TASK__MACRO, oldMacro, macro)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case SetupPackage.MACRO_TASK__ARGUMENTS: + return getArguments(); + case SetupPackage.MACRO_TASK__MACRO: + if (resolve) + { + return getMacro(); + } + return basicGetMacro(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case SetupPackage.MACRO_TASK__ARGUMENTS: + getArguments().clear(); + getArguments().addAll((Collection<? extends Argument>)newValue); + return; + case SetupPackage.MACRO_TASK__MACRO: + setMacro((Macro)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case SetupPackage.MACRO_TASK__ARGUMENTS: + getArguments().clear(); + return; + case SetupPackage.MACRO_TASK__MACRO: + setMacro((Macro)null); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case SetupPackage.MACRO_TASK__ARGUMENTS: + return arguments != null && !arguments.isEmpty(); + case SetupPackage.MACRO_TASK__MACRO: + return macro != null; + } + return super.eIsSet(featureID); + } + + public boolean isNeeded(SetupTaskContext context) throws Exception + { + return false; + } + + public void perform(SetupTaskContext context) throws Exception + { + } + +} // MacroTaskImpl diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ParameterImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ParameterImpl.java new file mode 100644 index 000000000..3e17f94e3 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ParameterImpl.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.impl; + +import org.eclipse.oomph.base.impl.ModelElementImpl; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * <!-- begin-user-doc --> + * An implementation of the model object '<em><b>Parameter</b></em>'. + * <!-- end-user-doc --> + * <p> + * The following features are implemented: + * </p> + * <ul> + * <li>{@link org.eclipse.oomph.setup.impl.ParameterImpl#getName <em>Name</em>}</li> + * <li>{@link org.eclipse.oomph.setup.impl.ParameterImpl#getDescription <em>Description</em>}</li> + * <li>{@link org.eclipse.oomph.setup.impl.ParameterImpl#getDefaultValue <em>Default Value</em>}</li> + * </ul> + * + * @generated + */ +public class ParameterImpl extends ModelElementImpl implements Parameter +{ + /** + * The default value of the '{@link #getName() <em>Name</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() <em>Name</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * The default value of the '{@link #getDescription() <em>Description</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getDescription() + * @generated + * @ordered + */ + protected static final String DESCRIPTION_EDEFAULT = null; + + /** + * The cached value of the '{@link #getDescription() <em>Description</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getDescription() + * @generated + * @ordered + */ + protected String description = DESCRIPTION_EDEFAULT; + + /** + * The default value of the '{@link #getDefaultValue() <em>Default Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getDefaultValue() + * @generated + * @ordered + */ + protected static final String DEFAULT_VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getDefaultValue() <em>Default Value</em>}' attribute. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @see #getDefaultValue() + * @generated + * @ordered + */ + protected String defaultValue = DEFAULT_VALUE_EDEFAULT; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + protected ParameterImpl() + { + super(); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() + { + return SetupPackage.Literals.PARAMETER; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String getName() + { + return name; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setName(String newName) + { + String oldName = name; + name = newName; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.PARAMETER__NAME, oldName, name)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String getDescription() + { + return description; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setDescription(String newDescription) + { + String oldDescription = description; + description = newDescription; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.PARAMETER__DESCRIPTION, oldDescription, description)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public String getDefaultValue() + { + return defaultValue; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public void setDefaultValue(String newDefaultValue) + { + String oldDefaultValue = defaultValue; + defaultValue = newDefaultValue; + if (eNotificationRequired()) + { + eNotify(new ENotificationImpl(this, Notification.SET, SetupPackage.PARAMETER__DEFAULT_VALUE, oldDefaultValue, defaultValue)); + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) + { + switch (featureID) + { + case SetupPackage.PARAMETER__NAME: + return getName(); + case SetupPackage.PARAMETER__DESCRIPTION: + return getDescription(); + case SetupPackage.PARAMETER__DEFAULT_VALUE: + return getDefaultValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) + { + switch (featureID) + { + case SetupPackage.PARAMETER__NAME: + setName((String)newValue); + return; + case SetupPackage.PARAMETER__DESCRIPTION: + setDescription((String)newValue); + return; + case SetupPackage.PARAMETER__DEFAULT_VALUE: + setDefaultValue((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) + { + switch (featureID) + { + case SetupPackage.PARAMETER__NAME: + setName(NAME_EDEFAULT); + return; + case SetupPackage.PARAMETER__DESCRIPTION: + setDescription(DESCRIPTION_EDEFAULT); + return; + case SetupPackage.PARAMETER__DEFAULT_VALUE: + setDefaultValue(DEFAULT_VALUE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) + { + switch (featureID) + { + case SetupPackage.PARAMETER__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + case SetupPackage.PARAMETER__DESCRIPTION: + return DESCRIPTION_EDEFAULT == null ? description != null : !DESCRIPTION_EDEFAULT.equals(description); + case SetupPackage.PARAMETER__DEFAULT_VALUE: + return DEFAULT_VALUE_EDEFAULT == null ? defaultValue != null : !DEFAULT_VALUE_EDEFAULT.equals(defaultValue); + } + return super.eIsSet(featureID); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + @Override + public String toString() + { + if (eIsProxy()) + { + return super.toString(); + } + + StringBuilder result = new StringBuilder(super.toString()); + result.append(" (name: "); + result.append(name); + result.append(", description: "); + result.append(description); + result.append(", defaultValue: "); + result.append(defaultValue); + result.append(')'); + return result.toString(); + } + +} // ParameterImpl diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ScopeImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ScopeImpl.java index 9c7fa5f7e..02c687dd0 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ScopeImpl.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/ScopeImpl.java @@ -13,11 +13,15 @@ package org.eclipse.oomph.setup.impl; import org.eclipse.oomph.setup.Scope; import org.eclipse.oomph.setup.ScopeType; import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.oomph.util.StringUtil; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.impl.ENotificationImpl; +import java.util.ArrayList; +import java.util.List; + /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Scope</b></em>'. @@ -230,6 +234,62 @@ public abstract class ScopeImpl extends SetupTaskContainerImpl implements Scope /** * <!-- begin-user-doc --> * <!-- end-user-doc --> + * @generated NOT + */ + public String getQualifiedLabel() + { + String label = getLabel(); + if (StringUtil.isEmpty(label)) + { + label = getName(); + } + + List<String> labelQualifiers = new ArrayList<String>(); + for (Scope parentScope = getParentScope(); parentScope != null; parentScope = parentScope.getParentScope()) + { + String parentLabel = parentScope.getLabel(); + if (StringUtil.isEmpty(parentLabel)) + { + parentLabel = parentScope.getName(); + } + + if (!StringUtil.isEmpty(parentLabel)) + { + labelQualifiers.add(0, parentLabel); + } + } + + if (!labelQualifiers.isEmpty()) + { + StringBuilder result = new StringBuilder(label); + result.append(" ("); + boolean first = true; + for (String labelQualifier : labelQualifiers) + { + if (first) + { + first = false; + } + else + { + result.append(" - "); + + } + + result.append(labelQualifier); + } + + result.append(")"); + + label = result.toString(); + } + + return label; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> * @generated */ @Override diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupFactoryImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupFactoryImpl.java index 3ba92aa09..0ea5c3596 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupFactoryImpl.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupFactoryImpl.java @@ -10,6 +10,7 @@ */ package org.eclipse.oomph.setup.impl; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.AttributeRule; import org.eclipse.oomph.setup.CatalogSelection; import org.eclipse.oomph.setup.CompoundTask; @@ -21,6 +22,9 @@ import org.eclipse.oomph.setup.InstallationTask; import org.eclipse.oomph.setup.LicenseInfo; import org.eclipse.oomph.setup.LinkLocationTask; import org.eclipse.oomph.setup.LocationCatalog; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.PreferenceTask; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; @@ -173,6 +177,14 @@ public class SetupFactoryImpl extends EFactoryImpl implements SetupFactory return (EObject)createInstallationToWorkspacesMapEntry(); case SetupPackage.WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY: return (EObject)createWorkspaceToInstallationsMapEntry(); + case SetupPackage.MACRO: + return createMacro(); + case SetupPackage.PARAMETER: + return createParameter(); + case SetupPackage.MACRO_TASK: + return createMacroTask(); + case SetupPackage.ARGUMENT: + return createArgument(); default: throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); } @@ -494,6 +506,50 @@ public class SetupFactoryImpl extends EFactoryImpl implements SetupFactory * <!-- end-user-doc --> * @generated */ + public Macro createMacro() + { + MacroImpl macro = new MacroImpl(); + return macro; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Parameter createParameter() + { + ParameterImpl parameter = new ParameterImpl(); + return parameter; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public MacroTask createMacroTask() + { + MacroTaskImpl macroTask = new MacroTaskImpl(); + return macroTask; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public Argument createArgument() + { + ArgumentImpl argument = new ArgumentImpl(); + return argument; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ public StringSubstitutionTask createStringSubstitutionTask() { StringSubstitutionTaskImpl stringSubstitutionTask = new StringSubstitutionTaskImpl(); diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupPackageImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupPackageImpl.java index 16ec51000..0d2028f8c 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupPackageImpl.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupPackageImpl.java @@ -11,6 +11,7 @@ package org.eclipse.oomph.setup.impl; import org.eclipse.oomph.base.BasePackage; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.AttributeRule; import org.eclipse.oomph.setup.CatalogSelection; import org.eclipse.oomph.setup.CompoundTask; @@ -22,6 +23,9 @@ import org.eclipse.oomph.setup.InstallationTask; import org.eclipse.oomph.setup.LicenseInfo; import org.eclipse.oomph.setup.LinkLocationTask; import org.eclipse.oomph.setup.LocationCatalog; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.PreferenceTask; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; @@ -232,6 +236,34 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage * <!-- end-user-doc --> * @generated */ + private EClass macroEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass parameterEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass macroTaskEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + private EClass argumentEClass = null; + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ private EClass stringSubstitutionTaskEClass = null; /** @@ -1317,6 +1349,136 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage * <!-- end-user-doc --> * @generated */ + public EClass getMacro() + { + return macroEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EReference getMacro_LogicalContainer() + { + return (EReference)macroEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EReference getMacro_Parameters() + { + return (EReference)macroEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EClass getParameter() + { + return parameterEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EAttribute getParameter_Name() + { + return (EAttribute)parameterEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EAttribute getParameter_Description() + { + return (EAttribute)parameterEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EAttribute getParameter_DefaultValue() + { + return (EAttribute)parameterEClass.getEStructuralFeatures().get(2); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EClass getMacroTask() + { + return macroTaskEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EReference getMacroTask_Arguments() + { + return (EReference)macroTaskEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EClass getArgument() + { + return argumentEClass; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EReference getArgument_Parameter() + { + return (EReference)argumentEClass.getEStructuralFeatures().get(0); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EAttribute getArgument_Value() + { + return (EAttribute)argumentEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public EReference getMacroTask_Macro() + { + return (EReference)macroTaskEClass.getEStructuralFeatures().get(1); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ public EReference getWorkspaceToInstallationsMapEntry_Key() { return (EReference)workspaceToInstallationsMapEntryEClass.getEStructuralFeatures().get(0); @@ -2065,6 +2227,23 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage createEReference(workspaceToInstallationsMapEntryEClass, WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY__KEY); createEReference(workspaceToInstallationsMapEntryEClass, WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY__VALUE); + macroEClass = createEClass(MACRO); + createEReference(macroEClass, MACRO__LOGICAL_CONTAINER); + createEReference(macroEClass, MACRO__PARAMETERS); + + parameterEClass = createEClass(PARAMETER); + createEAttribute(parameterEClass, PARAMETER__NAME); + createEAttribute(parameterEClass, PARAMETER__DESCRIPTION); + createEAttribute(parameterEClass, PARAMETER__DEFAULT_VALUE); + + macroTaskEClass = createEClass(MACRO_TASK); + createEReference(macroTaskEClass, MACRO_TASK__ARGUMENTS); + createEReference(macroTaskEClass, MACRO_TASK__MACRO); + + argumentEClass = createEClass(ARGUMENT); + createEReference(argumentEClass, ARGUMENT__PARAMETER); + createEAttribute(argumentEClass, ARGUMENT__VALUE); + // Create enums scopeTypeEEnum = createEEnum(SCOPE_TYPE); triggerEEnum = createEEnum(TRIGGER); @@ -2144,6 +2323,10 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage resourceCreationTaskEClass.getESuperTypes().add(getSetupTask()); textModifyTaskEClass.getESuperTypes().add(getSetupTask()); textModificationEClass.getESuperTypes().add(theBasePackage.getModelElement()); + macroEClass.getESuperTypes().add(getScope()); + parameterEClass.getESuperTypes().add(theBasePackage.getModelElement()); + macroTaskEClass.getESuperTypes().add(getSetupTask()); + argumentEClass.getESuperTypes().add(theBasePackage.getModelElement()); // Initialize classes and features; add operations and parameters initEClass(setupTaskEClass, SetupTask.class, "SetupTask", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); @@ -2193,6 +2376,8 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage addEOperation(scopeEClass, getScopeType(), "getType", 1, 1, IS_UNIQUE, IS_ORDERED); + addEOperation(scopeEClass, ecorePackage.getEString(), "getQualifiedLabel", 0, 1, IS_UNIQUE, IS_ORDERED); + initEClass(indexEClass, Index.class, "Index", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getIndex_Name(), ecorePackage.getEString(), "name", null, 1, 1, Index.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); @@ -2445,6 +2630,33 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage initEReference(getWorkspaceToInstallationsMapEntry_Value(), getInstallation(), null, "value", null, 0, -1, Map.Entry.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEClass(macroEClass, Macro.class, "Macro", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getMacro_LogicalContainer(), getMacroTask(), null, "logicalContainer", null, 0, 1, Macro.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getMacro_Parameters(), getParameter(), null, "parameters", null, 0, -1, Macro.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + getMacro_Parameters().getEKeys().add(getParameter_Name()); + + initEClass(parameterEClass, Parameter.class, "Parameter", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getParameter_Name(), ecorePackage.getEString(), "name", null, 1, 1, Parameter.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getParameter_Description(), theBasePackage.getText(), "description", null, 0, 1, Parameter.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getParameter_DefaultValue(), ecorePackage.getEString(), "defaultValue", null, 0, 1, Parameter.class, !IS_TRANSIENT, !IS_VOLATILE, + IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(macroTaskEClass, MacroTask.class, "MacroTask", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getMacroTask_Arguments(), getArgument(), null, "arguments", null, 0, -1, MacroTask.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getMacroTask_Macro(), getMacro(), null, "macro", null, 1, 1, MacroTask.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, + IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(argumentEClass, Argument.class, "Argument", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getArgument_Parameter(), getParameter(), null, "parameter", null, 1, 1, Argument.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getArgument_Value(), ecorePackage.getEString(), "value", null, 0, 1, Argument.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, + !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + // Initialize enums and add enum literals initEEnum(scopeTypeEEnum, ScopeType.class, "ScopeType"); addEEnumLiteral(scopeTypeEEnum, ScopeType.NONE); @@ -2457,6 +2669,7 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage addEEnumLiteral(scopeTypeEEnum, ScopeType.INSTALLATION); addEEnumLiteral(scopeTypeEEnum, ScopeType.WORKSPACE); addEEnumLiteral(scopeTypeEEnum, ScopeType.USER); + addEEnumLiteral(scopeTypeEEnum, ScopeType.MACRO); initEEnum(triggerEEnum, Trigger.class, "Trigger"); addEEnumLiteral(triggerEEnum, Trigger.BOOTSTRAP); @@ -2564,6 +2777,9 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage addAnnotation(getProductToProductVersionMapEntry_Value(), source, new String[] { "kind", "attribute" }); addAnnotation(getProjectToStreamMapEntry_Key(), source, new String[] { "kind", "attribute" }); addAnnotation(getProjectToStreamMapEntry_Value(), source, new String[] { "kind", "attribute" }); + addAnnotation(getMacro_Parameters(), source, new String[] { "kind", "element", "name", "parameter" }); + addAnnotation(getParameter_Description(), source, new String[] { "kind", "element" }); + addAnnotation(getMacroTask_Arguments(), source, new String[] { "kind", "element", "name", "argument" }); } /** @@ -2576,9 +2792,14 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage { String source = "http://www.eclipse.org/oomph/setup/NoExpand"; addAnnotation(getSetupTask_ID(), source, new String[] {}); + addAnnotation(getSetupTask_Disabled(), source, new String[] {}); addAnnotation(getSetupTask_Filter(), source, new String[] {}); - addAnnotation(getVariableTask_Name(), source, new String[] {}); + addAnnotation(getVariableTask_Type(), source, new String[] {}); + addAnnotation(getVariableTask_StorePromptedValue(), source, new String[] {}); + addAnnotation(getVariableTask_StorageURI(), source, new String[] {}); + addAnnotation(getVariableTask_Label(), source, new String[] {}); addAnnotation(getVariableChoice_Value(), source, new String[] {}); + addAnnotation(getParameter_Name(), source, new String[] {}); } /** @@ -2625,6 +2846,9 @@ public class SetupPackageImpl extends EPackageImpl implements SetupPackage protected void createEcoreAnnotations() { String source = "http://www.eclipse.org/emf/2002/Ecore"; + addAnnotation(macroEClass, source, new String[] { "constraints", "NoRecursion" }); + addAnnotation(macroTaskEClass, source, new String[] { "constraints", "IDRequired ArgumentsCorrespondToParameters" }); + addAnnotation(argumentEClass, source, new String[] { "constraints", "ConsistentParameterBinding" }); addAnnotation(filterEDataType, source, new String[] { "constraints", "WellformedFilterExpression" }); } diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupTaskImpl.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupTaskImpl.java index e85a75a3a..0380c9f41 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupTaskImpl.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/impl/SetupTaskImpl.java @@ -11,21 +11,12 @@ package org.eclipse.oomph.setup.impl; import org.eclipse.oomph.base.impl.ModelElementImpl; -import org.eclipse.oomph.setup.Installation; -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.Scope; import org.eclipse.oomph.setup.ScopeType; import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.oomph.setup.SetupTask; 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.Workspace; import org.eclipse.oomph.setup.util.SetupUtil; import org.eclipse.oomph.util.UserCallback; @@ -314,7 +305,7 @@ public abstract class SetupTaskImpl extends ModelElementImpl implements SetupTas * <!-- end-user-doc --> * @generated NOT */ - public ScopeType getScopeType() + public final ScopeType getScopeType() { return getScope(this); } @@ -419,49 +410,9 @@ public abstract class SetupTaskImpl extends ModelElementImpl implements SetupTas private ScopeType getScope(EObject object) { - if (object instanceof ProjectCatalog) + if (object instanceof Scope) { - return ScopeType.PROJECT_CATALOG; - } - - if (object instanceof Installation) - { - return ScopeType.INSTALLATION; - } - - if (object instanceof Workspace) - { - return ScopeType.WORKSPACE; - } - - if (object instanceof ProductCatalog) - { - return ScopeType.PRODUCT_CATALOG; - } - - if (object instanceof Product) - { - return ScopeType.PRODUCT; - } - - if (object instanceof ProductVersion) - { - return ScopeType.PRODUCT_VERSION; - } - - if (object instanceof Project) - { - return ScopeType.PROJECT; - } - - if (object instanceof Stream) - { - return ScopeType.STREAM; - } - - if (object instanceof User) - { - return ScopeType.USER; + return ((Scope)object).getType(); } EObject container = object.eContainer(); diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupAdapterFactory.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupAdapterFactory.java index 072734849..cf9a583b4 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupAdapterFactory.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupAdapterFactory.java @@ -11,6 +11,7 @@ package org.eclipse.oomph.setup.util; import org.eclipse.oomph.base.ModelElement; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.AttributeRule; import org.eclipse.oomph.setup.CatalogSelection; import org.eclipse.oomph.setup.CompoundTask; @@ -21,6 +22,9 @@ import org.eclipse.oomph.setup.Installation; import org.eclipse.oomph.setup.InstallationTask; import org.eclipse.oomph.setup.LinkLocationTask; import org.eclipse.oomph.setup.LocationCatalog; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.PreferenceTask; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; @@ -332,6 +336,30 @@ public class SetupAdapterFactory extends AdapterFactoryImpl } @Override + public Adapter caseMacro(Macro object) + { + return createMacroAdapter(); + } + + @Override + public Adapter caseParameter(Parameter object) + { + return createParameterAdapter(); + } + + @Override + public Adapter caseMacroTask(MacroTask object) + { + return createMacroTaskAdapter(); + } + + @Override + public Adapter caseArgument(Argument object) + { + return createArgumentAdapter(); + } + + @Override public Adapter caseModelElement(ModelElement object) { return createModelElementAdapter(); @@ -689,6 +717,66 @@ public class SetupAdapterFactory extends AdapterFactoryImpl } /** + * Creates a new adapter for an object of class '{@link org.eclipse.oomph.setup.Macro <em>Macro</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.oomph.setup.Macro + * @generated + */ + public Adapter createMacroAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.oomph.setup.Parameter <em>Parameter</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.oomph.setup.Parameter + * @generated + */ + public Adapter createParameterAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.oomph.setup.MacroTask <em>Macro Task</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.oomph.setup.MacroTask + * @generated + */ + public Adapter createMacroTaskAdapter() + { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link org.eclipse.oomph.setup.Argument <em>Argument</em>}'. + * <!-- begin-user-doc --> + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * <!-- end-user-doc --> + * @return the new adapter. + * @see org.eclipse.oomph.setup.Argument + * @generated + */ + public Adapter createArgumentAdapter() + { + return null; + } + + /** * Creates a new adapter for an object of class '{@link org.eclipse.oomph.base.ModelElement <em>Model Element</em>}'. * <!-- begin-user-doc --> * This default implementation returns null so that we can easily ignore cases; diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupSwitch.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupSwitch.java index 045bfbaa8..85d3e2c80 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupSwitch.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupSwitch.java @@ -11,6 +11,7 @@ package org.eclipse.oomph.setup.util; import org.eclipse.oomph.base.ModelElement; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.AttributeRule; import org.eclipse.oomph.setup.CatalogSelection; import org.eclipse.oomph.setup.CompoundTask; @@ -21,6 +22,9 @@ import org.eclipse.oomph.setup.Installation; import org.eclipse.oomph.setup.InstallationTask; import org.eclipse.oomph.setup.LinkLocationTask; import org.eclipse.oomph.setup.LocationCatalog; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.PreferenceTask; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; @@ -747,6 +751,74 @@ public class SetupSwitch<T> extends Switch<T> } return result; } + case SetupPackage.MACRO: + { + Macro macro = (Macro)theEObject; + T result = caseMacro(macro); + if (result == null) + { + result = caseScope(macro); + } + if (result == null) + { + result = caseSetupTaskContainer(macro); + } + if (result == null) + { + result = caseModelElement(macro); + } + if (result == null) + { + result = defaultCase(theEObject); + } + return result; + } + case SetupPackage.PARAMETER: + { + Parameter parameter = (Parameter)theEObject; + T result = caseParameter(parameter); + if (result == null) + { + result = caseModelElement(parameter); + } + if (result == null) + { + result = defaultCase(theEObject); + } + return result; + } + case SetupPackage.MACRO_TASK: + { + MacroTask macroTask = (MacroTask)theEObject; + T result = caseMacroTask(macroTask); + if (result == null) + { + result = caseSetupTask(macroTask); + } + if (result == null) + { + result = caseModelElement(macroTask); + } + if (result == null) + { + result = defaultCase(theEObject); + } + return result; + } + case SetupPackage.ARGUMENT: + { + Argument argument = (Argument)theEObject; + T result = caseArgument(argument); + if (result == null) + { + result = caseModelElement(argument); + } + if (result == null) + { + result = defaultCase(theEObject); + } + return result; + } default: return defaultCase(theEObject); } @@ -1185,6 +1257,70 @@ public class SetupSwitch<T> extends Switch<T> } /** + * Returns the result of interpreting the object as an instance of '<em>Macro</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Macro</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseMacro(Macro object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Parameter</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Parameter</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseParameter(Parameter object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Macro Task</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Macro Task</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseMacroTask(MacroTask object) + { + return null; + } + + /** + * Returns the result of interpreting the object as an instance of '<em>Argument</em>'. + * <!-- begin-user-doc --> + * This implementation returns null; + * returning a non-null result will terminate the switch. + * <!-- end-user-doc --> + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of '<em>Argument</em>'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseArgument(Argument object) + { + return null; + } + + /** * Returns the result of interpreting the object as an instance of '<em>Model Element</em>'. * <!-- begin-user-doc --> * This implementation returns null; diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupValidator.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupValidator.java index 57fb69534..f9c63d4c0 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupValidator.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/setup/util/SetupValidator.java @@ -11,6 +11,7 @@ package org.eclipse.oomph.setup.util; import org.eclipse.oomph.internal.setup.SetupPlugin; +import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.AttributeRule; import org.eclipse.oomph.setup.CatalogSelection; import org.eclipse.oomph.setup.CompoundTask; @@ -22,6 +23,9 @@ import org.eclipse.oomph.setup.InstallationTask; import org.eclipse.oomph.setup.LicenseInfo; import org.eclipse.oomph.setup.LinkLocationTask; import org.eclipse.oomph.setup.LocationCatalog; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.PreferenceTask; import org.eclipse.oomph.setup.Product; import org.eclipse.oomph.setup.ProductCatalog; @@ -34,6 +38,7 @@ import org.eclipse.oomph.setup.ResourceCopyTask; import org.eclipse.oomph.setup.ResourceCreationTask; 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; @@ -55,6 +60,7 @@ import org.eclipse.emf.common.CommonPlugin; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.DiagnosticChain; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.ResourceLocator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; @@ -62,6 +68,11 @@ import org.eclipse.emf.ecore.util.EObjectValidator; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -101,12 +112,32 @@ public class SetupValidator extends EObjectValidator private static final int GENERATED_DIAGNOSTIC_CODE_COUNT = 0; /** + * @see #validateMacroTask_IDRequired(MacroTask, DiagnosticChain, Map) + */ + public static final int MACRO_TASK_ID_REQUIRED = GENERATED_DIAGNOSTIC_CODE_COUNT + 1; + + /** + * @see #validateMacroTask_ArgumentsCorrespondToParameters(MacroTask, DiagnosticChain, Map) + */ + public static final int MACRO_TASK_ARGUMENTS_CORRESPOND_TO_PARAMETERS = GENERATED_DIAGNOSTIC_CODE_COUNT + 2; + + /** + * @see #validateArgument_ConsistentParameterBinding(Argument, DiagnosticChain, Map) + */ + public static final int ARGUMENT_CONSISTENT_PARAMETER_BINDING = GENERATED_DIAGNOSTIC_CODE_COUNT + 3; + + /** + * @see #validateMacro_NoRecursion(Macro, DiagnosticChain, Map) + */ + public static final int MACRO_NO_RECURSION = GENERATED_DIAGNOSTIC_CODE_COUNT + 4; + + /** * A constant with a fixed name that can be used as the base value for additional hand written constants in a derived class. * <!-- begin-user-doc --> * <!-- end-user-doc --> - * @generated + * @generated NOT */ - protected static final int DIAGNOSTIC_CODE_COUNT = GENERATED_DIAGNOSTIC_CODE_COUNT; + protected static final int DIAGNOSTIC_CODE_COUNT = MACRO_NO_RECURSION; private static boolean parseFilterMethodInitialized; @@ -219,6 +250,14 @@ public class SetupValidator extends EObjectValidator return validateInstallationToWorkspacesMapEntry((Map.Entry<?, ?>)value, diagnostics, context); case SetupPackage.WORKSPACE_TO_INSTALLATIONS_MAP_ENTRY: return validateWorkspaceToInstallationsMapEntry((Map.Entry<?, ?>)value, diagnostics, context); + case SetupPackage.MACRO: + return validateMacro((Macro)value, diagnostics, context); + case SetupPackage.PARAMETER: + return validateParameter((Parameter)value, diagnostics, context); + case SetupPackage.MACRO_TASK: + return validateMacroTask((MacroTask)value, diagnostics, context); + case SetupPackage.ARGUMENT: + return validateArgument((Argument)value, diagnostics, context); case SetupPackage.SCOPE_TYPE: return validateScopeType((ScopeType)value, diagnostics, context); case SetupPackage.TRIGGER: @@ -606,6 +645,386 @@ public class SetupValidator extends EObjectValidator * <!-- end-user-doc --> * @generated */ + public boolean validateMacro(Macro macro, DiagnosticChain diagnostics, Map<Object, Object> context) + { + if (!validate_NoCircularContainment(macro, diagnostics, context)) + { + return false; + } + boolean result = validate_EveryMultiplicityConforms(macro, diagnostics, context); + if (result || diagnostics != null) + { + result &= validate_EveryDataValueConforms(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryReferenceIsContained(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryBidirectionalReferenceIsPaired(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryProxyResolves(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_UniqueID(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryKeyUnique(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryMapEntryUnique(macro, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validateMacro_NoRecursion(macro, diagnostics, context); + } + return result; + } + + /** + * Validates the NoRecursion constraint of '<em>Macro</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + public boolean validateMacro_NoRecursion(Macro macro, DiagnosticChain diagnostics, Map<Object, Object> context) + { + Map<Macro, MacroTask> visitedMacros = new LinkedHashMap<Macro, MacroTask>(); + MacroTask fakeRootMacroTask = SetupFactory.eINSTANCE.createMacroTask(); + if (isRecursive(visitedMacros, macro, fakeRootMacroTask)) + { + if (diagnostics != null) + { + List<String> choices = new ArrayList<String>(); + List<Object> data = new ArrayList<Object>(); + data.add(macro); + data.add(SetupPackage.Literals.SETUP_TASK_CONTAINER__SETUP_TASKS); + + // Gather the chain of objects that lead to the recursion. + // The fake root macro task will have been replaced with an actual macro task that finally resulted in the recursion. + MacroTask finalRecursiveMacroTask = null; + for (Map.Entry<Macro, MacroTask> entry : visitedMacros.entrySet()) + { + Macro otherMacro = entry.getKey(); + choices.add(getObjectLabel(otherMacro, context)); + + MacroTask macroTask = entry.getValue(); + if (finalRecursiveMacroTask == null) + { + // The initial replaced macro task should be last in the data list. + finalRecursiveMacroTask = macroTask; + } + else + { + data.add(macroTask); + } + + if (otherMacro != macro) + { + data.add(otherMacro); + } + } + + data.add(finalRecursiveMacroTask); + + diagnostics.add(createDiagnostic(Diagnostic.ERROR, DIAGNOSTIC_SOURCE, MACRO_NO_RECURSION, "_UI_MacroNoRecursion_diagnostic", + new Object[] { getAvailableChoices(choices, true, "'", Integer.MAX_VALUE) }, data.toArray(), context)); + } + + return false; + } + + return true; + } + + private boolean isRecursive(Map<Macro, MacroTask> visitedMacros, Macro macro, MacroTask macroTask) + { + MacroTask put = visitedMacros.put(macro, macroTask); + if (put == null) + { + for (Iterator<EObject> it = macro.eAllContents(); it.hasNext();) + { + EObject eObject = it.next(); + if (eObject instanceof MacroTask) + { + MacroTask reachableMacroTask = (MacroTask)eObject; + Macro reachableMacro = reachableMacroTask.getMacro(); + if (reachableMacro != null) + { + if (isRecursive(visitedMacros, reachableMacro, reachableMacroTask)) + { + return true; + } + } + } + } + + visitedMacros.remove(macro); + return false; + } + else + { + return visitedMacros.keySet().iterator().next() == macro; + } + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public boolean validateParameter(Parameter parameter, DiagnosticChain diagnostics, Map<Object, Object> context) + { + return validate_EveryDefaultConstraint(parameter, diagnostics, context); + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public boolean validateMacroTask(MacroTask macroTask, DiagnosticChain diagnostics, Map<Object, Object> context) + { + if (!validate_NoCircularContainment(macroTask, diagnostics, context)) + { + return false; + } + boolean result = validate_EveryMultiplicityConforms(macroTask, diagnostics, context); + if (result || diagnostics != null) + { + result &= validate_EveryDataValueConforms(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryReferenceIsContained(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryBidirectionalReferenceIsPaired(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryProxyResolves(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_UniqueID(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryKeyUnique(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryMapEntryUnique(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validateMacroTask_IDRequired(macroTask, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validateMacroTask_ArgumentsCorrespondToParameters(macroTask, diagnostics, context); + } + return result; + } + + /** + * Validates the IDRequired constraint of '<em>Macro Task</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + public boolean validateMacroTask_IDRequired(MacroTask macroTask, DiagnosticChain diagnostics, Map<Object, Object> context) + { + if (StringUtil.isEmpty(macroTask.getID())) + { + if (diagnostics != null) + { + diagnostics.add(createDiagnostic(Diagnostic.ERROR, DIAGNOSTIC_SOURCE, MACRO_TASK_ID_REQUIRED, "_UI_MacroTaskDRequired_diagnostic", null, + new Object[] { macroTask, SetupPackage.Literals.SETUP_TASK__ID }, context)); + } + + return false; + } + + return true; + } + + /** + * Validates the ArgumentsCorrespondToParameters constraint of '<em>Macro Task</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + public boolean validateMacroTask_ArgumentsCorrespondToParameters(MacroTask macroTask, DiagnosticChain diagnostics, Map<Object, Object> context) + { + Macro macro = macroTask.getMacro(); + if (macro != null && !macro.eIsProxy()) + { + EList<Parameter> parameters = macro.getParameters(); + EList<Argument> arguments = macroTask.getArguments(); + Set<Parameter> boundParameters = new LinkedHashSet<Parameter>(); + for (Argument argument : arguments) + { + boundParameters.add(argument.getParameter()); + } + + Set<String> unboundParameters = new LinkedHashSet<String>(); + for (Parameter parameter : parameters) + { + if (!boundParameters.contains(parameter) && parameter.getDefaultValue() == null) + { + unboundParameters.add(parameter.getName()); + } + } + + if (!unboundParameters.isEmpty()) + { + if (diagnostics != null) + { + diagnostics.add(createDiagnostic(Diagnostic.ERROR, DIAGNOSTIC_SOURCE, MACRO_TASK_ARGUMENTS_CORRESPOND_TO_PARAMETERS, + "_UI_MacroTaskMissingArgument_diagnostic", new Object[] { getAvailableChoices(unboundParameters, true, "'", Integer.MAX_VALUE) }, + new Object[] { macroTask, SetupPackage.Literals.MACRO_TASK__ARGUMENTS }, context)); + } + + return false; + } + } + + return true; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ + public boolean validateArgument(Argument argument, DiagnosticChain diagnostics, Map<Object, Object> context) + { + if (!validate_NoCircularContainment(argument, diagnostics, context)) + { + return false; + } + boolean result = validate_EveryMultiplicityConforms(argument, diagnostics, context); + if (result || diagnostics != null) + { + result &= validate_EveryDataValueConforms(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryReferenceIsContained(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryBidirectionalReferenceIsPaired(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryProxyResolves(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_UniqueID(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryKeyUnique(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validate_EveryMapEntryUnique(argument, diagnostics, context); + } + if (result || diagnostics != null) + { + result &= validateArgument_ConsistentParameterBinding(argument, diagnostics, context); + } + return result; + } + + /** + * Validates the ConsistentParameterBinding constraint of '<em>Argument</em>'. + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated NOT + */ + public boolean validateArgument_ConsistentParameterBinding(Argument argument, DiagnosticChain diagnostics, Map<Object, Object> context) + { + boolean result = true; + Parameter parameter = argument.getParameter(); + if (parameter != null && !parameter.eIsProxy()) + { + if (argument.getValue() == null && parameter.getDefaultValue() == null) + { + if (diagnostics != null) + { + diagnostics.add(createDiagnostic(Diagnostic.ERROR, DIAGNOSTIC_SOURCE, ARGUMENT_CONSISTENT_PARAMETER_BINDING, + "_UI_ArgumentValueMustBeSpecified_diagnostic", null, new Object[] { argument, SetupPackage.Literals.ARGUMENT__VALUE }, context)); + result = false; + } + else + { + return false; + } + } + + EObject eContainer = argument.eContainer(); + if (eContainer instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)eContainer; + EList<Argument> arguments = macroTask.getArguments(); + for (int i = 0, index = arguments.indexOf(argument); i < index; ++i) + { + if (arguments.get(i).getParameter() == parameter) + { + if (diagnostics != null) + { + diagnostics.add(createDiagnostic(Diagnostic.ERROR, DIAGNOSTIC_SOURCE, ARGUMENT_CONSISTENT_PARAMETER_BINDING, + "_UI_ArgumentParameterAlreadyBound_diagnostic", null, new Object[] { argument, SetupPackage.Literals.ARGUMENT__PARAMETER }, context)); + result = false; + } + else + { + return false; + } + } + } + + Macro macro = macroTask.getMacro(); + if (macro != null && !macro.eIsProxy()) + { + EList<Parameter> parameters = macro.getParameters(); + if (!parameters.contains(parameter)) + { + if (diagnostics != null) + { + diagnostics.add(createDiagnostic(Diagnostic.ERROR, DIAGNOSTIC_SOURCE, ARGUMENT_CONSISTENT_PARAMETER_BINDING, + "_UI_ArgumentParameterOutOfScope_diagnostic", null, new Object[] { argument, SetupPackage.Literals.ARGUMENT__PARAMETER }, context)); + result = false; + } + else + { + return false; + } + } + } + } + } + + return result; + } + + /** + * <!-- begin-user-doc --> + * <!-- end-user-doc --> + * @generated + */ public boolean validateScopeType(ScopeType scopeType, DiagnosticChain diagnostics, Map<Object, Object> context) { return true; |