| /****************************************************************************** |
| * Copyright (c) 2009, 2022 Obeo Designer, CEA LIST, Artal Technologies |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| * Aurelien Didier (ARTAL) - aurelien.didier51@gmail.com - adaptation to integrate in Papyrus |
| *****************************************************************************/ |
| package org.eclipse.papyrus.uml.sirius.clazz.diagram.services; |
| |
| import java.awt.Dimension; |
| import java.awt.GridLayout; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import javax.swing.DefaultListModel; |
| import javax.swing.JButton; |
| import javax.swing.JDialog; |
| import javax.swing.JLabel; |
| import javax.swing.JList; |
| import javax.swing.JPanel; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EAnnotation; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.AssociationServices; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.DirectEditLabelSwitch; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.DisplayLabelSwitch; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.EditLabelSwitch; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.ElementServices; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.ILabelConstants; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.LabelServices; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.NodeInverseRefsServices; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.OperationServices; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.StereotypeServices; |
| import org.eclipse.papyrus.uml.sirius.common.diagram.core.services.UIServices; |
| import org.eclipse.sirius.diagram.DDiagram; |
| import org.eclipse.sirius.diagram.DDiagramElement; |
| import org.eclipse.sirius.diagram.DEdge; |
| import org.eclipse.sirius.diagram.DNodeList; |
| import org.eclipse.sirius.diagram.DSemanticDiagram; |
| import org.eclipse.sirius.diagram.EdgeTarget; |
| import org.eclipse.sirius.diagram.model.business.internal.spec.DNodeContainerSpec; |
| import org.eclipse.sirius.diagram.model.business.internal.spec.DNodeListSpec; |
| import org.eclipse.sirius.viewpoint.DSemanticDecorator; |
| import org.eclipse.sirius.viewpoint.FontFormat; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.dialogs.ListDialog; |
| import org.eclipse.uml2.uml.Abstraction; |
| import org.eclipse.uml2.uml.AggregationKind; |
| import org.eclipse.uml2.uml.Association; |
| import org.eclipse.uml2.uml.AssociationClass; |
| import org.eclipse.uml2.uml.Class; |
| import org.eclipse.uml2.uml.Classifier; |
| import org.eclipse.uml2.uml.Comment; |
| import org.eclipse.uml2.uml.Constraint; |
| import org.eclipse.uml2.uml.DataType; |
| import org.eclipse.uml2.uml.Dependency; |
| import org.eclipse.uml2.uml.Element; |
| import org.eclipse.uml2.uml.ElementImport; |
| import org.eclipse.uml2.uml.Enumeration; |
| import org.eclipse.uml2.uml.Feature; |
| import org.eclipse.uml2.uml.Generalization; |
| import org.eclipse.uml2.uml.GeneralizationSet; |
| import org.eclipse.uml2.uml.InformationFlow; |
| import org.eclipse.uml2.uml.InformationItem; |
| import org.eclipse.uml2.uml.InstanceSpecification; |
| import org.eclipse.uml2.uml.Interface; |
| import org.eclipse.uml2.uml.InterfaceRealization; |
| import org.eclipse.uml2.uml.Model; |
| import org.eclipse.uml2.uml.NamedElement; |
| import org.eclipse.uml2.uml.Namespace; |
| import org.eclipse.uml2.uml.OpaqueExpression; |
| import org.eclipse.uml2.uml.Operation; |
| import org.eclipse.uml2.uml.Package; |
| import org.eclipse.uml2.uml.PackageImport; |
| import org.eclipse.uml2.uml.PackageMerge; |
| import org.eclipse.uml2.uml.PackageableElement; |
| import org.eclipse.uml2.uml.PrimitiveType; |
| import org.eclipse.uml2.uml.ProfileApplication; |
| import org.eclipse.uml2.uml.Property; |
| import org.eclipse.uml2.uml.Realization; |
| import org.eclipse.uml2.uml.Stereotype; |
| import org.eclipse.uml2.uml.Substitution; |
| import org.eclipse.uml2.uml.Type; |
| import org.eclipse.uml2.uml.UMLFactory; |
| import org.eclipse.uml2.uml.Usage; |
| import org.eclipse.uml2.uml.ValueSpecification; |
| |
| import com.google.common.collect.Lists; |
| |
| /** |
| * Services to handle typed Element concerns. |
| * |
| */ |
| public class ClassDiagramServices { |
| /** |
| * A singleton instance to be accessed by other java services. |
| */ |
| public static final ClassDiagramServices INSTANCE = new ClassDiagramServices(); |
| |
| /** INSTANCE_END for instance specification eAnnotation */ |
| protected static final String INSTANCE_END = "InstanceEnd"; |
| |
| /** Dialog CANCEL button label */ |
| private static final String CANCEL_LABEL = "Cancel"; |
| |
| /** Dialog OK button label */ |
| private static final String OK_LABEL = "OK"; |
| |
| /** Annotation generic source name */ |
| private static final String ANNOTATION_GENERIC_SOURCE = "org.eclipse.papyrus"; |
| |
| /** Annotation InstanceEnd source name */ |
| private static final String ANNOTATION_INSTANCE_END_SOURCE = "InstanceEnd"; |
| |
| /** Annotation detail key */ |
| private static final String ANNOTATION_DETAIL_KEY = "nature"; |
| |
| /** Annotation detail value */ |
| private static final String ANNOTATION_DETAIL_VALUE = "UML_Nature"; |
| |
| /** underscore separator */ |
| private static final String UNDERSCORE = "_"; |
| |
| /** InstanceSpecification edge */ |
| private InstanceSpecification _instanceSpec; |
| |
| /** Association type for a new created InstanceSpecification */ |
| private String _selectedAssosType = ""; |
| |
| /** |
| * Move the given Element |
| * |
| * @param semanticObjectToDrop |
| * semantic element to drop |
| * @param targetContainerView |
| * the target container view |
| * @return the element |
| */ |
| public EObject dndElement(EObject semanticObjectToDrop, EObject targetContainerView) { |
| if ((targetContainerView instanceof DSemanticDecorator) && (semanticObjectToDrop instanceof PackageableElement)) { |
| Element element = (PackageableElement) semanticObjectToDrop; |
| EObject target = ((DSemanticDecorator) targetContainerView).getTarget(); |
| |
| Model targetModel = null; |
| if (target instanceof Model) { |
| targetModel = (Model) target; |
| } |
| if (targetModel != null) { |
| targetModel.getPackagedElements().add((PackageableElement) element); |
| } |
| |
| } |
| return semanticObjectToDrop; |
| } |
| |
| /** |
| * Create a new Abstraction Link between the source and the target. |
| * |
| * @param context, |
| * the current context |
| * @param sourceview, |
| * the source view |
| * @param source, |
| * the semantic source element |
| * @param target, |
| * the semantic target element |
| * @return nothing |
| */ |
| public static void createAbstractionLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| Abstraction abstraction = UMLFactory.eINSTANCE.createAbstraction(); |
| model.getPackagedElements().add(abstraction); |
| abstraction.getClients().add((NamedElement) source); |
| abstraction.getSuppliers().add((NamedElement) target); |
| } |
| } |
| } |
| |
| /** |
| * Get diagram root. |
| * |
| * @param context |
| * the current context (view) |
| * @return the root diagram owning the element |
| */ |
| private static EObject getDiagramRoot(EObject sourceView) { |
| DDiagramElement diagramElement = (DDiagramElement) sourceView; |
| DSemanticDiagram diagram = (DSemanticDiagram) diagramElement.getParentDiagram(); |
| EObject root = diagram.getTarget(); |
| return root; |
| } |
| |
| /** |
| * This method is in charge to move semantically the target element inside the source element |
| * |
| * @param context |
| * the current context |
| * @param source |
| * the source element |
| * @param target |
| * the target element |
| * |
| */ |
| public static void containmentLinkCreation_moveIntoOwner(final EObject context, final Element source, final Element target) { |
| if (source instanceof Package && target instanceof PackageableElement) { |
| ((Package) source).getPackagedElements().add((PackageableElement) target); |
| } else if (source instanceof Class && target instanceof Classifier) { |
| ((Class) source).getNestedClassifiers().add((Classifier) target); |
| } |
| } |
| |
| /** |
| * Check if the source and target are valid |
| * |
| * @param context |
| * the current context |
| * @param sourceView |
| * the source view |
| * @param targetView |
| * the target view |
| * @param source |
| * the semantic source element |
| * @param target |
| * the semantic target element |
| * @return true if the source and target are valid |
| */ |
| public boolean containmentLink_isValidSourceAndTarget(final EObject context, final EObject sourceView, final EObject targetView, final Element source, final Element target) { |
| if (source == target) { |
| // we forbid reflexive ContainmentLink of course |
| return false; |
| } |
| if (source instanceof Package || source instanceof Class) { |
| if (target instanceof Package || target instanceof Classifier) { |
| if (((Namespace) source).allNamespaces().contains(target)) { |
| // it will create a loop of containment |
| return false; |
| } |
| return true; |
| } |
| } |
| return false; |
| |
| } |
| |
| /** |
| * Service used to determine if the selected containment edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectContainmentLinkPrecondition(Element context, Element target) { |
| // context is previous value |
| // target is newValue |
| // TODO we must validate condition on source/target to forbid the containment of a Package inside a Class for example. |
| // it is not yet possible, see forum https://www.eclipse.org/forums/index.php/m/1853006/#msg_1853006 |
| // see bug 580155 |
| return (target instanceof Class || target instanceof Interface || target instanceof Model |
| || target instanceof Package || target instanceof DataType); |
| } |
| |
| /** |
| * Get the target element for the containment link. |
| * |
| * @param context |
| * the current context |
| * @return containment link lists |
| */ |
| public static List<?> getContainmentLinkTarget(final Element source) { |
| if (source instanceof Class) { |
| return ((Class) source).getNestedClassifiers(); |
| } else if (source instanceof Package) { |
| return ((Package) source).getPackagedElements(); |
| } |
| return null; |
| } |
| |
| /** |
| * Precondition test if sirius diagram or not. |
| * |
| * @param context |
| * the current context |
| * @return true if context is a DDiagram |
| */ |
| public boolean isDDiagram(EObject self) { |
| return self instanceof DDiagram; |
| } |
| |
| /** |
| * Precondition check is data type. |
| * |
| * @param context |
| * the current context |
| * @return true is DataType and not enumeration or PrimitiveType |
| */ |
| public boolean isDataType(EObject context) { |
| return !(context instanceof Enumeration || context instanceof PrimitiveType); |
| } |
| |
| /** |
| * Get the feature to contain the element |
| * |
| * @param context |
| * the current context |
| * @return the target feature |
| */ |
| public String getTypeTarget(EObject context) { |
| if (context instanceof Class || context instanceof Interface) { |
| return "nestedClassifier"; |
| } |
| |
| return "packagedElement"; |
| } |
| |
| /** |
| * Get the feature to contain the element |
| * |
| * @param context |
| * the current context |
| * @param newContainerView |
| * the new container view |
| * @return the target name |
| */ |
| public String getTypeTarget(EObject context, EObject newContainerView) { |
| if (newContainerView instanceof Class || newContainerView instanceof Interface) { |
| return "nestedClassifier"; |
| } |
| |
| return "packagedElement"; |
| } |
| |
| /** |
| * Create a new Dependency Link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createDependencyLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| Dependency dependency = UMLFactory.eINSTANCE.createDependency(); |
| dependency.getClients().add((NamedElement) source); |
| dependency.getSuppliers().add((NamedElement) target); |
| |
| if (source instanceof Class) { |
| model.getPackagedElements().add(dependency); |
| } else if (source instanceof Package) { |
| ((Package) source).getPackagedElements().add(dependency); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Create a new Association Class Link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public AssociationClass createAssociationClassLink(EObject context, EObject sourceView, Element source, |
| Element target) { |
| AssociationClass associationClass = null; |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| associationClass = UMLFactory.eINSTANCE.createAssociationClass(); |
| model.getPackagedElements().add(associationClass); |
| associationClass.setName(LabelServices.INSTANCE.computeDefaultName(associationClass)); |
| |
| final Property end1 = AssociationServices.INSTANCE.createAssociationClassEnd((Type) source); |
| associationClass.getMemberEnds().add(end1); |
| final Property end2 = AssociationServices.INSTANCE.createAssociationClassEnd((Type) target); |
| associationClass.getMemberEnds().add(end2); |
| |
| end1.setAssociation(associationClass); |
| end2.setAssociation(associationClass); |
| associationClass.getOwnedEnds().add(end1); |
| associationClass.getOwnedEnds().add(end2); |
| |
| EAnnotation eAnnotation = associationClass.createEAnnotation(ANNOTATION_GENERIC_SOURCE); |
| eAnnotation.getDetails().put(ANNOTATION_DETAIL_KEY, ANNOTATION_DETAIL_VALUE); |
| associationClass.getEAnnotations().add(eAnnotation); |
| } |
| } |
| return associationClass; |
| } |
| |
| /** |
| * Create a new Element Import Link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createElementImportLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| PackageableElement sourceElement = (PackageableElement) source; |
| PackageableElement targetElement = (PackageableElement) target; |
| ElementImport elemImport = UMLFactory.eINSTANCE.createElementImport(); |
| elemImport.setImportedElement(targetElement); |
| ((Namespace) sourceElement).getElementImports().add(elemImport); |
| } |
| } |
| } |
| |
| /** |
| * Create a new Generalization Link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createGeneralizationLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Classifier sourceElement = (Classifier) source; |
| Classifier targetElement = (Classifier) target; |
| Generalization generalization = UMLFactory.eINSTANCE.createGeneralization(); |
| generalization.setGeneral(targetElement); |
| sourceElement.getGeneralizations().add(generalization); |
| } |
| } |
| } |
| |
| /** |
| * Create a new Information Flow Link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createInformationFlowLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| InformationFlow informationFlow = UMLFactory.eINSTANCE.createInformationFlow(); |
| informationFlow.getInformationSources().add((NamedElement) source); |
| informationFlow.getInformationTargets().add((NamedElement) target); |
| |
| if (source instanceof Classifier) { |
| model.getPackagedElements().add(informationFlow); |
| } else if (source instanceof Package) { |
| ((Package) source).getPackagedElements().add(informationFlow); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Check if the target element is an Interface or not. |
| */ |
| public boolean isNotInterfaceTarget(EObject elem) { |
| return elem instanceof InterfaceRealization; |
| } |
| |
| /** |
| * Create a new Interface Realization Link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public InterfaceRealization createInterfaceRealizationLink(EObject context, EObject sourceView, Element source, |
| Element target) { |
| InterfaceRealization interfaceRealization = null; |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| if (source instanceof Class && target instanceof Interface) { |
| Class sourceElement = (Class) source; |
| Interface targetElement = (Interface) target; |
| interfaceRealization = UMLFactory.eINSTANCE.createInterfaceRealization(); |
| interfaceRealization.getClients().add(sourceElement); |
| interfaceRealization.getSuppliers().add(targetElement); |
| interfaceRealization.setContract(targetElement); |
| sourceElement.getInterfaceRealizations().add(interfaceRealization); |
| } |
| } |
| } |
| return interfaceRealization; |
| } |
| |
| /** |
| * Check if the current link type is corresponding to the linkTypeName. |
| */ |
| public boolean isCurrentLinkType(EObject elem, String linkTypeName) { |
| return elem.getClass().getSimpleName().equalsIgnoreCase(linkTypeName); |
| } |
| |
| /** |
| * Create a new Realization link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createRealizationLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| Realization realization = UMLFactory.eINSTANCE.createRealization(); |
| realization.getClients().add((NamedElement) source); |
| realization.getSuppliers().add((NamedElement) target); |
| |
| if (source instanceof Package) { |
| ((Package) source).getPackagedElements().add(realization); |
| } else { |
| model.getPackagedElements().add(realization); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Create a new Substitution link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createSubstitutionLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Classifier sourceElement = (Classifier) source; |
| Classifier targetElement = (Classifier) target; |
| Substitution substitution = UMLFactory.eINSTANCE.createSubstitution(); |
| substitution.getClients().add(sourceElement); |
| substitution.getSuppliers().add(targetElement); |
| substitution.setContract(targetElement); |
| ((Classifier) sourceElement).getSubstitutions().add(substitution); |
| } |
| } |
| } |
| |
| /** |
| * Create a new Package Import link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createPackageImportLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package sourceElement = (Package) source; |
| Package targetElement = (Package) target; |
| PackageImport packageImport = UMLFactory.eINSTANCE.createPackageImport(); |
| packageImport.setImportedPackage(targetElement); |
| sourceElement.getPackageImports().add(packageImport); |
| } |
| } |
| |
| } |
| |
| /** |
| * Create a new Package Merge link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createPackageMergeLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package sourceElement = (Package) source; |
| Package targetElement = (Package) target; |
| PackageMerge packageMerge = UMLFactory.eINSTANCE.createPackageMerge(); |
| packageMerge.setMergedPackage(targetElement); |
| sourceElement.getPackageMerges().add(packageMerge); |
| } |
| } |
| |
| } |
| |
| /** |
| * Create a new Usage link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createUsageLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| NamedElement sourceElement = (NamedElement) source; |
| NamedElement targetElement = (NamedElement) target; |
| Usage usage = UMLFactory.eINSTANCE.createUsage(); |
| usage.getClients().add(sourceElement); |
| usage.getSuppliers().add(targetElement); |
| |
| if (source instanceof Package) { |
| ((Package) source).getPackagedElements().add(usage); |
| } else { |
| model.getPackagedElements().add(usage); |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * Create a new Generalization Set link. |
| * |
| * @param sourceView |
| * the source view |
| * @param target |
| * the semantic target element |
| * @param targetView |
| * the target view |
| */ |
| public void createGeneralizationSetLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| Generalization generalization1 = (Generalization) source; |
| Generalization generalization2 = (Generalization) target; |
| |
| GeneralizationSet generalizationSet = UMLFactory.eINSTANCE.createGeneralizationSet(); |
| model.getPackagedElements().add(generalizationSet); |
| |
| // build name |
| String name = LabelServices.INSTANCE.computeDefaultName(generalizationSet); |
| String firstGeneralisationClassName = ((Classifier) generalization1.getGeneral()).getName(); |
| String secondGeneralisationClassName = ((Classifier) generalization2.getGeneral()).getName(); |
| name = name + UNDERSCORE + firstGeneralisationClassName + UNDERSCORE + secondGeneralisationClassName; |
| generalizationSet.setName(name); |
| |
| generalizationSet.getGeneralizations().add(generalization1); |
| generalizationSet.getGeneralizations().add(generalization2); |
| } |
| } |
| } |
| |
| /** |
| * Get the source element of the Generalization link. |
| */ |
| public EObject getSourceGeneralization(EObject elem) { |
| if (elem instanceof GeneralizationSet) { |
| GeneralizationSet generalizationSet = (GeneralizationSet) elem; |
| return generalizationSet.getGeneralizations().get(0); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get the target element of the Generalization link. |
| */ |
| public EObject getTargetGeneralization(EObject elem) { |
| if (elem instanceof GeneralizationSet) { |
| GeneralizationSet generalizationSet = (GeneralizationSet) elem; |
| return generalizationSet.getGeneralizations().get(1); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Create a new Link link. |
| * |
| * @param sourceView |
| * the source view |
| * @param source |
| * the semantic source element |
| * @param target |
| * the semantic target element |
| */ |
| public void createLink(EObject context, EObject sourceView, Element source, Element target) { |
| if (source instanceof Comment) { |
| ((Comment) source).getAnnotatedElements().add(target); |
| } else if (source instanceof Constraint) { |
| ((Constraint) source).getConstrainedElements().add(target); |
| } |
| } |
| |
| /** |
| * Get the target element of the Link link. |
| */ |
| public static EList<?> getLinkTarget(Element source) { |
| if (source instanceof Constraint) { |
| Constraint sourceElement = (Constraint) source; |
| return sourceElement.getConstrainedElements(); |
| } else if (source instanceof Comment) { |
| Comment sourceElement = (Comment) source; |
| return sourceElement.getAnnotatedElements(); |
| } |
| return null; |
| } |
| |
| /** |
| * Get the Constraint label. |
| */ |
| public String getConstraintLabel(Element elem) { |
| StringBuilder constLabel = new StringBuilder(); |
| String body = ""; |
| String lang = ""; |
| if (elem instanceof Constraint) { |
| Constraint constraint = ((Constraint) elem); |
| ValueSpecification valueSpec = constraint.getSpecification(); |
| if (valueSpec instanceof OpaqueExpression) { |
| OpaqueExpression opaqueEsp = (OpaqueExpression) valueSpec; |
| if (!opaqueEsp.getBodies().isEmpty()) { |
| body = opaqueEsp.getBodies().get(0); |
| } |
| if (!opaqueEsp.getLanguages().isEmpty()) { |
| lang = opaqueEsp.getLanguages().get(0); |
| } |
| |
| List<Stereotype> appliedStereoTypes = constraint.getAppliedStereotypes(); |
| if (!appliedStereoTypes.isEmpty()) { |
| constLabel.append(ILabelConstants.ST_LEFT); |
| } |
| for (int i = 0; i < constraint.getAppliedStereotypes().size(); i++) { |
| Stereotype stereoType = appliedStereoTypes.get(i); |
| constLabel.append(stereoType.getName()); |
| if (i + 1 == appliedStereoTypes.size()) { |
| constLabel.append(ILabelConstants.ST_RIGHT); |
| } else { |
| constLabel.append(","); //$NON-NLS-1$ |
| } |
| } |
| constLabel.append(constraint.getName()); |
| constLabel.append(ILabelConstants.NL); |
| constLabel.append("{{" + lang + "} " + body + "}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| } |
| |
| return constLabel.toString(); |
| } |
| |
| |
| /** |
| * Get the Constraint text body. |
| */ |
| public String getBody(EObject elem) { |
| Constraint constraint = ((Constraint) elem); |
| ValueSpecification valueSpec = constraint.getSpecification(); |
| if (valueSpec instanceof OpaqueExpression) { |
| OpaqueExpression opaqueEsp = (OpaqueExpression) valueSpec; |
| if (!opaqueEsp.getBodies().isEmpty()) { |
| return opaqueEsp.getBodies().get(0); |
| } |
| } |
| return ""; |
| } |
| |
| /** |
| * Compute label for InformationItem |
| * |
| * @param elem |
| * the current element |
| * @return the label of element |
| */ |
| public String buildLabel(Element element) { |
| StringBuilder labelBuilder = new StringBuilder(); |
| String name = LabelServices.INSTANCE.computeUmlLabel(element); |
| String prefix; |
| if (element instanceof InformationItem) { |
| prefix = "Information"; //$NON-NLS-1$ |
| } else if (element instanceof PrimitiveType) { |
| prefix = "Primitive"; //$NON-NLS-1$ |
| } else { |
| prefix = element.eClass().getName(); |
| } |
| prefix = ILabelConstants.ST_LEFT + prefix + ILabelConstants.ST_RIGHT; |
| |
| if (!name.startsWith(prefix)) { |
| labelBuilder.append(prefix); |
| labelBuilder.append(ILabelConstants.NL); |
| labelBuilder.append(name); |
| return labelBuilder.toString(); |
| } |
| |
| return name; |
| } |
| |
| /** |
| * Set the Constraint body. |
| */ |
| public void setConstraintBody(Element elem, String bodyValue) { |
| if (elem instanceof Constraint) { |
| ValueSpecification valueSpec = ((Constraint) elem).getSpecification(); |
| if (valueSpec instanceof OpaqueExpression) { |
| OpaqueExpression opaqueEsp = (OpaqueExpression) valueSpec; |
| |
| if (!opaqueEsp.getBodies().isEmpty()) { |
| opaqueEsp.getBodies().remove(0); |
| opaqueEsp.getBodies().add(0, bodyValue); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Create a new Instance Specification link. |
| * |
| * @param context |
| * the context element |
| * @param sourceView |
| * the source view |
| * @param source |
| * the semantic source element |
| * @param target |
| * the semantic target element |
| * @return the instance specification to create |
| */ |
| public InstanceSpecification createInstanceSpecification(EObject context, EObject sourceView, Element source, |
| Element target) { |
| JDialog dialog = new JDialog(); |
| GridLayout layout = new GridLayout(3, 1); |
| layout.setVgap(5); |
| dialog.setLayout(layout); |
| dialog.setModal(true); |
| dialog.setAlwaysOnTop(true); |
| dialog.setTitle("AssociationSelection"); |
| dialog.setSize(new Dimension(350, 200)); |
| |
| dialog.add(new JLabel("Select the association for this instanceSpecification")); |
| |
| // create OK button for the dialog |
| JButton okButton = new JButton(OK_LABEL); |
| okButton.setEnabled(false); |
| |
| // create associationType list for the dialog |
| DefaultListModel<String> assosTypesList = new DefaultListModel<String>(); |
| assosTypesList.addElement("<untyped>"); |
| JList<String> list = new JList<String>(assosTypesList); |
| list.addListSelectionListener(new ListSelectionListener() { |
| public void valueChanged(ListSelectionEvent e) { |
| if (e.getValueIsAdjusting() == false) { |
| _selectedAssosType = list.getSelectedValue(); |
| okButton.setEnabled(true); |
| } |
| } |
| }); |
| |
| dialog.add(list); |
| |
| // add listener to OK button |
| okButton.addActionListener(new ActionListener() { |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| if (source instanceof InstanceSpecification && target instanceof InstanceSpecification) { |
| _instanceSpec = UMLFactory.eINSTANCE.createInstanceSpecification(); |
| EAnnotation endtypes = _instanceSpec.createEAnnotation(ANNOTATION_INSTANCE_END_SOURCE); |
| endtypes.getReferences().add(source); |
| endtypes.getReferences().add(target); |
| } |
| } |
| } |
| dialog.setVisible(false); |
| |
| } |
| }); |
| |
| // create Cancel button for the dialog |
| JButton cancelButton = new JButton(CANCEL_LABEL); |
| cancelButton.addActionListener(new ActionListener() { |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| dialog.setVisible(false); |
| |
| } |
| }); |
| |
| JPanel buttonsPane = new JPanel(); |
| buttonsPane.setLayout(new GridLayout(1, 2)); |
| buttonsPane.add(okButton); |
| buttonsPane.add(cancelButton); |
| dialog.add(buttonsPane); |
| dialog.setVisible(true); |
| |
| return _instanceSpec; |
| } |
| |
| /** |
| * Add the new created instance specification to the model |
| * |
| * @param context |
| * the new created instance specification |
| * @param sourceView |
| * the source view |
| */ |
| public void addInstanceSpecificationToModel(EObject context, EObject sourceView) { |
| if (sourceView instanceof DDiagramElement) { |
| EObject root = getDiagramRoot(sourceView); |
| if (root instanceof Package) { |
| Package model = (Package) root; |
| InstanceSpecification createdInstanceSpec = (InstanceSpecification) context; |
| model.getPackagedElements().add(createdInstanceSpec); |
| createdInstanceSpec.setName(LabelServices.INSTANCE.computeDefaultName(createdInstanceSpec)); |
| } |
| } |
| } |
| |
| |
| |
| /** |
| * Service used to determine if the selected Dependency edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectDependencyLinkPrecondition(Element context, Element target) { |
| return (target instanceof Class || target instanceof Package || target instanceof Interface |
| || target instanceof Enumeration || target instanceof PrimitiveType); |
| } |
| |
| /** |
| * Service used to determine if the selected ElementImport edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectElementImportLinkPrecondition(Element context, Element target) { |
| return (target instanceof Class || target instanceof Package || target instanceof Interface |
| || target instanceof Enumeration || target instanceof PrimitiveType); |
| } |
| |
| /** |
| * Service used to determine if the selected Generalization edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectGeneralizationLinkPrecondition(Element context, Element target) { |
| return (target instanceof Class || target instanceof Interface || target instanceof Enumeration |
| || target instanceof PrimitiveType); |
| } |
| |
| /** |
| * Service used to determine if the selected GeneralizationSet edge target could |
| * be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectGeneralizationSetLinkPrecondition(Element context, Element target) { |
| return target instanceof Generalization; |
| } |
| |
| /** |
| * Service used to determine if the selected InformationFlow edge target could |
| * be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectInformationFlowLinkPrecondition(Element context, Element target) { |
| return (target instanceof Class || target instanceof Package || target instanceof Interface |
| || target instanceof Enumeration || target instanceof PrimitiveType); |
| } |
| |
| /** |
| * Service used to determine if the selected InstanceSpecification edge target |
| * could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectInstanceSpecLinkPrecondition(Element context, Element target) { |
| return target instanceof InstanceSpecification; |
| } |
| |
| /** |
| * Service used to determine if the selected PackageImport/PackageMerge edge |
| * source could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectPackageImportMergeLinkSourcePrecondition(Element context, Element newSource) { |
| return newSource instanceof Package && !(newSource instanceof Model); |
| } |
| |
| /** |
| * Service used to determine if the selected Realization edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectRealizationLinkPrecondition(Element context, Element newSource) { |
| return newSource instanceof Class || newSource instanceof Interface || newSource instanceof Enumeration |
| || newSource instanceof PrimitiveType || newSource instanceof Package |
| || newSource instanceof InstanceSpecification; |
| } |
| |
| /** |
| * Service used to determine if the selected Substitution edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectSubstitutionLinkPrecondition(Element context, Element newSource) { |
| return newSource instanceof Class || newSource instanceof Interface || newSource instanceof Enumeration |
| || newSource instanceof PrimitiveType; |
| } |
| |
| /** |
| * Service used to determine if the selected InterfaceRealization edge source |
| * could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectInterfaceRealizationLinkSourcePrecondition(Element context, Element newSource) { |
| return newSource instanceof Class; |
| } |
| |
| /** |
| * Service used to determine if the selected InterfaceRealization edge target |
| * could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newTarget |
| * Represents the target element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectInterfaceRealizationLinkTargetPrecondition(Element context, Element newTarget) { |
| return newTarget instanceof Interface; |
| } |
| |
| /** |
| * Service used to determine if the selected Usage edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectUsageLinkPrecondition(Element context, Element newSource) { |
| return newSource instanceof Class || newSource instanceof Package || newSource instanceof Interface |
| || newSource instanceof Enumeration || newSource instanceof PrimitiveType; |
| } |
| |
| /** |
| * Service used to determine if the selected Link edge source could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectLinkSourcePrecondition(Element context, Element newSource) { |
| return newSource instanceof Constraint || newSource instanceof Comment; |
| } |
| |
| /** |
| * Service used to determine if the selected Link edge target could be |
| * reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newSource |
| * Represents the source element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectLinkTargetPrecondition(Element context, Element newSource) { |
| return newSource instanceof Constraint || newSource instanceof Comment |
| || newSource instanceof PrimitiveType || newSource instanceof Enumeration |
| || newSource instanceof Package || newSource instanceof Interface || newSource instanceof Class; |
| } |
| |
| /** |
| * Service used to determine if the selected PackageImport/PackageMerge edge |
| * target could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param newTarget |
| * Represents the target element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectPackageImportMergeLinkTargetPrecondition(Element context, Element newtarget) { |
| return newtarget instanceof Package; |
| } |
| |
| /** |
| * Service used to determine if the selected Association edge source/target |
| * could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectAssociationLinkPrecondition(Element context, Element target) { |
| return target instanceof Class || target instanceof Interface || target instanceof Enumeration |
| || target instanceof PrimitiveType; |
| } |
| |
| /** |
| * Service used to determine if the selected Abstraction edge source/target |
| * could be reconnected to an element. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return true if the edge could be reconnected |
| */ |
| public boolean reconnectAbstractionLinkPrecondition(Element context, Element target) { |
| return target instanceof Class || target instanceof Interface || target instanceof Enumeration |
| || target instanceof PrimitiveType; |
| } |
| |
| /** |
| * Service used to reconnect a Containment Link source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param sourceView |
| * Represents the graphical element pointed by the edge before |
| * reconnecting |
| * @param targetView |
| * Represents the graphical element pointed by the edge after |
| * reconnecting |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectContainementLinkSource(Element context, DEdge edgeView, EdgeTarget sourceView, EdgeTarget targetView, Element oldSource, Element newSource) { |
| if (oldSource instanceof Class) { // if the old source is a Class |
| |
| // remove the target from the old source class and add it to the new source |
| // class |
| Classifier target = (Classifier) ((DNodeContainerSpec) edgeView.getTargetNode()).getTarget(); |
| ((Class) oldSource).getNestedClassifiers().remove(target); |
| if (newSource instanceof Class) { |
| ((Class) newSource).getNestedClassifiers().add(target); |
| } else if (newSource instanceof Package) { |
| ((Package) newSource).getPackagedElements().add(target); |
| } |
| } else if (oldSource instanceof Package) {// if the old source is a Package |
| // remove the target from the old source package and add it to the new source |
| // package |
| PackageableElement target = (PackageableElement) ((DNodeContainerSpec) edgeView.getTargetNode()) |
| .getTarget(); |
| ((Package) oldSource).getPackagedElements().remove(target); |
| |
| if (newSource instanceof Class) { |
| ((Class) newSource).getNestedClassifiers().add((Classifier) target); |
| } else if (newSource instanceof Package) { |
| ((Package) newSource).getPackagedElements().add(target); |
| } |
| } |
| } |
| |
| /** |
| * Service used to reconnect a Containment Link target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param sourceView |
| * Represents the graphical element pointed by the edge before |
| * reconnecting |
| * @param targetView |
| * Represents the graphical element pointed by the edge after |
| * reconnecting |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectContainementLinkTarget(Element context, DEdge edgeView, EdgeTarget sourceView, |
| EdgeTarget targetView, Element oldTarget, Element newTarget) { |
| // get the root model of the diagram |
| Model rootModel = getRootModel(oldTarget); |
| |
| // if the old target element is a Class |
| if (oldTarget instanceof Class) { |
| // remove old target from the class source and add the new target |
| Class source = (Class) ((DNodeContainerSpec) edgeView.getSourceNode()).getTarget(); |
| ((Class) source).getNestedClassifiers().remove(oldTarget); |
| ((Class) source).getNestedClassifiers().add((Classifier) newTarget); |
| } |
| // if the old target element is a Package |
| else if (oldTarget instanceof Package) { |
| // remove old target from the package source and add the new target |
| Package source = (Package) ((DNodeContainerSpec) edgeView.getSourceNode()).getTarget(); |
| source.getPackagedElements().remove(oldTarget); |
| source.getPackagedElements().add((PackageableElement) newTarget); |
| } |
| |
| // keep the old target (Class or Package) in the root model |
| if (oldTarget instanceof Class) { |
| rootModel.getPackagedElements().add((Class) oldTarget); |
| } else if (oldTarget instanceof Package) { |
| rootModel.getPackagedElements().add((Package) oldTarget); |
| } |
| } |
| |
| /** |
| * Get the root model of the diagram |
| */ |
| private Model getRootModel(Element element) { |
| Model currentModel = element.getModel(); |
| if (!element.equals(currentModel)) { |
| currentModel = getRootModel(currentModel); |
| } |
| |
| return currentModel; |
| } |
| |
| /** |
| * Service used to reconnect a Dependency edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectDependencyEdgeSource(Element context, Element oldSource, Element newSource) { |
| // get the root model of the diagram |
| Model rootModel = getRootModel(oldSource); |
| |
| // remove the old source from the Dependency edge and to it the new source |
| Dependency dependencyEdge = (Dependency) context; |
| dependencyEdge.getClients().remove(oldSource); |
| dependencyEdge.getClients().add((NamedElement) newSource); |
| |
| if (oldSource instanceof Package && !(newSource instanceof Package)) { |
| // remove the dependencyEdge from the old source Package and keep it in the root |
| // model |
| ((Package) oldSource).getPackagedElements().remove(dependencyEdge); |
| rootModel.getPackagedElements().add(dependencyEdge); |
| } else if (newSource instanceof Package && !(oldSource instanceof Package)) { |
| // add the dependencyEdge to the new source Package and remove it from the root |
| // model |
| ((Package) newSource).getPackagedElements().add(dependencyEdge); |
| rootModel.getPackagedElements().remove(dependencyEdge); |
| } |
| } |
| |
| /** |
| * Service used to reconnect a Containment edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param sourceView |
| * Represents the graphical element pointed by the edge before |
| * reconnecting |
| * @param targetView |
| * Represents the graphical element pointed by the edge after |
| * reconnecting |
| * @param source |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectDependencyEdgeTarget(Element context, DEdge edgeView, EdgeTarget sourceView, |
| EdgeTarget targetView, Element source, Element target) { |
| Dependency dependencyEdge = (Dependency) context; |
| dependencyEdge.getSuppliers().remove(source); |
| dependencyEdge.getSuppliers().add((NamedElement) target); |
| } |
| |
| /** |
| * Service used to reconnect an ElementImport edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param sourceView |
| * Represents the graphical element pointed by the edge before |
| * reconnecting |
| * @param targetView |
| * Represents the graphical element pointed by the edge after |
| * reconnecting |
| * @param source |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectElementImportEdgeSource(Element context, Element source, Element target) { |
| ElementImport elementImportEdge = (ElementImport) context; |
| ((Namespace) source).getElementImports().remove(elementImportEdge); |
| ((Namespace) target).getElementImports().add(elementImportEdge); |
| } |
| |
| /** |
| * Service used to reconnect an ElementImport edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * reconnecting |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectElementImportEdgeTarget(Element context, Element source, Element target) { |
| ElementImport elementImportEdge = (ElementImport) context; |
| elementImportEdge.setImportedElement((PackageableElement) target); |
| } |
| |
| /** |
| * Service used to reconnect a Generalization edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param source |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectGeneralizationEdgeSource(Element context, Element source, Element target) { |
| Generalization generalizationEdge = (Generalization) context; |
| ((Classifier) source).getGeneralizations().remove(generalizationEdge); |
| ((Classifier) target).getGeneralizations().add(generalizationEdge); |
| } |
| |
| /** |
| * Service used to reconnect a Generalization edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param source |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectGeneralizationEdgeTarget(Element context, Element source, Element target) { |
| Generalization generalizationEdge = (Generalization) context; |
| generalizationEdge.setGeneral((Classifier) target); |
| } |
| |
| /** |
| * Service used to reconnect a GeneralizationSet edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectGeneralizationSetEdgeSource(Element context, Element oldSource, Element newSource) { |
| // get the old and new source generalization elements |
| GeneralizationSet generalizationSet = (GeneralizationSet) context; |
| Generalization oldSourceGeneralization = (Generalization) oldSource; |
| Generalization newSourceGeneralization = (Generalization) newSource; |
| |
| // delete the old source generalization from the generalizations set and add the |
| // new source one |
| generalizationSet.getGeneralizations().add(0, newSourceGeneralization); |
| generalizationSet.getGeneralizations().remove(oldSource); |
| |
| // build new name for the generalization set |
| String newSourceName = newSourceGeneralization.getGeneral().getName(); |
| String oldSourceName = oldSourceGeneralization.getGeneral().getName(); |
| |
| String newName = generalizationSet.getName().replace(oldSourceName, newSourceName); |
| generalizationSet.setName(newName); |
| } |
| |
| /** |
| * Service used to reconnect a GeneralizationSet edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectGeneralizationSetEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| GeneralizationSet generalizationSet = (GeneralizationSet) context; |
| Generalization oldTargetGeneralization = (Generalization) oldTarget; |
| Generalization newTargetGeneralization = (Generalization) newTarget; |
| |
| generalizationSet.getGeneralizations().add(1, newTargetGeneralization); |
| generalizationSet.getGeneralizations().remove(oldTargetGeneralization); |
| |
| // build new name |
| String newTargetName = newTargetGeneralization.getGeneral().getName(); |
| String oldTargetName = oldTargetGeneralization.getGeneral().getName(); |
| |
| String newName = generalizationSet.getName().replace(oldTargetName, newTargetName); |
| generalizationSet.setName(newName); |
| } |
| |
| /** |
| * Service used to reconnect an InformationFlow edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectInformationFlowEdgeSource(Element context, Element oldSource, Element newSource) { |
| // get the root model of the diagram |
| Model rootModel = getRootModel(oldSource); |
| |
| // remove the old source from the information flow element and add to it the new |
| // source |
| InformationFlow informationFlow = (InformationFlow) context; |
| informationFlow.getInformationSources().remove(oldSource); |
| informationFlow.getInformationSources().add((NamedElement) newSource); |
| |
| // keep the removed old source in the root model |
| if (oldSource instanceof Package && !(newSource instanceof Package)) { |
| ((Package) oldSource).getPackagedElements().remove(informationFlow); |
| rootModel.getPackagedElements().add(informationFlow); |
| } else if (newSource instanceof Package && !(oldSource instanceof Package)) { |
| ((Package) newSource).getPackagedElements().add(informationFlow); |
| rootModel.getPackagedElements().remove(informationFlow); |
| } |
| } |
| |
| /** |
| * Service used to reconnect an informationFlow edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectInformationFlowEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| InformationFlow informationFlow = (InformationFlow) context; |
| informationFlow.getInformationTargets().remove(oldTarget); |
| informationFlow.getInformationTargets().add((NamedElement) newTarget); |
| } |
| |
| /** |
| * Service used to reconnect an InstanceSpecifictaion edge source/target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectInstanceSpecEdge(Element context, Element oldSource, Element newSource) { |
| InstanceSpecification instanceSpec = (InstanceSpecification) context; |
| EAnnotation eAnnotation = instanceSpec.getEAnnotations().get(0); |
| eAnnotation.getReferences().remove(oldSource); |
| eAnnotation.getReferences().add((InstanceSpecification) newSource); |
| } |
| |
| /** |
| * Service used to reconnect an PacakgeImport edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectPackageImportEdgeSource(Element context, Element oldSource, Element newSource) { |
| PackageImport packageImport = (PackageImport) context; |
| ((Package) oldSource).getPackageImports().remove(packageImport); |
| ((Package) newSource).getPackageImports().add(packageImport); |
| } |
| |
| /** |
| * Service used to reconnect a PacakgeImport edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectPackageImportEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| PackageImport packageImport = (PackageImport) context; |
| packageImport.setImportedPackage((Package) newTarget); |
| } |
| |
| /** |
| * Service used to reconnect a PackageMerge edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectPackageMergeEdgeSource(Element context, Element oldSource, Element newSource) { |
| PackageMerge packageMerged = (PackageMerge) context; |
| ((Package) oldSource).getPackageMerges().remove(packageMerged); |
| ((Package) newSource).getPackageMerges().add(packageMerged); |
| } |
| |
| /** |
| * Service used to reconnect a PackageMerge edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectPackageMergeEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| PackageMerge packageMerged = (PackageMerge) context; |
| packageMerged.setMergedPackage((Package) newTarget); |
| } |
| |
| /** |
| * Service used to reconnect a Realization edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| |
| public void reconnectRealizationEdgeSource(Element context, Element oldSource, Element newSource) { |
| // get the root model of the diagram |
| Model rootModel = getRootModel(oldSource); |
| |
| // remove the old source from the realization element and add the new source |
| Realization realizationEdge = (Realization) context; |
| realizationEdge.getClients().remove(oldSource); |
| realizationEdge.getClients().add((NamedElement) newSource); |
| |
| // keep the removed old source in the root model |
| if (oldSource instanceof Package && !(newSource instanceof Package)) { |
| ((Package) oldSource).getPackagedElements().remove(realizationEdge); |
| rootModel.getPackagedElements().add(realizationEdge); |
| } else if (newSource instanceof Package && !(oldSource instanceof Package)) { |
| ((Package) newSource).getPackagedElements().add(realizationEdge); |
| rootModel.getPackagedElements().remove(realizationEdge); |
| } |
| } |
| |
| /** |
| * Service used to reconnect a Realization edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectRealizationEdgeTarget(Element context, Element source, Element target) { |
| Realization realizationEdge = (Realization) context; |
| realizationEdge.getSuppliers().remove(source); |
| realizationEdge.getSuppliers().add((NamedElement) target); |
| } |
| |
| /** |
| * Service used to reconnect a Substitution edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectSubstitutionEdgeSource(Element context, Element oldSource, Element newSource) { |
| Substitution substitutionEdge = (Substitution) context; |
| substitutionEdge.getClients().remove(oldSource); |
| substitutionEdge.getClients().add((NamedElement) newSource); |
| |
| ((Classifier) oldSource).getSubstitutions().remove(substitutionEdge); |
| ((Classifier) newSource).getSubstitutions().add(substitutionEdge); |
| } |
| |
| /** |
| * Service used to reconnect a Substitution edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectSubstitutionEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| Substitution substitutionEdge = (Substitution) context; |
| substitutionEdge.getSuppliers().remove(oldTarget); |
| substitutionEdge.getSuppliers().add((NamedElement) newTarget); |
| substitutionEdge.setContract((Classifier) newTarget); |
| } |
| |
| /** |
| * Service used to reconnect a InterfaceRealization edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectInterfaceRealizationEdgeSource(Element context, Element oldSource, Element newSource) { |
| InterfaceRealization interfaceRealizationEdge = (InterfaceRealization) context; |
| interfaceRealizationEdge.getClients().remove(oldSource); |
| interfaceRealizationEdge.getClients().add((NamedElement) newSource); |
| |
| ((Class) oldSource).getInterfaceRealizations().remove(interfaceRealizationEdge); |
| ((Class) newSource).getInterfaceRealizations().add(interfaceRealizationEdge); |
| } |
| |
| /** |
| * Service used to reconnect a InterfaceRealization edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectInterfaceRealizationEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| InterfaceRealization interfaceRealizationEdge = (InterfaceRealization) context; |
| interfaceRealizationEdge.getSuppliers().remove(oldTarget); |
| interfaceRealizationEdge.getSuppliers().add((NamedElement) newTarget); |
| interfaceRealizationEdge.setContract((Interface) newTarget); |
| } |
| |
| /** |
| * Service used to reconnect a Usage edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectUsageEdgeSource(Element context, Element oldSource, Element newSource) { |
| // get the root model of the diagram |
| Model rootModel = getRootModel(oldSource); |
| |
| // remove the old source from the Usage element and the new source |
| Usage usageEdge = (Usage) context; |
| usageEdge.getClients().remove(oldSource); |
| usageEdge.getClients().add((NamedElement) newSource); |
| |
| // keep the removed old source in the root model |
| if (oldSource instanceof Package && !(newSource instanceof Package)) { |
| ((Package) oldSource).getPackagedElements().remove(usageEdge); |
| rootModel.getPackagedElements().add(usageEdge); |
| } else if (newSource instanceof Package && !(oldSource instanceof Package)) { |
| ((Package) newSource).getPackagedElements().add(usageEdge); |
| rootModel.getPackagedElements().remove(usageEdge); |
| } |
| } |
| |
| /** |
| * Service used to reconnect a Usage edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param source |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param target |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectUsageEdgeTarget(Element context, Element source, Element target) { |
| Usage usageEdge = (Usage) context; |
| usageEdge.getSuppliers().remove(source); |
| usageEdge.getSuppliers().add((NamedElement) target); |
| } |
| |
| /** |
| * Service used to reconnect a Link edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param oldsource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectLinkEdgeSource(Element context, DEdge edgeView, Element oldSource, Element newSource) { |
| Element target = (Element) ((DNodeContainerSpec) edgeView.getTargetNode()).getTarget(); |
| |
| // remove the target from the old source |
| if (oldSource instanceof Comment) { |
| ((Comment) oldSource).getAnnotatedElements().remove(target); |
| } else if (oldSource instanceof Constraint) { |
| ((Constraint) oldSource).getConstrainedElements().remove(target); |
| } |
| |
| // add the target to the new source |
| if (newSource instanceof Comment) { |
| ((Comment) newSource).getAnnotatedElements().add(target); |
| } else if (newSource instanceof Constraint) { |
| ((Constraint) newSource).getConstrainedElements().add(target); |
| } |
| } |
| |
| /** |
| * Service used to reconnect a Link edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectLinkEdgeTarget(Element context, DEdge edgeView, Element oldTarget, Element newTarget) { |
| Element source = (Element) ((DNodeContainerSpec) edgeView.getSourceNode()).getTarget(); |
| |
| if (source instanceof Comment) { |
| ((Comment) source).getAnnotatedElements().remove(oldTarget); |
| ((Comment) source).getAnnotatedElements().add(newTarget); |
| } else if (source instanceof Constraint) { |
| ((Constraint) source).getConstrainedElements().remove(oldTarget); |
| ((Constraint) source).getConstrainedElements().add(newTarget); |
| } |
| } |
| |
| /** |
| * Service used to reconnect a Abstraction edge source. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectAbstractionEdgeSource(Element context, Element oldSource, Element newSource) { |
| Abstraction abstractionEdge = (Abstraction) context; |
| abstractionEdge.getClients().remove(oldSource); |
| abstractionEdge.getClients().add((NamedElement) newSource); |
| } |
| |
| /** |
| * Service used to reconnect a Abstraction edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectAbstractionEdgeTarget(Element context, Element oldTarget, Element newTarget) { |
| Abstraction abstractionEdge = (Abstraction) context; |
| abstractionEdge.getSuppliers().remove(oldTarget); |
| abstractionEdge.getSuppliers().add((NamedElement) newTarget); |
| } |
| |
| /** |
| * Service used to reconnect a Link edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param oldSource |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newSource |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectAssociationEdgeSource(Element context, DEdge edgeView, Element oldSource, Element newSource) { |
| // if reconnect the source of an AssociationClass edge |
| if (context instanceof AssociationClass) { |
| // set the ownedEnd to the new source |
| for (Property ownedEnd : ((AssociationClass) context).getOwnedEnds()) { |
| if (ownedEnd.getType().equals(oldSource)) { |
| ownedEnd.setType((Type) newSource); |
| ownedEnd.setName(((Type) newSource).getName()); |
| break; |
| } |
| } |
| } else // if reconnect the source of an Association edge |
| { |
| // get the target of the edge |
| Element target = null; |
| if (edgeView.getTargetNode() instanceof DNodeListSpec) { |
| target = (Element) ((DNodeListSpec) edgeView.getTargetNode()).getTarget(); |
| } else if (edgeView.getTargetNode() instanceof DNodeContainerSpec) |
| |
| { |
| target = (Element) ((DNodeContainerSpec) edgeView.getTargetNode()).getTarget(); |
| } |
| |
| // find the Attribute in the old source to be modified |
| EList<Property> attributes = null; |
| if (oldSource instanceof Class) { |
| attributes = ((Class) oldSource).getOwnedAttributes(); |
| } else if (oldSource instanceof Interface) { |
| attributes = ((Interface) oldSource).getOwnedAttributes(); |
| } else if (oldSource instanceof DataType) { |
| attributes = ((DataType) oldSource).getOwnedAttributes(); |
| } |
| |
| // remove attribute from the old source |
| Property modifiedAttribute = findAttributToBeModified(attributes, (Element) target); |
| attributes.remove(modifiedAttribute); |
| |
| // add attribute to the new source |
| if (newSource instanceof Class) { |
| ((Class) newSource).getOwnedAttributes().add(modifiedAttribute); |
| } else if (newSource instanceof Interface) { |
| ((Interface) newSource).getOwnedAttributes().add(modifiedAttribute); |
| } else if (newSource instanceof DataType) { |
| ((DataType) newSource).getOwnedAttributes().add(modifiedAttribute); |
| } |
| |
| Association association = (Association) modifiedAttribute.getAssociation(); |
| for (Property ownedEnd : association.getOwnedEnds()) { |
| if (ownedEnd.getType().equals(oldSource)) { |
| ownedEnd.setType((Type) newSource); |
| ownedEnd.setName(((Type) newSource).getName()); |
| break; |
| } |
| } |
| } |
| } |
| |
| /** |
| * Find an attribute in a list of attributes |
| * |
| * @param attributes |
| * list of attributes |
| * @param target |
| * the searched attribute |
| * @return the found attribute |
| */ |
| private Property findAttributToBeModified(EList<Property> attributes, Element target) { |
| for (Property attribut : attributes) { |
| if (attribut.getType().equals(target)) { |
| return attribut; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Service used to reconnect a Link edge target. |
| * |
| * @param context |
| * Element attached to the existing edge |
| * @param edgeView |
| * Represents the graphical new edge |
| * @param oldTarget |
| * Represents the semantic element pointed by the edge before |
| * reconnecting |
| * @param newTarget |
| * Represents the semantic element pointed by the edge after |
| * reconnecting |
| * @return the Element attached to the edge once it has been modified |
| */ |
| public void reconnectAssociationEdgeTarget(Element context, DEdge edgeView, Element oldTarget, Element newTarget) { |
| // if reconnect the target of an AssociationClass edge |
| if (context instanceof AssociationClass) { |
| // set the ownedEnd to the new target |
| for (Property ownedEnd : ((AssociationClass) context).getOwnedEnds()) { |
| if (ownedEnd.getType().equals(oldTarget)) { |
| ownedEnd.setType((Type) newTarget); |
| ownedEnd.setName(((Type) newTarget).getName()); |
| break; |
| } |
| } |
| } else // if reconnect the target of an Association edge |
| { |
| // get the source of the edge |
| Element source = null; |
| if (edgeView.getSourceNode() instanceof DNodeListSpec) { |
| source = (Element) ((DNodeListSpec) edgeView.getSourceNode()).getTarget(); |
| } else if (edgeView.getSourceNode() instanceof DNodeContainerSpec) |
| |
| { |
| source = (Element) ((DNodeContainerSpec) edgeView.getSourceNode()).getTarget(); |
| } |
| |
| // find the Attribute in the source to be modified |
| EList<Property> attributes = null; |
| if (source instanceof Class) { |
| attributes = ((Class) source).getOwnedAttributes(); |
| } else if (source instanceof Interface) { |
| attributes = ((Interface) source).getOwnedAttributes(); |
| } else if (source instanceof DataType) { |
| attributes = ((DataType) source).getOwnedAttributes(); |
| } |
| Property modifiedAttribute = findAttributToBeModified(attributes, (Element) oldTarget); |
| |
| // set the attribute to the new target |
| modifiedAttribute.setType((Type) newTarget); |
| modifiedAttribute.setName(((Type) newTarget).getName()); |
| } |
| } |
| |
| /** |
| * Check if the current element is instance of instance specification Link or |
| * Class. |
| * |
| * @param elem |
| * the current element to be checked |
| * @return true if instance specification Class, otherwise return false |
| */ |
| public boolean isNotInstanceSpecificationLink(Element elem) { |
| return elem.getEAnnotations().isEmpty(); |
| } |
| |
| /** |
| * Check if the current element is instance of instance specification Link or |
| * Class. |
| * |
| * @param elem |
| * the current element to be checked |
| * @return true if instance specification Class, otherwise return false |
| */ |
| public boolean isInstanceSpecificationEdge(EObject elem) { |
| if (elem instanceof InstanceSpecification) { |
| InstanceSpecification instanceSpecification = (InstanceSpecification) elem; |
| return !instanceSpecification.getEAnnotations().isEmpty(); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Get the target element of the instance specification link. |
| * |
| * @param elem |
| * the instance specification Link |
| * @return the target element of the current instance specification link |
| */ |
| public EObject getTargetOfInstanceSpecification(EObject elem) { |
| if (elem instanceof InstanceSpecification) { |
| InstanceSpecification instanceSpecification = (InstanceSpecification) elem; |
| if (!instanceSpecification.getEAnnotations().isEmpty()) { |
| EAnnotation eAnnotation = instanceSpecification.getEAnnotations().get(0); |
| if (!eAnnotation.getReferences().isEmpty()) { |
| return eAnnotation.getReferences().get(1); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get the source element of the instance specification link. |
| * |
| * @param elem |
| * the instance specification Link |
| * @return the source element of the current instance specification link |
| */ |
| public EObject getSourceOfInstanceSpecification(EObject elem) { |
| if (elem instanceof InstanceSpecification) { |
| InstanceSpecification instanceSpecification = (InstanceSpecification) elem; |
| if (!instanceSpecification.getEAnnotations().isEmpty()) { |
| EAnnotation eAnnotation = instanceSpecification.getEAnnotations().get(0); |
| if (!eAnnotation.getReferences().isEmpty()) { |
| return eAnnotation.getReferences().get(0); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Compute the label of the given association. |
| * |
| * @param association |
| * the {@link Association} for which to retrieve a label. |
| * @return the computed label. |
| */ |
| public String computeAssociationBeginLabel(Association association) { |
| return LabelServices.INSTANCE.computeAssociationBeginLabel(association); |
| } |
| |
| /** |
| * Compute the association edge begin name |
| * |
| * @param association |
| * the current association |
| * @return the begin name |
| */ |
| public String computeAssociationClassBeginLabel(Association association) { |
| Property source = AssociationServices.INSTANCE.getSource(association); |
| return "+ " + source.getName(); |
| } |
| |
| /** |
| * Compute the association edge end name |
| * |
| * @param association |
| * the current association |
| * @return the end name |
| */ |
| public String computeAssociationClassEndLabel(Association association) { |
| Property target = AssociationServices.INSTANCE.getTarget(association); |
| return "+ " + target.getName(); |
| } |
| |
| /** |
| * Compute the instance specification edge begin name |
| * |
| * @param context |
| * the current instance specification |
| * @return the begin name |
| */ |
| public String computeInstanceSpecBeginLabel(EObject context) { |
| InstanceSpecification instanceSpec = (InstanceSpecification) context; |
| InstanceSpecification source = (InstanceSpecification) instanceSpec.getEAnnotations().get(0).getReferences() |
| .get(0); |
| return source.getName(); |
| } |
| |
| /** |
| * Compute the instance specification edge end name |
| * |
| * @param context |
| * the current instance specification |
| * @return the end name |
| */ |
| public String computeInstanceSpecEndLabel(EObject context) { |
| InstanceSpecification instanceSpec = (InstanceSpecification) context; |
| InstanceSpecification target = (InstanceSpecification) instanceSpec.getEAnnotations().get(0).getReferences() |
| .get(1); |
| return target.getName(); |
| } |
| |
| /** |
| * Compute the label of the given association. |
| * |
| * @param association |
| * the {@link Association} for which to retrieve a label. |
| * @return the computed label. |
| */ |
| public String computeAssociationEndLabel(Association association) { |
| return LabelServices.INSTANCE.computeAssociationEndLabel(association); |
| } |
| |
| |
| /** |
| * Create an association between two elements. |
| * |
| * @param source |
| * association source |
| * @param target |
| * association target |
| * @return The association |
| */ |
| private Association createAssociation(Element source, Element target, int assocType) { |
| // get the root model of the diagram |
| Model rootModel = getRootModel(source); |
| |
| final Association association = UMLFactory.eINSTANCE.createAssociation(); |
| final Property end1 = AssociationServices.INSTANCE.createAssociationClassEnd((Type) source); |
| association.getMemberEnds().add(end1); |
| final Property end2 = AssociationServices.INSTANCE.createAssociationEnd((Type) target); |
| association.getMemberEnds().add(end2); |
| |
| association.getOwnedEnds().add(end1); |
| end2.setAssociation(association); |
| end2.setUpper(1); |
| |
| switch (assocType) { |
| case AggregationKind.SHARED: |
| end2.setAggregation(AggregationKind.SHARED_LITERAL); |
| break; |
| case AggregationKind.COMPOSITE: |
| end2.setAggregation(AggregationKind.COMPOSITE_LITERAL); |
| break; |
| default: |
| break; |
| } |
| |
| if (source instanceof Class) { |
| ((Class) source).getOwnedAttributes().add(end2); |
| } else if (source instanceof Interface) { |
| ((Interface) source).getOwnedAttributes().add(end2); |
| } else if (source instanceof DataType) { |
| ((DataType) source).getOwnedAttributes().add(end2); |
| } |
| |
| EAnnotation eAnnotation = association.createEAnnotation(ANNOTATION_GENERIC_SOURCE); |
| eAnnotation.getDetails().put(ANNOTATION_DETAIL_KEY, ANNOTATION_DETAIL_VALUE); |
| association.getEAnnotations().add(eAnnotation); |
| |
| rootModel.getPackagedElements().add(association); |
| |
| return association; |
| } |
| |
| public boolean isNotAssociation(EObject elem) { |
| return ((Property) elem).getAssociation() == null; |
| } |
| |
| public void createProfileApplicationLink(EObject object, Element source) { |
| ProfileApplication profileApplication = UMLFactory.eINSTANCE.createProfileApplication(); |
| ((Package) source).getProfileApplications().add(profileApplication); |
| } |
| |
| /** |
| * Create a new association. |
| * |
| * @param object |
| * Object |
| * @param source |
| * selected source |
| * @param target |
| * selected Target |
| * @param sourceView |
| * Source view |
| * @param targetView |
| * Target view |
| * @return Association |
| */ |
| public Association createAssociation(EObject object, Element source, Element target, EObject sourceView, |
| EObject targetView, int assocType) { |
| if (source.eContainer() instanceof Package) { |
| // tool creation association edge |
| if (!(source instanceof Association || target instanceof Association)) { |
| return createAssociation(source, target, assocType); |
| } else if ((source instanceof AssociationClass || target instanceof AssociationClass) |
| && (sourceView instanceof DEdge || targetView instanceof DEdge)) { |
| // try to connect association from/to associationClas (edge part) |
| return createAssociationAddEnd(source, target); |
| } else if (source instanceof AssociationClass || target instanceof AssociationClass |
| && (sourceView instanceof DNodeList || targetView instanceof DNodeList)) { |
| // try to connect association from/to associationClas (container part) |
| return createAssociation(source, target, assocType); |
| } else if (source instanceof Association || target instanceof Association) { |
| return createAssociationAddEnd(source, target); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Add an end to an existing association. |
| * |
| * @param source |
| * Association or element |
| * @param target |
| * element or association |
| */ |
| private Association createAssociationAddEnd(Element source, Element target) { |
| Association association; |
| Type type; |
| if (source instanceof Association) { |
| association = (Association) source; |
| type = (Type) target; |
| } else { |
| association = (Association) target; |
| type = (Type) source; |
| } |
| |
| if (isBroken(association)) { // Look for broken association |
| fixAssociation(association, type); |
| } else { // create new end |
| final Property end = AssociationServices.INSTANCE.createAssociationEnd(type); |
| association.getNavigableOwnedEnds().add(end); |
| association.getOwnedEnds().add(end); |
| } |
| return association; |
| } |
| |
| /** |
| * Precondition for n-ary association creation. |
| * |
| * @param object |
| * selected association |
| * @return true if association is binary and no end have no qualifiers |
| */ |
| public boolean createNaryAssociationPrecondition(EObject object) { |
| return AssociationServices.INSTANCE.createNaryAssociationPrecondition(object); |
| } |
| |
| /** |
| * Create an operation in a class. |
| * |
| * @param type |
| * the container {@link org.eclipse.uml2.uml.Type} element |
| * @return New operation |
| */ |
| public Operation createOperation(org.eclipse.uml2.uml.Type type) { |
| return OperationServices.INSTANCE.createOperation(type); |
| } |
| |
| /** |
| * Create new qualifier for association |
| * |
| * @param association |
| * selected association |
| */ |
| public void createQualifier(Association association) { |
| // Display a selection pop-up to choose the end |
| final ListDialog dialog = new ListDialog(Display.getCurrent().getActiveShell()); |
| dialog.setTitle("Qualifier creation"); //$NON-NLS-1$ |
| dialog.setMessage("Please select the end to create new Qualifier:"); //$NON-NLS-1$ |
| dialog.setInput(association.getMemberEnds().toArray()); |
| dialog.setContentProvider(new ArrayContentProvider()); |
| dialog.setLabelProvider(new LabelProvider() { |
| @Override |
| public String getText(Object element) { |
| return ((NamedElement) element).getName(); |
| } |
| }); |
| dialog.setInitialSelections(new Object[] { association.getMemberEnds().get(0) }); |
| |
| final int status = dialog.open(); |
| if (status == Window.OK) { |
| final Property qualifier = UMLFactory.eINSTANCE.createProperty(); |
| final Property end = (Property) dialog.getResult()[0]; |
| end.getQualifiers().add(qualifier); |
| qualifier.setName(LabelServices.INSTANCE.computeDefaultName(qualifier)); |
| } |
| } |
| |
| /** |
| * Delete selected edge fron a N-Ary association |
| * |
| * @param association |
| * association |
| * @param element |
| * edge to delete |
| */ |
| public void deleteNAryAssociation(Association association, DDiagramElement element) { |
| if (isNary(association)) { |
| final Property end = AssociationServices.INSTANCE.getSourceEndAssociation(association, element); |
| end.eContainer(); |
| EcoreUtil.delete(end); |
| } |
| } |
| |
| /** |
| * Edit the qualifier label |
| * |
| * @param context |
| * property association end element |
| * @param editedLabelContent |
| * edit label content |
| * @return end |
| */ |
| public Element editQualifierLabel(Property context, String editedLabelContent) { |
| final DisplayLabelSwitch displayLabelSwitch = new DisplayLabelSwitch(); |
| final EditLabelSwitch editLabel = new EditLabelSwitch(); |
| // Separator for direct edit |
| final ArrayList<String> labels = new ArrayList<String>( |
| Arrays.asList(editedLabelContent.split(DirectEditLabelSwitch.QUALIFIER_SEPARATOR))); |
| // List qualifiers |
| final EList<Property> qualifiers = context.getQualifiers(); |
| // Check for changes |
| if (labels.size() != qualifiers.size()) { |
| qualifiers.clear(); |
| for (final String label : labels) { |
| final Property qualifier = UMLFactory.eINSTANCE.createProperty(); |
| qualifiers.add(qualifier); |
| editLabel.setEditedLabelContent(label); |
| editLabel.doSwitch(qualifier); |
| } |
| } else { |
| // Only rename element |
| int index = 0; |
| for (final String label : labels) { |
| if (!label.equals(displayLabelSwitch.doSwitch(qualifiers.get(index)))) { |
| editLabel.setEditedLabelContent(label); |
| editLabel.doSwitch(qualifiers.get(index)); |
| } |
| index++; |
| } |
| } |
| return context; |
| } |
| |
| /** |
| * Iterate over the given {@link Collection} of root elements to find a |
| * {@link Type} element with the given name. |
| * |
| * @param roots |
| * the elements to inspect |
| * @param typeName |
| * the name to match |
| * @return the found {@link Type} or <code>null</code> |
| */ |
| public Type findTypeByName(Collection<EObject> roots, String typeName) { |
| return ElementServices.INSTANCE.findTypeByName(roots, typeName); |
| } |
| |
| /** |
| * With the given {@link EObject} iterate over root elements to find a |
| * {@link Type} element with the given name. |
| * |
| * @param object |
| * the elements to inspect |
| * @param typeName |
| * the name to match |
| * @return the found {@link Type} or <code>null</code> |
| */ |
| public Type findTypeByName(EObject object, String typeName) { |
| return ElementServices.INSTANCE.findTypeByName(object, typeName); |
| } |
| |
| private void fixAssociation(Association association, Type type) { |
| final EList<Property> ends = association.getMemberEnds(); |
| final List<Property> brokenEnds = new ArrayList<Property>(); |
| for (final Property end : ends) { |
| if (end.getType() == null) { |
| brokenEnds.add(end); |
| } |
| } |
| |
| if (brokenEnds.size() > 1) { |
| // If several broken links exist user have to select the link to reconnect. |
| |
| final ListDialog dialog = new ListDialog(Display.getCurrent().getActiveShell()); |
| dialog.setTitle("Reconnect broken association end:"); //$NON-NLS-1$ |
| dialog.setMessage("Please select the end to reconnect: "); //$NON-NLS-1$ |
| dialog.setInput(brokenEnds.toArray()); |
| dialog.setContentProvider(new ArrayContentProvider()); |
| dialog.setLabelProvider(new LabelProvider() { |
| @Override |
| public String getText(Object element) { |
| return ((NamedElement) element).getName(); |
| } |
| }); |
| dialog.setInitialSelections(new Object[] { brokenEnds.get(0) }); |
| |
| final int status = dialog.open(); |
| if (status == Window.OK) { |
| final Object[] types = dialog.getResult(); |
| if (types != null && types.length == 1) { |
| final Property endToFix = (Property) types[0]; |
| endToFix.setType(type); |
| endToFix.setName(AssociationServices.INSTANCE.getAssociationEndsName(type)); |
| } |
| } |
| } else { |
| final Property endToFix = brokenEnds.get(0); |
| endToFix.setType(type); |
| endToFix.setName(AssociationServices.INSTANCE.getAssociationEndsName(type)); |
| } |
| } |
| |
| /** |
| * Fix association. |
| * |
| * @param host |
| * Host |
| * @param a |
| * Association |
| * @param b |
| * Association |
| */ |
| public void fixAssociation(EObject host, EObject a, EObject b) { |
| if (a instanceof Association && b instanceof Type) { |
| fixAssociation((Association) a, (Type) b); |
| } else if (b instanceof Association && a instanceof Type) { |
| fixAssociation((Association) b, (Type) a); |
| } |
| } |
| |
| /** |
| * Get abstract label format. |
| * |
| * @param object |
| * EObject |
| * @return Abstract label format |
| */ |
| public List<FontFormat> getAbstractBoldLabelFormat(EObject object) { |
| // Fix to return bold/italic when bug will be fixed on sirius |
| final List<FontFormat> fontFormats = new ArrayList<FontFormat>(); |
| fontFormats.add(FontFormat.BOLD_LITERAL); |
| fontFormats.add(FontFormat.ITALIC_LITERAL); |
| return fontFormats; |
| } |
| |
| /** |
| * Get abstract label format. |
| * |
| * @param object |
| * EObject |
| * @return Abstract label format |
| */ |
| public FontFormat getAbstractItalicLabelFormat(EObject object) { |
| // Fix to return bold/italic when bug will be fixed on sirius |
| return FontFormat.ITALIC_LITERAL; |
| } |
| |
| /** |
| * Get all the stereotype applications according to the selected diagram. |
| * |
| * @param diagram |
| * Current diagram |
| * @return Stereotype applications |
| */ |
| public Collection<Object> getAllStereotypeApplications(DDiagram diagram) { |
| return org.eclipse.papyrus.uml.sirius.common.diagram.core.services.StereotypeServices.INSTANCE |
| .getAllStereotypeApplications(diagram); |
| } |
| |
| /** |
| * Get list of association. Check in diagram only two ends are presents. |
| * |
| * @param container |
| * package |
| * @param diagram |
| * diagram |
| * @return list of binary association |
| */ |
| public List<Association> getAssociation(Package container, DDiagram diagram) { |
| final List<Association> result = new ArrayList<Association>(); |
| final Collection<EObject> associations = getAssociationInverseRefs(diagram); |
| for (final EObject object : associations) { |
| final Association association = (Association) object; |
| if (getVisibleAssociationEnds(association, diagram).size() <= 2) { |
| result.add(association); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Retrieve the cross references of the association of all the UML elements |
| * displayed as node in a Diagram. Note that a Property cross reference will |
| * lead to retrieve the cross references of this property. |
| * |
| * @param diagram |
| * a diagram. |
| * @return the list of cross reference of the given |
| */ |
| public Collection<EObject> getAssociationInverseRefs(DDiagram diagram) { |
| return NodeInverseRefsServices.INSTANCE.getAssociationInverseRefs(diagram); |
| } |
| |
| /** |
| * Get base class associated to a stereotype application. |
| * |
| * @param stereotypeApplication |
| * Stereotype application |
| * @return Base class |
| */ |
| public Element getBaseClass(EObject stereotypeApplication) { |
| return StereotypeServices.INSTANCE.getBaseClass(stereotypeApplication); |
| } |
| |
| /** |
| * Get broken associations. |
| * |
| * @param container |
| * the current container. |
| * @return a list of association which might be considered as "broken", we are |
| * not able to display them as edges. |
| */ |
| public Collection<Association> getBrokenAssociations(EObject container) { |
| final Collection<Association> result = new ArrayList<Association>(); |
| for (final EObject child : container.eContents()) { |
| if (child instanceof Association && isBroken((Association) child)) { |
| result.add((Association) child); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Get navigable owned end of an association |
| * |
| * @param association |
| * Association |
| * @return Association |
| */ |
| public List<Property> getNavigableOwnedEnds(Association association) { |
| final List<Property> ends = Lists.newArrayList(); |
| final Property source = AssociationServices.INSTANCE.getSource(association); |
| final Property target = AssociationServices.INSTANCE.getTarget(association); |
| if (source != null) { |
| ends.add(source); |
| } |
| if (target != null) { |
| ends.add(target); |
| } |
| return ends; |
| } |
| |
| /** |
| * Get the type of the association source end. |
| * |
| * @param association |
| * association |
| * @param diagram |
| * diagram |
| * @return type of the source |
| */ |
| public Element getSourceType(Association association, DDiagram diagram) { |
| final EList<DDiagramElement> elements = diagram.getDiagramElements(); |
| // List semantic elements visible in diagram |
| final List<EObject> visibleEnds = new ArrayList<EObject>(); |
| for (final DDiagramElement element : elements) { |
| visibleEnds.add(element.getTarget()); |
| } |
| final EList<Property> ends = association.getMemberEnds(); |
| for (final Property end : ends) { |
| if (visibleEnds.contains(end.getType())) { |
| if (end.getQualifiers().isEmpty()) { |
| return end.getType(); |
| } |
| return end; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Get the type of the association target end. |
| * |
| * @param association |
| * association |
| * @param diagram |
| * diagram |
| * @return Type of the target |
| */ |
| public Element getTargetType(Association association, DDiagram diagram) { |
| final EList<DDiagramElement> elements = diagram.getDiagramElements(); |
| // List semantic elements visible in diagram |
| final List<EObject> diagramElements = new ArrayList<EObject>(); |
| for (final DDiagramElement element : elements) { |
| diagramElements.add(element.getTarget()); |
| } |
| final List<Property> ends = association.getMemberEnds(); |
| // find source index in list |
| int sourceIndex = 0; |
| for (int i = 0; i < ends.size(); i++) { |
| if (diagramElements.contains(ends.get(i).getType())) { |
| sourceIndex = i; |
| break; |
| } |
| } |
| // find target from the end of the list |
| int targetIndex = ends.size() - 1; |
| while (targetIndex > 0 && targetIndex > sourceIndex) { |
| if (diagramElements.contains(ends.get(targetIndex).getType())) { |
| if (ends.get(targetIndex).getQualifiers().isEmpty()) { |
| return ends.get(targetIndex).getType(); |
| } |
| return ends.get(targetIndex); |
| } |
| targetIndex--; |
| } |
| return null; |
| } |
| |
| /** |
| * Retrieve the cross references of the template binding of all the UML elements |
| * displayed as node in a Diagram. Note that a Property cross reference will |
| * lead to retrieve the cross references of this property. |
| * |
| * @param diagram |
| * a diagram. |
| * @return the list of cross reference of the given |
| */ |
| public Collection<EObject> getTemplateBindingInverseRefs(DDiagram diagram) { |
| return NodeInverseRefsServices.INSTANCE.getTemplateBindingInverseRefs(diagram); |
| } |
| |
| /** |
| * Return collection of visible association class in a diagram. |
| * |
| * @param diagram |
| * Diagram |
| * @param container |
| * Container of the associationClass |
| * @return Set of visible association Classes or empty collection |
| */ |
| public Collection<EObject> getVisibleAssociationClass(DSemanticDiagram diagram, EObject container) { |
| final Set<EObject> associationClasses = new HashSet<EObject>(); |
| final Collection<EObject> displayedNodes = UIServices.INSTANCE.getDisplayedNodes(diagram); |
| final Collection<EObject> associations = getAssociationInverseRefs(diagram); |
| for (final EObject association : associations) { |
| if (association instanceof AssociationClass) { |
| final Property source = AssociationServices.INSTANCE.getSource((AssociationClass) association); |
| final Property target = AssociationServices.INSTANCE.getTarget((AssociationClass) association); |
| if (source != null && target != null) { |
| final Type sourceType = source.getType(); |
| final Type targetType = target.getType(); |
| final Package parent = ((AssociationClass) association).getNearestPackage(); |
| |
| // An association class is visible in its parent if the parent is visible, else |
| // it is visible |
| // directly on the diagram |
| if ((container.equals(parent) |
| || !displayedNodes.contains(parent) && container.equals(diagram.getTarget())) |
| && sourceType != null && displayedNodes.contains(sourceType) && targetType != null |
| && displayedNodes.contains(targetType)) { |
| associationClasses.add(association); |
| } |
| } |
| } |
| } |
| return associationClasses; |
| } |
| |
| private List<Property> getVisibleAssociationEnds(Association association, DDiagram diagram) { |
| final List<Property> ends = new ArrayList<Property>(); |
| // Association should be visible in self container |
| // At least one of the ends is visible in diagram |
| final EList<DDiagramElement> elements = diagram.getDiagramElements(); |
| // check if at least more than 2 ends are displayed in diagram |
| final List<EObject> visibleEndsList = new ArrayList<EObject>(); |
| for (final DDiagramElement element : elements) { |
| visibleEndsList.add(element.getTarget()); |
| } |
| final EList<Property> associationEnds = association.getMemberEnds(); |
| for (final Property end : associationEnds) { |
| if (visibleEndsList.contains(end.getType())) { |
| ends.add(end); |
| } |
| if (end.getType() == null) { // Broken association case |
| ends.add(end); |
| } |
| } |
| return ends; |
| } |
| |
| private boolean isBroken(Association child) { |
| final EList<Property> ends = child.getMemberEnds(); |
| for (final Property end : ends) { |
| if (end.getType() == null) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean isNary(Association association) { |
| if (association != null && association.getMembers() != null && association.getMembers().size() > 2) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Check an element is not a Class. |
| * |
| * @param element |
| * Element |
| * @return return true if the element is not a Class |
| */ |
| public boolean isNotTypeOfClass(EObject element) { |
| return !isTypeOfClass(element); |
| } |
| |
| /** |
| * Check is a feature is static. |
| * |
| * @param feature |
| * Feature |
| * @return True if it is a static feature |
| */ |
| public boolean isStatic(Feature feature) { |
| return feature != null && feature.isStatic(); |
| } |
| |
| /** |
| * Check if an element is type of class. |
| * |
| * @param element |
| * Element |
| * @return True if element is a class |
| */ |
| public boolean isTypeOfClass(EObject element) { |
| return "Class".equals(element.eClass().getName()); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Check if an association can be created. |
| * |
| * @param self |
| * association |
| * @param preSource |
| * selected element |
| * @return true if valid |
| */ |
| public boolean isValidAssociation(EObject self, Element preSource) { |
| if (preSource instanceof Association) { |
| // Verify association ends don't have qualifiers |
| final EList<Property> ends = ((Association) preSource).getMemberEnds(); |
| for (final Property end : ends) { |
| if (!end.getQualifiers().isEmpty()) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Check if an association can be created. Both selected elements are not |
| * association. If an association is selected is should not be an aggregation or |
| * a composite |
| * |
| * @param self |
| * association |
| * @param preSource |
| * User select element as source |
| * @param preTarget |
| * user select element as target |
| * @return true if valid |
| */ |
| public boolean isValidAssociation(EObject self, Element preSource, Element preTarget) { |
| |
| if (preSource instanceof Association && preTarget instanceof Association) { |
| return false; // Source and Target are not association |
| } else if (preSource instanceof Association || preTarget instanceof Association) { |
| // Verify association is not a binary association |
| Association association; |
| if (preSource instanceof Association) { |
| association = (Association) preSource; |
| } else { |
| association = (Association) preTarget; |
| } |
| |
| final EList<Property> ends = association.getMemberEnds(); |
| for (final Property end : ends) { |
| if (AssociationServices.INSTANCE.isComposite(end) || AssociationServices.INSTANCE.isShared(end)) { |
| return false; |
| } |
| if (!end.getQualifiers().isEmpty()) { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Check is an association source is composite. |
| * |
| * @param association |
| * Association |
| * @return True if source is composite |
| */ |
| public boolean sourceIsComposite(Association association) { |
| return AssociationServices.INSTANCE.sourceIsComposite(association); |
| } |
| |
| /** |
| * Check is an association source is navigable. |
| * |
| * @param association |
| * Association |
| * @param element |
| * Edge element |
| * @return True if source is navigable |
| */ |
| public boolean sourceIsNavigable(Association association, DDiagramElement element) { |
| return AssociationServices.INSTANCE.sourceIsNavigable(association, element); |
| } |
| |
| /** |
| * Check is an association source is navigable and composite. |
| * |
| * @param association |
| * Association |
| * @return True if source is navigable and composite |
| */ |
| public boolean sourceIsNavigableAndTargetIsComposite(Association association) { |
| return AssociationServices.INSTANCE.sourceIsNavigableAndTargetIsComposite(association); |
| } |
| |
| /** |
| * Check is an association source is navigable and shared. |
| * |
| * @param association |
| * Association |
| * @return True if source is navigable and shared |
| */ |
| public boolean sourceIsNavigableAndTargetIsShared(Association association) { |
| return AssociationServices.INSTANCE.sourceIsNavigableAndTargetIsShared(association); |
| } |
| |
| /** |
| * Check is an association source is shared. |
| * |
| * @param association |
| * Association |
| * @return True if source is shared |
| */ |
| public boolean sourceIsShared(Association association) { |
| return AssociationServices.INSTANCE.sourceIsShared(association); |
| } |
| |
| /** |
| * Check is an association target is composite. |
| * |
| * @param association |
| * Association |
| * @return True if target is composite |
| */ |
| public boolean targetIsComposite(Association association) { |
| return AssociationServices.INSTANCE.targetIsComposite(association); |
| } |
| |
| /** |
| * Check is an association target is navigable. |
| * |
| * @param association |
| * Association |
| * @return True if target is navigable |
| */ |
| public boolean targetIsNavigable(Association association) { |
| return AssociationServices.INSTANCE.targetIsNavigable(association); |
| } |
| |
| /** |
| * Check is an association target is navigable and composite. |
| * |
| * @param association |
| * Association |
| * @return True if target is navigable and composite |
| */ |
| public boolean targetIsNavigableAndSourceIsComposite(Association association) { |
| return AssociationServices.INSTANCE.targetIsNavigableAndSourceIsComposite(association); |
| } |
| |
| /** |
| * Check is an association target is navigable and shared. |
| * |
| * @param association |
| * Association |
| * @return True if target is navigable and shared |
| */ |
| public boolean targetIsNavigableAndSourceIsShared(Association association) { |
| return AssociationServices.INSTANCE.targetIsNavigableAndSourceIsShared(association); |
| } |
| |
| /** |
| * Check is an association target is shared. |
| * |
| * @param association |
| * Association |
| * @return True if target is shared |
| */ |
| public boolean targetIsShared(Association association) { |
| return AssociationServices.INSTANCE.targetIsShared(association); |
| } |
| |
| } |