blob: 42295facf72e2f6957bf92dd72fb645827e89f60 [file] [log] [blame]
/*****************************************************************************
* 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;
}