blob: 82b465ad13551cc6df07993c63cd1f131f1084a5 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2013, 2014 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
*****************************************************************************/
modeltype notation "strict" uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation';
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 umlrpy "strict" uses 'http://www.eclipse.org/Papyrus/UMLRpy/1.0.0';
/**
* Abstract transformation rules for importing notation diagrams into Papyrus
*/
transformation RpyToPapyrus(in semantics : umlrpy, out graphics : notation);
main() {
semantics.rootObjects()[IDiagram]->map toOwnedDiagrams();
}
abstract mapping IDiagram::toOwnedDiagrams() : notation::Diagram{
}
/** Abstract mappings. Never called directly, inherited only */
abstract mapping notation::View::toPapyrusView() : notation::View {
result.element := self.element; /* UML Model is in-out. No mapping required. */
result.visible := self.visible;
result.children := self.children.map toNode();
result.type := self.getType();
}
//abstract mapping Edge::toPapyrusEdge() : Edge inherits View::toPapyrusView {
// result.bendpoints := self.bendpoints.map toBendpoint(self.diagram);
// result.sourceAnchor := self.sourceAnchor.map toAnchor();
// result.targetAnchor := self.targetAnchor.map toAnchor();
// result.source := self.source.map toView();
// result.target := self.target.map toView();
//}
//abstract mapping Connector::toPapyrusConnector() : Connector inherits Edge::toPapyrusEdge, RoutingStyle::toRoutingstyle, LineStyle::toLineStyle {};
//abstract mapping Connector::toCommentLink() : Connector inherits Connector::toPapyrusConnector{};
abstract mapping umlrpy::CGIClass::toPapyrusNode() : Node ;
abstract mapping inout Shape::addCommentDecoration(){};
abstract mapping Node::toPapyrusConnectorLabel() : Node {
result.visible := self.visible;
result.type := self.getType();
var initX := self.layoutConstraint.oclAsType(Location).x;
var initY := self.layoutConstraint.oclAsType(Location).y;
if self.diagram.isHimetric() then {
initX := initX.toPixels();
initY := initY.toPixels();
} endif;
result.layoutConstraint := object Location {
x := initX;
y := initY;
};
//Do not set element
//Do not set children
}
//abstract mapping IDiagram::toPapyrusDiagram() : notation::Diagram {
//population {
//result.name := self.name;
/* Papyrus uses Pixel, whereas RSA uses Himetric. Forcing the conversion to Pixel is a bad idea */
//result.measurementUnit := MeasurementUnit::Pixel;
//result.styles := createDiagramStyle();
// }
//end {
// worked(1);
//}
//}
query Diagram::getName() : String{
return if self.name.oclIsUndefined() or self.name = '' then {
var element := self.findElement();
return if element.oclIsKindOf(NamedElement) then
element.oclAsType(NamedElement).getDiagramName()
else
''
endif;
} else
self.name
endif;
}
query NamedElement::getDiagramName() : String {
return if self.oclIsKindOf(Behavior) then
self.owner.oclAsType(NamedElement).getDiagramName()
else
self.name
endif;
}
abstract mapping Element::toCompartmentEntry(node : Node) : Shape {
result.element := self.oclAsType(EObject);
//result.type := self.findType(node);
}
helper createDiagramStyle() : DiagramStyle {
return object DiagramStyle {
};
}
/** Common mappings: Copy (Call or Inherit) */
mapping FontStyle::toFontStyle() : FontStyle {
result.fontColor := self.fontColor;
result.fontName := self.fontName;
result.fontHeight := self.fontHeight;
result.bold := self.bold;
result.italic := self.italic;
result.underline := self.underline;
result.strikeThrough := self.strikeThrough;
}
abstract mapping Node::toPapyrusNode() : Node inherits View::toPapyrusView{};
mapping FillStyle::toFillStyle() : FillStyle {
result.fillColor := self.fillColor;
/* Workaround for Bug 456933: use default transparency so that CSS can override the value if necessary */
result.transparency := if self.transparency = 0 then -1 else self.transparency endif;
//TODO: Gradient
}
mapping LineStyle::toLineStyle() : LineStyle {
result.lineColor := self.lineColor;
result.lineWidth := self.lineWidth;
}
mapping RoutingStyle::toRoutingstyle() : RoutingStyle {
result.roundedBendpointsRadius := self.roundedBendpointsRadius;
result.routing := self.routing;
result.smoothness := self.smoothness;
result.avoidObstructions := self.avoidObstructions;
result.closestDistance := self.closestDistance;
result.jumpLinkStatus := self.jumpLinkStatus;
result.jumpLinkType := self.jumpLinkType;
result.jumpLinksReverse := self.jumpLinksReverse;
}
//abstract mapping Bendpoints::toBendpoint(diagram: Diagram) : Bendpoints disjuncts
// RelativeBendpoints::toBendpoint
//;
//mapping RelativeBendpoints::toBendpoint(diagram: Diagram) : Bendpoints {
// init {
// result := object RelativeBendpoints {}
// }
// var convertToPixels := diagram.isHimetric();
// self.copyBendpoints(result.oclAsType(RelativeBendpoints), convertToPixels);
//}
mapping LayoutConstraint::toLayout(diagram : Diagram) : LayoutConstraint disjuncts
Bounds::toLayout{
}
mapping Bounds::toLayout(diagram : Diagram) : LayoutConstraint {
init {
result := object Bounds{}
}
var bounds : Bounds := result.oclAsType(Bounds);
if diagram.isHimetric() then {
bounds.x := self.x.toPixels();
bounds.y := self.y.toPixels();
if self.width > 0 then bounds.width := self.width.toPixels() endif;
if self.height > 0 then bounds.height := self.height.toPixels() endif;
} else{
bounds.x := self.x;
bounds.y := self.y;
if self.width > 0 then bounds.width := self.width endif;
if self.height > 0 then bounds.height := self.height endif;
} endif;
}
query View::isHimetric() : Boolean {
return self.diagram.measurementUnit = MeasurementUnit::Himetric
}
query Integer::toPixels() : Integer{
return self.div(25); //FIXME: Approx.
}
mapping Anchor::toAnchor() : Anchor disjuncts
IdentityAnchor::toAnchor{
}
mapping IdentityAnchor::toAnchor() : Anchor {
init {
result := object IdentityAnchor {
}
}
var id := if self.oclAsType(EObject).isHimetric() then {
var id := self.id;
var part1 := id.substringBefore(':').asInteger();
var part2 := id.substringAfter(':').asInteger();
var newId := if part1.oclIsInvalid() or part2.oclIsInvalid() then
self.id
else
(part1.toPixels().toString())+':'+(part2.toPixels().toString())
endif;
newId;
} else {
self.id;
} endif;
result.oclAsType(IdentityAnchor).id := id;
}
query EObject::isHimetric() : Boolean {
return if self.oclIsKindOf(Diagram) then
self.oclAsType(Diagram).isHimetric()
else
self.eContainer().isHimetric()
endif;
}
helper View::fail() : String {
var type := self.type;
var isProxy := self.element != null and self.element.oclIsUndefined();
var semanticEClassName := if isProxy then 'Unresolved (proxy) reference' elif self.element = null then 'No semantic element' else self.element.eClass().name endif;
//warning('Unknown or unsupported element type. Graphical Type = "'+self.type+'", Semantic Type = "'+semanticEClassName+'". Diagram Type: "'+self.diagram.type+'". The element will be ignored.');
return '';
}
/** Generic mapping logic */
query View::getType(): String{
var element : Element := self.findElement();
return
if self.oclIsKindOf(Diagram) then
self.getDiagramType()
elif self.oclIsKindOf(BasicDecorationNode) then
self.getDecorationType(element)
elif self.oclIsKindOf(Node) then
self.getNodeType(element)
else self.fail()
endif;
}
query View::findElement() : Element {
return self.findAssociatedElement().oclAsType(Element);
}
query View::findAssociatedElement() : EObject {
return if self.element.oclIsUndefined() then
self.container().oclAsType(View).findAssociatedElement()
else
self.element
endif;
}
query Sequence(Node)::safeUnion(unionWith: Sequence(Node)) : Sequence(Node) {
var res := if self->oclIsUndefined() and unionWith->oclIsUndefined() then
object Sequence(Object){}
elif self->oclIsUndefined() then
unionWith
elif unionWith->oclIsUndefined() then
self
else
self->union(unionWith)
endif;
return res;
}
mapping View::toView() : View disjuncts Node::toNode, Edge::toEdge;
/** Generic mapping logic */
query GraphElementsType::getNodeType() : String {
return
if self.oclIsTypeOf(CGIClass) then '2008'
elif (self.oclIsTypeOf(CGIState) and self[CGIState].m_type![String].equalsIgnoreCase("8")) then '6000'
elif (self.oclIsTypeOf(CGIState) and self[CGIState].m_type![String].equalsIgnoreCase("5")) then '8000'
endif;
}
query GraphicChartType::getNodesType() : String {
return
if self.oclIsTypeOf(CGIStateChart) then '2000'
endif;
}
/** Diagram-specific transformations (Implement only) */
abstract mapping Node::toNode() : Node;
abstract mapping Edge::toEdge() : Edge;
abstract query View::getDiagramType() : String;
//Distinction between TopNode and ChildNode is not important in the Notation model.
//Simply use the TopNode Type.
abstract query View::getNodeType(element : Element) : String;
abstract query View::getEdgeType(element : Element) : String;
abstract query View::getDecorationType(element : Element) : String;
/** Main diagram mapping */
abstract mapping IDiagram::generateDiagram() : notation::Diagram;