diff options
author | Fanch BONNABESSE | 2015-10-22 08:50:02 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2015-10-23 14:37:28 +0000 |
commit | 40b9929b81f9439cc1a0c235d20ddbd5c4a4b9ed (patch) | |
tree | 0587c4befec4b9279775a8d7ee07d0bb9739022f /plugins/sysml | |
parent | f17c27f6b74a8aa6987f236b645f21fec7227ac0 (diff) | |
download | org.eclipse.papyrus-40b9929b81f9439cc1a0c235d20ddbd5c4a4b9ed.tar.gz org.eclipse.papyrus-40b9929b81f9439cc1a0c235d20ddbd5c4a4b9ed.tar.xz org.eclipse.papyrus-40b9929b81f9439cc1a0c235d20ddbd5c4a4b9ed.zip |
Bug 478288: [BDD] Bad restore Association/DirectedAssociation
https://bugs.eclipse.org/bugs/show_bug.cgi?id=478288
Comparison of Association to add.
Change-Id: Iad6036d4a768f7ccaa5858d578115a324f721b7d
Signed-off-by: Fanch BONNABESSE <fanch.bonnabesse@all4tec.net>
Diffstat (limited to 'plugins/sysml')
2 files changed, 356 insertions, 190 deletions
diff --git a/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src/org/eclipse/papyrus/sysml/diagram/common/utils/SysMLCreateOrShowExistingElementHelper.java b/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src/org/eclipse/papyrus/sysml/diagram/common/utils/SysMLCreateOrShowExistingElementHelper.java index 1af6e4da783..9bcf5501c7d 100644 --- a/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src/org/eclipse/papyrus/sysml/diagram/common/utils/SysMLCreateOrShowExistingElementHelper.java +++ b/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.common/src/org/eclipse/papyrus/sysml/diagram/common/utils/SysMLCreateOrShowExistingElementHelper.java @@ -1,190 +1,255 @@ -/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.sysml.diagram.common.utils;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gmf.runtime.emf.type.core.IElementType;
-import org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants;
-import org.eclipse.papyrus.sysml.service.types.element.SysMLElementTypes;
-import org.eclipse.papyrus.sysml.service.types.utils.ConnectorUtils;
-import org.eclipse.papyrus.uml.diagram.common.helper.CreateOrShowExistingElementHelper;
-import org.eclipse.papyrus.uml.diagram.common.helper.ILinkMappingHelper;
-import org.eclipse.papyrus.uml.diagram.common.util.LinkEndsMapper;
-import org.eclipse.uml2.uml.AggregationKind;
-import org.eclipse.uml2.uml.Association;
-import org.eclipse.uml2.uml.Connector;
-import org.eclipse.uml2.uml.Element;
-import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.UMLPackage;
-
-/**
- * Show Existing Link Helper for SysML. This class provides specific management for SysML Association.
- *
- * @author VL222926
- *
- */
-public class SysMLCreateOrShowExistingElementHelper extends CreateOrShowExistingElementHelper {
-
- /**
- * the sysml connector util
- */
- private ConnectorUtils sysmlConnectorUtils = new ConnectorUtils();
-
- /**
- *
- * Constructor.
- *
- */
- public SysMLCreateOrShowExistingElementHelper() {
- super();
- }
-
- /**
- *
- * Constructor.
- *
- * @param linkHelper
- */
- public SysMLCreateOrShowExistingElementHelper(final ILinkMappingHelper linkHelper) {
- super(linkHelper);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.uml.diagram.common.helper.CreateOrShowExistingElementHelper#getIElementTypeNameToDisplay(org.eclipse.gmf.runtime.emf.type.core.IElementType)
- *
- * @param elementType
- * @return
- */
- @Override
- protected String getIElementTypeNameToDisplay(final IElementType elementType) {
- if (SysMLElementTypes.ASSOCIATION_NONE.equals(elementType) || SysMLElementTypes.ASSOCIATION_NONE_DIRECTED.equals(elementType)) {
- return "Association/DirectAssociation"; //$NON-NLS-1$
- } else if (SysMLElementTypes.ASSOCIATION_COMPOSITE.equals(elementType) || SysMLElementTypes.ASSOCIATION_COMPOSITE_DIRECTED.equals(elementType)) {
- return "Composition/DirectComposition"; //$NON-NLS-1$
- } else if (SysMLElementTypes.ASSOCIATION_SHARED.equals(elementType) || SysMLElementTypes.ASSOCIATION_SHARED_DIRECTED.equals(elementType)) {
- return "Aggregation/DirectAggregation"; //$NON-NLS-1$
- }
- return super.getIElementTypeNameToDisplay(elementType);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.uml.diagram.common.helper.CreateOrShowExistingElementHelper#hasWantedType(org.eclipse.emf.ecore.EObject, org.eclipse.gmf.runtime.emf.type.core.IElementType)
- *
- * @param eobject
- * an eobject
- * @param wantedType
- * the wanted element type
- * @return
- * true if the eobject is an instance of the wanted element type.
- *
- * Add test for SysML Association
- */
- @Override
- protected boolean hasWantedType(final EObject eobject, final IElementType wantedType) {
- boolean result = super.hasWantedType(eobject, wantedType);
- if (result) {
- if (eobject instanceof Association) {
- Association association = (Association) eobject;
- // Skip incomplete associations: it can't be a duplicate of the current link (Which has a source and a target)
- if (association.getMemberEnds().size() < 2) {
- return false;
- }
-
- final AggregationKind current = getAssociationAggregationKind((Association) eobject);
- if (current == AggregationKind.NONE_LITERAL) {
- if (SysMLElementTypes.ASSOCIATION_NONE.equals(current) || SysMLElementTypes.ASSOCIATION_NONE_DIRECTED.equals(wantedType)) {
- result = true;
- }
- } else if (current == AggregationKind.COMPOSITE_LITERAL) {
- if (SysMLElementTypes.ASSOCIATION_COMPOSITE.equals(current) || SysMLElementTypes.ASSOCIATION_COMPOSITE_DIRECTED.equals(wantedType)) {
- result = true;
- }
- } else if (current == AggregationKind.SHARED_LITERAL) {
- if (SysMLElementTypes.ASSOCIATION_SHARED.equals(current) || SysMLElementTypes.ASSOCIATION_SHARED_DIRECTED.equals(wantedType)) {
- result = true;
- }
- } else {
- result = false;
- }
- }
- }
- return result;
- }
-
- /**
- *
- * @param association
- * an association
- * @return
- * the association kind for the association
- */
- private static final AggregationKind getAssociationAggregationKind(final Association association) {
- // Incomplete associations
- if (association.getMemberEnds().size() < 2) {
- return AggregationKind.NONE_LITERAL;
- }
-
- final Property source = association.getMemberEnds().get(0);
- final Property target = association.getMemberEnds().get(1);
-
- if (source.getAggregation() == AggregationKind.NONE_LITERAL && target.getAggregation() == AggregationKind.NONE_LITERAL) {
- return AggregationKind.NONE_LITERAL;
- } else if ((source.getAggregation() == AggregationKind.COMPOSITE_LITERAL) || (target.getAggregation() == AggregationKind.COMPOSITE_LITERAL)) {
- return AggregationKind.COMPOSITE_LITERAL;
- } else {
- return AggregationKind.SHARED_LITERAL;
- }
-
- }
-
- /**
- * @param request
- * the request for the creation
- * @param wantedEClass
- * @return
- * a list of {@link EdgeEndsMapper} referencing the existing links between the source and the target
- */
- @Override
- protected List<LinkEndsMapper> getExistingLinksBetweenSourceAndTarget(final CreateRelationshipRequest request, final IElementType wantedElementType) {
- if (wantedElementType.getEClass() == UMLPackage.eINSTANCE.getConnector()) {
- final List<LinkEndsMapper> existingElement = new ArrayList<LinkEndsMapper>();
- for (final Element current : ((Element) request.getContainer()).getOwnedElements()) {
- if (hasWantedType(current, wantedElementType)) {
- final Collection<?> sources = this.linkMappingHelper.getSource(current);
- final Collection<?> targets = this.linkMappingHelper.getTarget(current);
-
- if (sources.contains(request.getSource()) && targets.contains(request.getTarget())) {
- // we verify the nestedPath before to propose to restore a connector
- View sourceView = (View) request.getParameter(RequestParameterConstants.EDGE_CREATE_REQUEST_SOURCE_VIEW);
- View targetView = (View) request.getParameter(RequestParameterConstants.EDGE_CREATE_REQUEST_TARGET_VIEW);
- boolean canBeDisplayed = ConnectorUtils.canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths((Connector) current, sourceView, targetView);
- if (canBeDisplayed) {
- existingElement.add(new LinkEndsMapper(current, sources, null, null));
- }
- }
- }
- }
- return existingElement;
- }
- return super.getExistingLinksBetweenSourceAndTarget(request, wantedElementType);
- }
-}
+/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * + * CEA LIST - Initial API and implementation + * Bonnabesse Fanch (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 478288 + * + *****************************************************************************/ +package org.eclipse.papyrus.sysml.diagram.common.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gmf.runtime.emf.type.core.IElementType; +import org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants; +import org.eclipse.papyrus.sysml.service.types.element.SysMLElementTypes; +import org.eclipse.papyrus.sysml.service.types.utils.AssociationUtils; +import org.eclipse.papyrus.sysml.service.types.utils.ConnectorUtils; +import org.eclipse.papyrus.uml.diagram.common.helper.CreateOrShowExistingElementHelper; +import org.eclipse.papyrus.uml.diagram.common.helper.ILinkMappingHelper; +import org.eclipse.papyrus.uml.diagram.common.util.LinkEndsMapper; +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Association; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * Show Existing Link Helper for SysML. This class provides specific management for SysML Association. + * + * @author VL222926 + * + */ +public class SysMLCreateOrShowExistingElementHelper extends CreateOrShowExistingElementHelper { + + /** + * + * Constructor. + * + */ + public SysMLCreateOrShowExistingElementHelper() { + super(); + } + + /** + * + * Constructor. + * + * @param linkHelper + */ + public SysMLCreateOrShowExistingElementHelper(final ILinkMappingHelper linkHelper) { + super(linkHelper); + } + + /** + * + * @see org.eclipse.papyrus.uml.diagram.common.helper.CreateOrShowExistingElementHelper#getIElementTypeNameToDisplay(org.eclipse.gmf.runtime.emf.type.core.IElementType) + * + * @param elementType + * @return + */ + @Override + protected String getIElementTypeNameToDisplay(final IElementType elementType) { + if (SysMLElementTypes.ASSOCIATION_NONE.equals(elementType) || SysMLElementTypes.ASSOCIATION_NONE_DIRECTED.equals(elementType)) { + return "Association/DirectAssociation"; //$NON-NLS-1$ + } else if (SysMLElementTypes.ASSOCIATION_COMPOSITE.equals(elementType) || SysMLElementTypes.ASSOCIATION_COMPOSITE_DIRECTED.equals(elementType)) { + return "Composition/DirectComposition"; //$NON-NLS-1$ + } else if (SysMLElementTypes.ASSOCIATION_SHARED.equals(elementType) || SysMLElementTypes.ASSOCIATION_SHARED_DIRECTED.equals(elementType)) { + return "Aggregation/DirectAggregation"; //$NON-NLS-1$ + } + return super.getIElementTypeNameToDisplay(elementType); + } + + /** + * + * @see org.eclipse.papyrus.uml.diagram.common.helper.CreateOrShowExistingElementHelper#hasWantedType(org.eclipse.emf.ecore.EObject, org.eclipse.gmf.runtime.emf.type.core.IElementType) + * + * @param eobject + * an eobject + * @param wantedType + * the wanted element type + * @return + * true if the eobject is an instance of the wanted element type. + * + * Add test for SysML Association + */ + @Override + protected boolean hasWantedType(final EObject eobject, final IElementType wantedType) { + boolean result = super.hasWantedType(eobject, wantedType); + if (result) { + if (eobject instanceof Association) { + Association association = (Association) eobject; + // Skip incomplete associations: it can't be a duplicate of the current link (Which has a source and a target) + if (association.getMemberEnds().size() < 2) { + return false; + } + + final AggregationKind current = getAssociationAggregationKind((Association) eobject); + if (current == AggregationKind.NONE_LITERAL) { + if (SysMLElementTypes.ASSOCIATION_NONE.equals(current) || SysMLElementTypes.ASSOCIATION_NONE_DIRECTED.equals(wantedType)) { + result = true; + } + } else if (current == AggregationKind.COMPOSITE_LITERAL) { + if (SysMLElementTypes.ASSOCIATION_COMPOSITE.equals(current) || SysMLElementTypes.ASSOCIATION_COMPOSITE_DIRECTED.equals(wantedType)) { + result = true; + } + } else if (current == AggregationKind.SHARED_LITERAL) { + if (SysMLElementTypes.ASSOCIATION_SHARED.equals(current) || SysMLElementTypes.ASSOCIATION_SHARED_DIRECTED.equals(wantedType)) { + result = true; + } + } else { + result = false; + } + } + } + return result; + } + + /** + * + * @param association + * an association + * @return + * the association kind for the association + */ + private static final AggregationKind getAssociationAggregationKind(final Association association) { + // Incomplete associations + if (association.getMemberEnds().size() < 2) { + return AggregationKind.NONE_LITERAL; + } + + final Property source = association.getMemberEnds().get(0); + final Property target = association.getMemberEnds().get(1); + + if (source.getAggregation() == AggregationKind.NONE_LITERAL && target.getAggregation() == AggregationKind.NONE_LITERAL) { + return AggregationKind.NONE_LITERAL; + } else if ((source.getAggregation() == AggregationKind.COMPOSITE_LITERAL) || (target.getAggregation() == AggregationKind.COMPOSITE_LITERAL)) { + return AggregationKind.COMPOSITE_LITERAL; + } else { + return AggregationKind.SHARED_LITERAL; + } + + } + + /** + * @param request + * the request for the creation + * @param wantedEClass + * @return + * a list of {@link EdgeEndsMapper} referencing the existing links between the source and the target + */ + @Override + protected List<LinkEndsMapper> getExistingLinksBetweenSourceAndTarget(final CreateRelationshipRequest request, final IElementType wantedElementType) { + List<LinkEndsMapper> existingElement = null; + + final EClass wantedEClass = wantedElementType.getEClass(); + + if (UMLPackage.eINSTANCE.getConnector().equals(wantedEClass)) { + EList<Element> ownedElements = ((Element) request.getContainer()).getOwnedElements(); + + existingElement = new ArrayList<LinkEndsMapper>(); + + for (final Element current : ownedElements) { + if (hasWantedType(current, wantedElementType)) { + final Collection<?> sources = this.linkMappingHelper.getSource(current); + final Collection<?> targets = this.linkMappingHelper.getTarget(current); + + if (sources.contains(request.getSource()) && targets.contains(request.getTarget())) { + // we verify the nestedPath before to propose to restore a connector + View sourceView = (View) request.getParameter(RequestParameterConstants.EDGE_CREATE_REQUEST_SOURCE_VIEW); + View targetView = (View) request.getParameter(RequestParameterConstants.EDGE_CREATE_REQUEST_TARGET_VIEW); + boolean canBeDisplayed = ConnectorUtils.canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths((Connector) current, sourceView, targetView); + if (canBeDisplayed) { + existingElement.add(new LinkEndsMapper(current, sources, null, null)); + } + } + } + } + + } else if (UMLPackage.eINSTANCE.getAssociation().equals(wantedEClass)) { + final EList<Element> ownedElements = ((Element) request.getContainer()).getOwnedElements(); + + existingElement = new ArrayList<LinkEndsMapper>(); + + for (final Element current : ownedElements) { + if (hasWantedType(current, wantedElementType)) { + final Collection<?> sources = this.linkMappingHelper.getSource(current); + final Collection<?> targets = this.linkMappingHelper.getTarget(current); + + if (sources.contains(request.getSource()) && targets.contains(request.getTarget()) && (current instanceof Association)) { + boolean identicalAssociation = true; + + final Iterator<Property> iterator = ((Association) current).getMemberEnds().iterator(); + + while (iterator.hasNext() && identicalAssociation) { + final Property property = iterator.next(); + + final boolean source = request.getSource().equals(property.getType()); + + // Handle of all types of Association in SysML + if (SysMLElementTypes.ASSOCIATION_NONE_DIRECTED.equals(wantedElementType)) { + if (!AssociationUtils.isIdenticalProperties(false, AggregationKind.NONE_LITERAL, source, property)) { + identicalAssociation = false; + } + } else if (SysMLElementTypes.ASSOCIATION_NONE.equals(wantedElementType)) { + if (!AssociationUtils.isIdenticalProperties(true, AggregationKind.NONE_LITERAL, source, property)) { + identicalAssociation = false; + } + } else if (SysMLElementTypes.ASSOCIATION_COMPOSITE_DIRECTED.equals(wantedElementType)) { + if (!AssociationUtils.isIdenticalProperties(false, AggregationKind.COMPOSITE_LITERAL, source, property)) { + identicalAssociation = false; + } + } else if (SysMLElementTypes.ASSOCIATION_COMPOSITE.equals(wantedElementType)) { + if (!AssociationUtils.isIdenticalProperties(true, AggregationKind.COMPOSITE_LITERAL, source, property)) { + identicalAssociation = false; + } + } else if (SysMLElementTypes.ASSOCIATION_SHARED_DIRECTED.equals(wantedElementType)) { + if (!AssociationUtils.isIdenticalProperties(false, AggregationKind.SHARED_LITERAL, source, property)) { + identicalAssociation = false; + } + } else if (SysMLElementTypes.ASSOCIATION_SHARED.equals(wantedElementType)) { + if (!AssociationUtils.isIdenticalProperties(true, AggregationKind.SHARED_LITERAL, source, property)) { + identicalAssociation = false; + } + } + } + + if (identicalAssociation) { + existingElement.add(new LinkEndsMapper(current, sources, null, null)); + } + } + } + } + } else { + existingElement = super.getExistingLinksBetweenSourceAndTarget(request, wantedElementType); + } + + return existingElement; + } + +} diff --git a/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/AssociationUtils.java b/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/AssociationUtils.java new file mode 100644 index 00000000000..5b3f5e07576 --- /dev/null +++ b/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/AssociationUtils.java @@ -0,0 +1,101 @@ +/***************************************************************************** + * Copyright (c) 2015 CEA LIST and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bonnabesse Fanch (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 478288 + * + *****************************************************************************/ + +package org.eclipse.papyrus.sysml.service.types.utils; + +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Property; + +/** + * Utility class for Association edit helpers. + */ +public class AssociationUtils { + + /** + * This compares the Property of an Association with expected informations. + * + * @param expectedNavigable + * The expected navigable information. + * @param expectedAggregation + * The expected kind of aggregation. + * @param source + * To specify if the member in treatment is a source. + * @param property + * The property containing the aggregation to compare. + * @return The result of the comparison. + */ + public static boolean isIdenticalProperties(final boolean expectedNavigable, final AggregationKind expectedAggregation, final boolean source, final Property property) { + return (isIdenticalAggregations(expectedAggregation, source, property) && isIdenticalNavigables(expectedNavigable, source, property)); + } + + /** + * This compares the aggregation information of a Property with an expected kind of aggregation. + * + * @param expectedAggregation + * The expected kind of aggregation. + * @param source + * To specify if the member in treatment is a source. + * @param property + * The property containing the aggregation to compare. + * @return The result of the comparison. + */ + public static boolean isIdenticalAggregations(final AggregationKind expectedAggregation, final boolean source, final Property property) { + boolean identicalAggregation = false; + + final AggregationKind aggregation = property.getAggregation(); + + if (source) { + // If the member is the source member, the aggregation must be NONE + if (AggregationKind.NONE_LITERAL.equals(aggregation)) { + identicalAggregation = true; + } + + // If the member is the target member, the aggregation must be the same than the expected aggregation + } else if (expectedAggregation.equals(aggregation)) { + identicalAggregation = true; + } + + return identicalAggregation; + } + + /** + * This compares the navigable information of a Property with an expected navigable. + * + * @param expectedNavigable + * The expected navigable information. + * @param source + * To specify if the member in treatment is a source. + * @param property + * The property containing the navigable information to compare. + * @return The result of the comparison. + */ + public static boolean isIdenticalNavigables(final boolean expectedNavigable, final boolean source, final Property property) { + boolean identicalNavigable = false; + + final boolean navigable = property.isNavigable(); + + if (source) { + // If the member is the source member, the navigable value must be the same than the expected navigable + if (expectedNavigable == navigable) { + identicalNavigable = true; + } + + // If the member is the source member, the navigable value must be the same than the expected navigable + } else if (navigable) { + identicalNavigable = true; + } + + return identicalNavigable; + } + +} |