| /***************************************************************************** |
| * Copyright (c) 2015, 2016 CEA LIST, Christian W. Damus, and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation |
| * Christian W. Damus - bug 465656 |
| *****************************************************************************/ |
| import RSAToPapyrus; |
| import org.eclipse.papyrus.uml.m2m.qvto.common.blackboxes.utils.Properties; |
| |
| modeltype notation "strict" uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation'; |
| modeltype umlNotation "strict" uses 'http://www.eclipse.org/papyrus/umlnotation'; |
| modeltype uml "strict" uses 'http://www.eclipse.org/uml2/5.0.0/UML'; |
| modeltype ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore'; |
| modeltype sash "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/sashdi'; |
| modeltype vpconfig "strict" uses 'http://www.eclipse.org/papyrus/infra/viewpoints/configuration'; |
| modeltype vpstyle "strict" uses 'http://www.eclipse.org/papyrus/infra/viewpoints/policy/style'; |
| modeltype config "strict" uses 'http:///RSAToPapyrusParameters.ecore'; |
| |
| transformation RSAUsecaseDiagram(inout semantics : uml, inout graphics : notation, out di : sash, in param : config); |
| |
| main() { |
| semantics.rootObjects()[uml::Element]->map toOwnedDiagrams(); |
| } |
| |
| query View::getDiagramType() : String{ |
| return 'UseCase'; |
| } |
| |
| mapping notation::Diagram::generateDiagram() : notation::Diagram inherits Diagram::toPapyrusDiagram when { |
| self.type = 'Usecase' |
| }{ |
| end { |
| //Remove Generalization#name since it is not supported in Papyrus |
| result.edges->select(e | e.type = 'Generalization_Edge').children->selectByType(DecorationNode)->select(type.oclIsUndefined()).map delete(); |
| |
| //Change the position of the Actor#name Label, since it is fixed in RSA and Floating in Papyrus |
| graphics.objectsOfType(DecorationNode)->select(type = 'Actor_NameLabel').map fixActorLabelPosition(); |
| } |
| } |
| |
| mapping inout notation::DecorationNode::fixActorLabelPosition() when { |
| self.type = 'Actor_NameLabel' |
| } { |
| self.layoutConstraint := object Location { |
| x := 20; |
| y := 60; |
| } |
| } |
| |
| mapping inout notation::DecorationNode::delete(){ |
| graphics.removeElement(self) |
| } |
| |
| mapping Node::toNode() : Node disjuncts |
| UMLShape::toPapyrusShape, |
| UMLShapeCompartment::toStructureCompartment, |
| BasicDecorationNode::toConnectorLabel, |
| BasicDecorationNode::toLabel, |
| //BasicSemanticCompartment::toListCompartment, |
| ListCompartment::toListCompartment |
| //TODO: Disjunct nodes mapping |
| ; |
| /***** Nodes **********/ |
| |
| mapping UMLShape::toPapyrusShape() : Shape inherits Shape::toPapyrusShape when { |
| self.type = '' and ( |
| self.element.oclIsTypeOf(Actor) or |
| self.element.oclIsTypeOf(UseCase) or |
| self.element.oclIsTypeOf(Package) or |
| self.element.oclIsTypeOf(Constraint) or |
| self.element.oclIsTypeOf(Comment) or |
| self.element.oclIsKindOf(Classifier) or |
| self.element.oclIsKindOf(NamedElement) or |
| self.element.oclIsTypeOf(Diagram) |
| ) |
| }{ |
| |
| } |
| mapping BasicDecorationNode::toLabel() : DecorationNode inherits Node::toPapyrusNode when { |
| self.element.oclIsKindOf(uml::NamedElement) and |
| self.type = 'Name' or |
| self.type = 'ValueSpecification' or //Constraint body |
| self.type = 'CommentBody' //Comment body |
| }{ |
| |
| } |
| mapping Edge::toEdge() : Edge disjuncts |
| UMLConnector::toCommentLink, |
| UMLConnector::toConstraintLink, |
| UMLConnector::toPapyrusConnector |
| ; |
| |
| /******* Edges ********/ |
| |
| |
| mapping UMLConnector::toPapyrusConnector() : Connector inherits Connector::toPapyrusConnector when { |
| self.type = '' and ( |
| self.element.oclIsTypeOf(Include) or |
| self.element.oclIsTypeOf(Extend) or |
| self.element.oclIsTypeOf(Generalization) or |
| self.element.oclIsTypeOf(Association) or |
| self.element.oclIsTypeOf(Dependency) or |
| self.element.oclIsTypeOf(Abstraction) or |
| self.element.oclIsTypeOf(Usage) or |
| self.element.oclIsTypeOf(Realization) or |
| self.element.oclIsTypeOf(PackageMerge) or |
| self.element.oclIsTypeOf(PackageImport) |
| ) |
| }{ |
| result.styles := self.map toFontStyle(); |
| } |
| |
| mapping UMLConnector::toCommentLink() : Connector inherits Connector::toCommentLink when{ |
| self.type='Reference' and ( |
| self.source.element.oclIsTypeOf(Comment) or |
| self.target.element.oclIsKindOf(Comment) |
| ) |
| }{ |
| result.type :='Comment_AnnotatedElementEdge'; |
| result.bendpoints := self.bendpoints.map toBendpoint(self.diagram); |
| result.sourceAnchor := object IdentityAnchor{}; |
| } |
| |
| mapping UMLConnector::toConstraintLink() : Connector inherits Connector::toPapyrusConnector when{ |
| self.type='Reference' and ( |
| self.source.element.oclIsTypeOf(Constraint) or |
| self.target.element.oclIsKindOf(Constraint) |
| ) |
| }{ |
| result.type :='Constraint_ConstrainedElementEdge'; |
| result.bendpoints := self.bendpoints.map toBendpoint(self.diagram); |
| result.sourceAnchor := object IdentityAnchor{}; |
| } |
| |
| /****** Connector Labels ******/ |
| |
| mapping BasicDecorationNode::toConnectorLabel() : DecorationNode inherits Node::toPapyrusConnectorLabel when { |
| self.type = 'ToMultiplicityLabel' or |
| self.type = 'ToRoleLabel' or |
| self.type = 'FromMultiplicityLabel' or |
| self.type = 'FromRoleLabel' or |
| self.type = 'NameLabel' or |
| self.type = 'KindLabel' |
| }{ |
| |
| } |
| /****** Compartments *******/ |
| |
| mapping UMLShapeCompartment::toStructureCompartment() : DecorationNode inherits UMLShapeCompartment::toAbstractStructureCompartment when { |
| self.type = 'StructureCompartment' or |
| self.type = 'PackageContents' or |
| self.type = 'UseCaseShapeCompartment' |
| and not self.getType().oclIsUndefined(); |
| }{ |
| |
| } |
| |
| |
| |
| //0. Top-level mapping operation |
| //Standard Compartments (e.g. slots) |
| mapping ListCompartment::toListCompartment() : BasicCompartment inherits Node::toPapyrusNode, DrawerStyle::toDrawerStyle when { |
| self.type.endsWith('Compartment') or self.type = 'Extension_Points' |
| } { |
| //Super class implementation is sufficient. It will already transform the children and set the compartment ID |
| result.children += self.findElement().map toContents(self); |
| } |
| |
| //Synchronized Compartments |
| mapping BasicSemanticCompartment::toListCompartment() : BasicCompartment inherits Node::toPapyrusNode, DrawerStyle::toDrawerStyle when { |
| self.type.endsWith('Compartment') |
| }{ |
| result.children += self.findElement().map toContents(self); |
| } |
| |
| //1.1 BasicCompartment |
| mapping Element::toContents(node : BasicSemanticCompartment) : Sequence(Node); |
| |
| //1.2 ListCompartment |
| mapping Element::toContents(node : ListCompartment) : Sequence(Node) disjuncts |
| UseCase::toContents |
| ; |
| //2. TopLevelNode x Compartment |
| mapping UseCase::toContents(node : ListCompartment) : Sequence(Node) disjuncts |
| UseCase::toExtensionPointCompartmentContents |
| ; |
| |
| //3. Compartment x ElementType |
| |
| mapping UseCase::toExtensionPointCompartmentContents(node : ListCompartment) : Sequence(Node) when { |
| node.type = 'Extension_Points'; |
| }{ |
| init { |
| result := |
| (self.map fillExtensionPoint(node)) |
| } |
| } |
| |
| //4. ElementType |
| |
| mapping uml::UseCase::fillExtensionPoint(node : ListCompartment) : Sequence(Node) when { |
| node.type='ExtensionPointCompartment'; |
| }{ |
| init { |
| result := self.extensionPoint->selectByKind(ExtensionPoint).map toExtensionPointInUseCase(node)->asSequence(); |
| } |
| } |
| |
| //5. ChildLabelNode x TopNode visual ID |
| mapping ExtensionPoint::toExtensionPointInUseCase(node : Node) : Shape inherits Element::toCompartmentEntry { |
| result.type := 'ExtensionPoint_ExtensionPointLabel'; |
| } |
| |
| query View::getDecorationType(element : Element) : String{ |
| var res := self.doGetDecorationType(element); |
| |
| /*log('Get papyrus ID for'+ element.oclAsType(EObject).eClass().name+', '+self.type); |
| |
| log(res); |
| |
| if self.container().oclIsKindOf(Node) then |
| log('IsNode') |
| else |
| log('IsEdge') |
| endif;*/ |
| |
| return res; |
| } |
| /****** Element Type queries ******/ |
| |
| query View::getNodeType(element : Element) : String { |
| return |
| if element.oclIsTypeOf(Actor) then 'Actor_Shape' |
| elif element.oclIsTypeOf(UseCase) then 'UseCase_Shape' |
| elif element.oclIsTypeOf(Package) then 'Package_Shape' |
| elif element.oclIsTypeOf(Constraint) then 'Constraint_Shape' |
| elif element.oclIsTypeOf(Comment) then 'Comment_Shape' |
| elif element.oclIsTypeOf(Diagram) then 'Diagram_ShortcutShape' |
| elif element.oclIsKindOf(Classifier) then 'Classifier_SubjectShape' |
| elif element.oclIsKindOf(NamedElement) then 'NamedElement_DefaultShape' |
| else self.fail() |
| endif; |
| } |
| query View::getEdgeType(element : Element) : String { |
| return if self.type = 'Reference' then '' /* Context and Constraint Links handled separately */ |
| elif self.element.oclIsTypeOf(Include) then 'Include_Edge' |
| elif self.element.oclIsTypeOf(Extend) then 'Extend_Edge' |
| elif self.element.oclIsTypeOf(Generalization) then 'Generalization_Edge' |
| elif self.element.oclIsTypeOf(Association) then 'Association_Edge' |
| elif self.element.oclIsTypeOf(Dependency) then 'Dependency_Edge' |
| elif self.element.oclIsTypeOf(Abstraction) then 'Abstraction_Edge' |
| elif self.element.oclIsTypeOf(Usage) then 'Usage_Edge' |
| elif self.element.oclIsTypeOf(Realization) then 'Realization_Edge' |
| elif self.element.oclIsTypeOf(PackageMerge) then 'PackageMerge_Edge' |
| elif self.element.oclIsTypeOf(PackageImport) then 'PackageImport_Edge' |
| else self.fail() |
| endif; |
| } |
| |
| query View::doGetDecorationType(element : Element) : String{ |
| |
| return if self.container().oclIsKindOf(Node) then { |
| /* Labels & Compartments (GenCompartment + GenNodeLabel) */ |
| return if |
| |
| element.oclIsKindOf(Actor) then |
| return switch { |
| case (self.type = 'Name') 'Actor_NameLabel'; |
| case (self.type = 'UNKNOWN') 'Actor_StereotypeLabel'; |
| case (self.type = 'UNKNOWN') 'Actor_QualifiedNameLabel'; |
| case (self.type = 'Name') 'Actor_FloatingNameLabel'; |
| } |
| elif |
| element.oclIsKindOf(Actor) then |
| return switch { |
| case (self.type = 'Name') 'Actor_ClassifierNameLabel'; |
| } |
| elif |
| element.oclIsKindOf(UseCase) then |
| return switch { |
| case (self.type = 'Name') 'UseCase_NameLabel'; |
| case (self.type = 'Name') 'UseCase_FloatingNameLabel'; |
| case (self.type = 'Extension_Points') 'UseCase_ExtensionPointCompartment'; |
| } |
| elif |
| element.oclIsKindOf(UseCase) then |
| return switch { |
| case (self.type = 'Name') 'UseCase_ClassifierNameLabel'; |
| case (self.type = 'Extension_Points') 'UseCase_ClassifierExtensionPointCompartment'; |
| } |
| elif |
| element.oclIsKindOf(Classifier) then |
| return switch { |
| case (self.type = 'Name') 'Classifier_NameLabel'; |
| case (self.type = 'Name') 'Classifier_FloatingNameLabel'; |
| case (self.type = 'UseCaseShapeCompartment') 'Classifier_UseCaseCompartment'; |
| } |
| elif |
| element.oclIsKindOf(Package) then |
| return switch { |
| case (self.type = 'Name') 'Package_NameLabel'; |
| case (self.type = 'PackageContents') 'Package_PackagedElementCompartment'; |
| } |
| elif |
| element.oclIsKindOf(Constraint) then |
| return switch { |
| case (self.type = 'Name') 'Constraint_NameLabel'; |
| case (self.type = 'ValueSpecification') 'Constraint_BodyLabel'; |
| } |
| elif |
| element.oclIsKindOf(Comment) then |
| return switch { |
| case (self.type = 'CommentBody') 'Comment_BodyLabel'; |
| } |
| elif |
| element.oclIsKindOf(NamedElement) then |
| return switch { |
| case (self.type = 'Name') 'NamedElement_NameLabel'; |
| } |
| elif |
| element.oclIsKindOf(Diagram) then |
| return switch { |
| case (self.type = 'Name') 'Diagram_NameLabel'; |
| } |
| endif |
| } else { /* Floating Edge Labels */ |
| return if |
| element.oclIsKindOf(Include) then |
| return switch { |
| case (self.type='KindLabel') 'Include_KeywordLabel'; |
| case (self.type='Stereotype') 'Include_StereotypeLabel'; |
| } |
| elif |
| element.oclIsKindOf(Extend) then |
| return switch { |
| case (self.type='KindLabel') 'Extend_KeywordLabel'; |
| case (self.type='Stereotype') 'Extend_StereotypeLabel'; |
| } |
| elif |
| element.oclIsKindOf(Generalization) then |
| return switch { |
| case (self.type='Stereotype') 'Generalization_StereotypeLabel'; |
| } |
| elif |
| element.oclIsKindOf(Association) then |
| return switch { |
| case (self.type='Name') 'Association_NameLabel'; |
| case (self.type='Stereotype') 'Association_StereotypeLabel'; |
| case (self.type='NameLabel') 'Association_NameLabel'; |
| } |
| elif |
| element.oclIsKindOf(Realization) then |
| return switch { |
| case (self.type='Name') 'Realization_NameLabel'; |
| case (self.type='Stereotype') 'Realization_StereotypeLabel'; |
| case (self.type='NameLabel') 'Realization_NameLabel'; |
| } |
| elif |
| element.oclIsKindOf(Abstraction) then |
| return switch { |
| case (self.type='Name') 'Abstraction_NameLabel'; |
| case (self.type='Stereotype') 'Abstraction_StereotypeLabel'; |
| case (self.type='NameLabel') 'Abstraction_NameLabel'; |
| } |
| elif |
| element.oclIsKindOf(Usage) then |
| return switch { |
| case (self.type='Name') 'Usage_NameLabel'; |
| case (self.type='Stereotype') 'Usage_StereotypeLabel'; |
| case (self.type='NameLabel') 'Usage_NameLabel'; |
| } |
| elif |
| element.oclIsKindOf(Dependency) then |
| return switch { |
| case (self.type='Name') 'Dependency_NameLabel'; |
| case (self.type='Stereotype') 'Dependency_StereotypeLabel'; |
| case (self.type='NameLabel') 'Dependency_NameLabel'; |
| } |
| elif |
| element.oclIsKindOf(PackageMerge) then |
| return switch { |
| case (self.type='Stereotype') 'PackageMerge_StereotypeLabel'; |
| } |
| elif |
| element.oclIsKindOf(PackageImport) then |
| return switch { |
| case (self.type='Stereotype') 'PackageImport_StereotypeLabel'; |
| } |
| endif; |
| } endif; |
| } |