Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2015-05-27 08:47:32 -0400
committerChristian W. Damus2015-05-27 08:49:35 -0400
commit2e75551978e7b0da994662c5682bada6615cb240 (patch)
treefcc16d86b6fe64318c649763f44486adc0af5916
parentd696ec8f0a2d90dcb5cf78840b8f16fdb3fd6ab2 (diff)
downloadorg.eclipse.papyrus-2e75551978e7b0da994662c5682bada6615cb240.tar.gz
org.eclipse.papyrus-2e75551978e7b0da994662c5682bada6615cb240.tar.xz
org.eclipse.papyrus-2e75551978e7b0da994662c5682bada6615cb240.zip
Bug 467016: [State Machine] Cannot create State Machine Diagram in a class
https://bugs.eclipse.org/bugs/show_bug.cgi?id=467016 The viewpoint specifies BehavioredClassifier::classifierBehavior as the reference in which to create the Behavior required by a new behavior diagram of a behaviored classifier. That's fine, except that this is not a containment reference, so GMF rejects it. The UML-specific ElementEditHelper is updated to accept subsets of containments also, because the UML2 API implicitly adds elements to the containment superset, ensuring proper attachment of the new element to the model.
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ElementEditHelper.java33
-rw-r--r--plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/model/UmlUtils.java37
2 files changed, 69 insertions, 1 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ElementEditHelper.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ElementEditHelper.java
index aab70c3862e..f99f7dbde3b 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ElementEditHelper.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ElementEditHelper.java
@@ -9,6 +9,7 @@
* Contributors:
* Yann Tanguy (CEA LIST) yann.tanguy@cea.fr - Initial API and implementation
* Christian W. Damus - bug 458685
+ * Christian W. Damus - bug 467016
*
*****************************************************************************/
package org.eclipse.papyrus.uml.service.types.helper;
@@ -16,11 +17,15 @@ package org.eclipse.papyrus.uml.service.types.helper;
import java.util.Map;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.papyrus.infra.gmfdiag.common.helper.DefaultEditHelper;
import org.eclipse.papyrus.infra.services.edit.commands.IConfigureCommandFactory;
+import org.eclipse.papyrus.uml.tools.model.UmlUtils;
import org.eclipse.uml2.uml.Element;
/**
@@ -58,4 +63,32 @@ public class ElementEditHelper extends DefaultEditHelper {
return super.getDefaultContainmentFeatures();
}
+ @Override
+ protected boolean approveRequest(IEditCommandRequest request) {
+ boolean result = super.approveRequest(request);
+
+ if (!result) {
+ if (request instanceof CreateElementRequest) {
+ // Bug 467016: Maybe the "containment" reference isn't actually a containment but subsets one?
+ // e.g., BehavioredClassifier::classifierBehavior subsets BehavioredClassifier::ownedBehavior
+ Object context = request.getEditHelperContext();
+ if (context instanceof EObject) {
+ EObject owner = (EObject) context;
+ EReference reference = getContainmentFeature((CreateElementRequest) request);
+ if ((reference != null) && reference.getEContainingClass().isSuperTypeOf(owner.eClass()) && !reference.isContainment()) {
+ // Look for containment superset. UML2 will do the right thing and add the new
+ // element implicitly to that superset
+ for (EReference next : UmlUtils.getSupersets(reference)) {
+ if (next.isContainment()) {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
}
diff --git a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/model/UmlUtils.java b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/model/UmlUtils.java
index c0efc784a83..8ae60c9a6b7 100644
--- a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/model/UmlUtils.java
+++ b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/model/UmlUtils.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2011, 2014 LIFL, CEA, and others.
+ * Copyright (c) 2011, 2015 LIFL, CEA, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -9,6 +9,7 @@
* Contributors:
* LIFL - Initial API and implementation
* Christian W. Damus (CEA) - bug 431618
+ * Christian W. Damus - bug 467016
*
*****************************************************************************/
package org.eclipse.papyrus.uml.tools.model;
@@ -17,6 +18,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import org.eclipse.emf.ecore.EAnnotation;
@@ -31,6 +33,9 @@ import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers;
import org.eclipse.papyrus.uml.tools.Activator;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
/**
* Set of utility methods linked to Trace for ControlMode
*
@@ -207,4 +212,34 @@ public class UmlUtils {
return result;
}
+
+ /**
+ * Obtains all supersets, including transitive supersets-of-supersets, of the specified {@code subset}.
+ *
+ * @param subset
+ * a subset reference
+ * @return its supersets, or an empty iterable if it is not actually a subset of anything
+ */
+ public static Iterable<EReference> getSupersets(EReference subset) {
+ List<EReference> result;
+
+ EAnnotation supersets = (subset == null) ? null : subset.getEAnnotation(ANNOTATION_SUBSETS);
+ if (supersets == null) {
+ result = Collections.emptyList();
+ } else {
+ result = Lists.newArrayListWithCapacity(supersets.getReferences().size());
+ for (EObject next : supersets.getReferences()) {
+ if (next instanceof EReference) {
+ EReference superset = (EReference) next;
+ result.add(superset);
+ if (isSubset(superset)) {
+ // Look for transitive supersets
+ Iterables.addAll(result, getSupersets(superset));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
}

Back to the top