diff options
author | Christian W. Damus | 2020-11-18 14:33:36 +0000 |
---|---|---|
committer | Christian W. Damus | 2020-11-24 14:45:52 +0000 |
commit | 5e503e0f744798b1b69d87afce1068962c274454 (patch) | |
tree | ae9fc94fd036075d44035a2c8d26b408367b62a4 | |
parent | 5b6467b1a9ce93e7f799907295b9535d3ac2a29b (diff) | |
download | org.eclipse.papyrus-5e503e0f744798b1b69d87afce1068962c274454.tar.gz org.eclipse.papyrus-5e503e0f744798b1b69d87afce1068962c274454.tar.xz org.eclipse.papyrus-5e503e0f744798b1b69d87afce1068962c274454.zip |
Bug 568853: [Toolsmiths - ElementTypes] Add "MatchAndApply" Stereotype Matcher
- fix drag-and-drop for owned advices
- create wrappers to identify the multiple roles of StereotypeMatcherAdviceConfiguration
- ensure that deletion of owned configurations should deletes from the superset
https://bugs.eclipse.org/bugs/show_bug.cgi?id=568853
Signed-off-by: Christian W. Damus <give.a.damus@gmail.com>
Change-Id: I4f9dbfb98104c91b9d4303cb5a0adcf9a5a5afb7
-rw-r--r-- | plugins/infra/types/org.eclipse.papyrus.infra.types.edit/src-gen/org/eclipse/papyrus/infra/types/provider/ElementTypeConfigurationItemProvider.java | 152 |
1 files changed, 148 insertions, 4 deletions
diff --git a/plugins/infra/types/org.eclipse.papyrus.infra.types.edit/src-gen/org/eclipse/papyrus/infra/types/provider/ElementTypeConfigurationItemProvider.java b/plugins/infra/types/org.eclipse.papyrus.infra.types.edit/src-gen/org/eclipse/papyrus/infra/types/provider/ElementTypeConfigurationItemProvider.java index c03e9b9da3b..1f31626f0b1 100644 --- a/plugins/infra/types/org.eclipse.papyrus.infra.types.edit/src-gen/org/eclipse/papyrus/infra/types/provider/ElementTypeConfigurationItemProvider.java +++ b/plugins/infra/types/org.eclipse.papyrus.infra.types.edit/src-gen/org/eclipse/papyrus/infra/types/provider/ElementTypeConfigurationItemProvider.java @@ -16,16 +16,26 @@ package org.eclipse.papyrus.infra.types.provider; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; +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.EAnnotation; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EContentsEList.FeatureIterator; +import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; +import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider; import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; import org.eclipse.emf.edit.provider.ViewerNotification; +import org.eclipse.osgi.util.NLS; import org.eclipse.papyrus.infra.types.ElementTypeConfiguration; import org.eclipse.papyrus.infra.types.ElementTypesConfigurationsFactory; import org.eclipse.papyrus.infra.types.ElementTypesConfigurationsPackage; @@ -198,17 +208,130 @@ public class ElementTypeConfigurationItemProvider extends ConfigurationElementIt /** * <!-- begin-user-doc --> * <!-- end-user-doc --> - * @generated + * @generated NOT */ @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. + EStructuralFeature result = null; + + // Sort the children features to get the most specific subset reference and, if applicable, + // a single subset, in which to (e.g.) drop a dragged object + for (EStructuralFeature feature : sortChildrenFeatures(getChildrenFeatures(object))) { + if (isValidValue(object, child, feature)) { + result = feature; + break; + } + } - return super.getChildFeature(object, child); + return result; } /** + * Sort children features by: + * <ul> + * <li>single features before many features</li> + * <li>subset features before their supersets</li> + * </ul> + * + * @param features + * @return + */ + protected List<? extends EStructuralFeature> sortChildrenFeatures(Collection<? extends EStructuralFeature> features) { + List<EStructuralFeature> result = new ArrayList<>(features); + + Collections.sort(result, this::compareFeatures); + + return result; + } + + protected int compareFeatures(EStructuralFeature a, EStructuralFeature b) { + if (a.isMany() && !b.isMany()) { + return +1; + } + if (b.isMany() && !a.isMany()) { + return -1; + } + if (isSubset(a, b)) { + return +1; + } + if (isSubset(b, a)) { + return -1; + } + return 0; + } + + protected boolean isSubset(EStructuralFeature possibleSubset, EStructuralFeature possibleSuperset) { + EAnnotation subsetAnnotation = possibleSubset.getEAnnotation("subsets"); //$NON-NLS-1$ + return subsetAnnotation != null && subsetAnnotation.getReferences().contains(possibleSuperset); + } + + @Override + protected boolean isWrappingNeeded(Object object) { + return true; // the 'ownedConfigurations' has subsets that can repeat the same element + } + + @Override + protected Object createWrapper(EObject object, EStructuralFeature feature, Object value, int index) { + Object result = value; + + if (feature instanceof EReference) { + // Wrapping is needed if the value appears in multiple subsets of the 'ownedConfigurations' + EStructuralFeature previousSubset = null; + + for (FeatureIterator<EObject> iter = (FeatureIterator<EObject>) object.eCrossReferences().iterator(); iter.hasNext();) { + EObject next = iter.next(); + + if (next == value + && next.eContainmentFeature() == ElementTypesConfigurationsPackage.Literals.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS + && isSubset(iter.feature(), ElementTypesConfigurationsPackage.Literals.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS)) { + + if (previousSubset != null && previousSubset != iter.feature()) { + result = new DelegatingWrapperItemProvider(value, object, feature, index, adapterFactory) { + @Override + public String getText(Object object) { + return NLS.bind("{0} as {1}", super.getText(object), getFeatureText(feature)); + } + }; + break; + } + + previousSubset = iter.feature(); + } + } + } else { + result = super.createWrapper(object, feature, value, index); + } + + return result; + } + + @Override + protected Command createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) { + if (feature.isDerived() && isSubset(feature, ElementTypesConfigurationsPackage.Literals.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS)) { + // Add to the superset because the subset is derived + feature = ElementTypesConfigurationsPackage.Literals.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS; + } + + return super.createAddCommand(domain, owner, feature, collection, index); + } + + @Override + protected Command createRemoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection) { + Command result; + + if (isSubset(feature, ElementTypesConfigurationsPackage.Literals.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS)) { + // Remove from the containment superset to entirely remove the object + result = createRemoveCommand(domain, owner, (EStructuralFeature) ElementTypesConfigurationsPackage.Literals.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS, collection); + } else { + result = super.createRemoveCommand(domain, owner, feature, collection); + } + + return result; + } + + /** * This returns the label text for the adapted class. * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -230,8 +353,7 @@ public class ElementTypeConfigurationItemProvider extends ConfigurationElementIt * <!-- end-user-doc --> * @generated */ - @Override - public void notifyChanged(Notification notification) { + public void notifyChangedGen(Notification notification) { updateChildren(notification); switch (notification.getFeatureID(ElementTypeConfiguration.class)) { @@ -249,6 +371,28 @@ public class ElementTypeConfigurationItemProvider extends ConfigurationElementIt } super.notifyChanged(notification); } + + @Override + public void notifyChanged(Notification notification) { + notifyChangedGen(notification); + + switch (notification.getEventType()) { + case Notification.ADD: + case Notification.ADD_MANY: + case Notification.REMOVE: + case Notification.REMOVE_MANY: + switch (notification.getFeatureID(ElementTypeConfiguration.class)) { + case ElementTypesConfigurationsPackage.ELEMENT_TYPE_CONFIGURATION__OWNED_CONFIGURATIONS: + // Refresh derived subsets + if (childrenStoreMap != null) { + childrenStoreMap.remove(notification.getNotifier()); + } + fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, true)); + return; + } + break; + } + } /** * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s describing the children |