blob: b2ece0ed2f2e33e2d9ec759acf16f1111f9f4d98 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2016 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:
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
*****************************************************************************/
import Rpy2PapyrusSemanticElements;
import RpyUtils;
import SysMLRpyUtils;
import RpyToPapyrusDiagamCommon;
import org.eclipse.papyrus.interoperability.rpy.blackboxes.Rpy2PapyrusNotationBlackboxes;
import org.eclipse.papyrus.interoperability.rpy.blackboxes.sysml11.diagrams.InternalBlockDiagramFixLayoutBlackboxes;
modeltype umlrpy "strict" uses 'http://www.eclipse.org/Papyrus/UMLRpy/1.0.0';
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 sysml11 "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/SysML';
modeltype ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype UMLPrimitivesTypes "strict" uses 'http://www.eclipse.org/uml2/5.0.0/Types' ;
/**
*
* This transformation manages the SysML 1.1 Internal Block Diagram
* TODO in this transfo :
* floating label location
* managing comment link on link
*/
transformation SysML11InternalBlockDiagram(in semantics : umlrpy, out graphics : notation, inout model:uml, in Sysml11Profile:sysml11, in primitives:UMLPrimitivesTypes)
access transformation Rpy2PapyrusSemanticElements(in inModel:umlrpy, out outModel:uml, in primitives:UMLPrimitivesTypes)
extends Rpy2PapyrusSemanticElements(in inModel:umlrpy, out outModel:uml, in primitives:UMLPrimitivesTypes)
{
//nothing to do here
}
/**
*
* Map a Rpy IBD Diagram with a Papyrus SysML 1.1 IBD Diagram
*/
mapping rpymetamodel::IDiagram::iDiagramToSysML11InternalBlockDiagram(rpyProject:IProject):Diagram when{self.isUserModelDiagram() and self.isSysMLInternalBlockDiagram()}{
//1. creating the diagram object
init {
//we are looking for the owner of the diagram
var owner:EObject;
var iDiagramOwner:ecore::EObject:=self[EObject].eContainer()![EObject];
if(iDiagramOwner.oclIsKindOf(umlrpy::IClass)){
owner:= iDiagramOwner.resolveIn(ecore::EObject::generalMappingToUMLElement, uml::Element)![EObject];
};
result:=self.map createAndInitDiagram(rpyProject,getPapyrusDiagramType(), owner, owner);
}
//1. find some objects
var cgiClassChart:CGIClassChart:=self.graphicChart->oclAsSet().selectByType(CGIClassChart)->any(true);
var cgiClass:CGIClass:=cgiClassChart.graphElements->selectByType(CGIClass)->any(true);
var cgiDiagramFrame:CGIDiagramFrame:=cgiClassChart.graphElements->selectByType(CGIDiagramFrame)->any(true);
//2. as it is an IBD, we must represent the owner in the diagram. This is the Rpy Frame
var rootBlockShape:Shape= object Shape{
type:="shape_sysml_block_as_composite";
children+= object DecorationNode { type:="label_sysml_block_name"};
layoutConstraint:=object Bounds{
x:=cgiDiagramFrame.get_X_Position();
y:=cgiDiagramFrame.get_Y_Position();
width:=cgiDiagramFrame.get_Width();
height:=cgiDiagramFrame.get_Height()
};
};
var blockCompartmentStructure:BasicCompartment:= object BasicCompartment {
type:="compartment_sysml_structure";
styles+= object TitleStyle{};
};
rootBlockShape.children+=blockCompartmentStructure;
children+=rootBlockShape;
//3. map the children of the compartment
blockCompartmentStructure.children+=cgiClassChart.graphElements->select(a | a.isAllowedAsCompartmentChildren(blockCompartmentStructure)).map graphElementsTypeToIBDShapes(cgiClassChart,cgiClass->asSequence());
//4. map the affixed child node of the compartment
rootBlockShape.children+=cgiClassChart.graphElements->select(a | a.isAllowedAsAffixedChildNode(rootBlockShape)).map graphElementsTypeToIBDShapes(cgiClassChart, cgiDiagramFrame->asSequence());
//5. map the edges of the diagram
edges+=cgiClassChart.graphElements.map graphElementsTypeToIBDEdges(cgiClassChart, cgiDiagramFrame->asSequence()).oclAsType(notation::Edge);
fixLayout(result);
}
/**
* Returns the type of the diagram to create
*/
query getPapyrusDiagramType():String{
return 'InternalBlock';
};
/**
* This method allows to map comment link
*
*/
mapping rpymetamodel::CGIAnchor::graphElementsTypeToIBDCommentLink(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Connector when {self.getLinkSourceView()<>null and self.getLinkTargetView()<>null}{
type:="Comment_AnnotatedElementEdge";
source:=self.getLinkSourceView();
target:=self.getLinkTargetView();
var sourceNode:M_pRootType:=self.m_pSource;
var targetNode:M_pRootType:=self.m_pTarget;
addAnchorsAndBendpoints(self,result);
//manage connector routing
routing:=self.oclAsType(GraphElementsType).getConnectorRouting();
eAnnotations+=createCSSForceValue("routing");
}
/**
*
* This method allows to map the connector link
*/
mapping rpymetamodel::CGIObjectLink::graphElementsTypeToIBDConnector(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Connector when {self.getLinkSourceView()<>null and self.getLinkTargetView()<>null}{
type:="link_uml_connector";
source:=self.getLinkSourceView();
target:=self.getLinkTargetView();
element:= self.m_pModelObject.resolveoneIn(umlrpy::IObjectLink::iObjectLinkToUMLElement).oclAsType(EObject);
addAnchorsAndBendpoints(self,result);
children+=object DecorationNode{
type:="linklabel_uml_appliedstereotype";
layoutConstraint:=object Location{
y:=-30; //TODO : a dummy value
};
};
//managing the name label of the connector
// var nameText:CGIText:=self.m_rpn;
children+=object DecorationNode{
type:="linklabel_uml_connector_label";
layoutConstraint:=object Location{
y:=-10; //TODO : a dummy value
};
};
//manage connector routing
routing:=self.oclAsType(GraphElementsType).getConnectorRouting();
eAnnotations+=createCSSForceValue("routing");
}
//TODO : calling resolve method could not work in soem case : if we are mapping a link linked to another link not yet mapped -> we will not able to resolve it!
//TODO : manage link linked to an other link (comment link for example)
query umlrpy::CGIAnchor::getLinkSourceView():View{
var source:View:=self.m_pSource![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDShapes, Shape)![View];
if(source=null){
// source:=self.m_pSource![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDEdges, Connector)![View];
};
return source;
}
query umlrpy::CGIAnchor::getLinkTargetView():View{
var target:View:=self.m_pTarget![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDShapes, Shape)![View];
if(target=null){
// target:=self.m_pTarget![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDEdges, Connector)![View];
};
return target
}
query umlrpy::CGIObjectLink::getLinkSourceView():View{
var source:View:=self.m_pSource![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDShapes, Shape)![View];
if(source=null){
// source:=self.m_pSource![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDEdges, Connector)![View];
};
return source;
}
query umlrpy::CGIObjectLink::getLinkTargetView():View{
var target:View:=self.m_pTarget![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDShapes, Shape)![View];
if(target=null){
// target:=self.m_pTarget![M_pRootType].resolveIn(umlrpy::GraphElementsType::graphElementsTypeToIBDEdges, Connector)![View];
};
return target
}
/**
* This mapping take GraphElementsType and returns Shape.
* @param
* cgiClassChart : the class chart of the diagram, it is useful to find child to create for the created element
* @param
* rpyAllowedParent : the list of the allowed Rpy parent to manage the object.
* if the Rpy parent is not in this list, the object won't be mapped
*
*/
mapping rpymetamodel::GraphElementsType::graphElementsTypeToIBDShapes(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Shape disjuncts
rpymetamodel::CGIAnnotation::CGIAnnotationToCommentCN,
rpymetamodel::CGIObjectInstance::CGIObjectInstanceIBDBlockProperty,
rpymetamodel::CGIGenericElement::CGIGenericElementToIBDBlockProperty,
rpymetamodel::CGIPortConnector::CGIPortConnectorToIBDPort
{}
mapping rpymetamodel::GraphElementsType::graphElementsTypeToIBDEdges(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Edge disjuncts
rpymetamodel::CGIObjectLink::graphElementsTypeToIBDConnector,
rpymetamodel::CGIAnchor::graphElementsTypeToIBDCommentLink
{}
mapping rpymetamodel::CGIPortConnector::CGIPortConnectorToIBDPort(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Shape when {self.oclIsTypeOf(CGIPortConnector) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
type:="shape_sysml_flowport_as_affixed";
children+= object DecorationNode{
type:="affixedlabel_sysml_flowport_label";
layoutConstraint:= object Location{
x:=30; //TODO
};
};
children+= object DecorationNode{
type:="affixedlabel_uml_appliedstereotype";
layoutConstraint:= object Location{
x:=30; //TODO
};
};
layoutConstraint:= object Bounds{
x:=getX(self);
y:=getY(self);
//width:=getRectangleWidth(self);
//height:=getRectangleHeight(self);
//result of calculus was wrong for port size and moreover this calculus is useless for port.
width:=20;
height:=20;
};
var semanticElementRpy:IRelation:=self.m_pModelObject;
element:=self.m_pModelObject.resolveoneIn(umlrpy::IRelation::iRelationToUMLElement).oclAsType(EObject);
}
/**
* This method maps a CGIObject on a BlockProperty
* @param
* cgiClassChart
* @param
* rpyAllowedParent
*
*/
mapping rpymetamodel::CGIObjectInstance::CGIObjectInstanceIBDBlockProperty(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Shape when {self.m_pModelObject.oclIsTypeOf(IPart) and self.oclIsTypeOf(CGIObjectInstance) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
init{
//1. create the shape
result:=self.graphElementTypeToIBDBlockProperty(cgiClassChart, rpyAllowedParent);
}
//2. set the represented element
var resolvedE:=self.m_pModelObject.resolveoneIn(umlrpy::IPart::iPartToUMLElement);
element:=resolvedE.oclAsType(EObject);
}
/**
* Returns true when the graph element can be used as an affixed child node in Papyrus Diagram
*/
query umlrpy::GraphElementsType::isAllowedAsAffixedChildNode(shape:Shape):Boolean{
return self.oclIsTypeOf(CGIPortConnector);
}
/**
* Returns true when the graph element can be set as a children of a given compartment
*/
query umlrpy::GraphElementsType::isAllowedAsCompartmentChildren(cpt:BasicCompartment):Boolean{
return not self.oclIsTypeOf(CGIPortConnector);
}
mapping rpymetamodel::CGIGenericElement::CGIGenericElementToIBDBlockProperty(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Shape when {self.m_pModelObject.oclIsTypeOf(IAssociationEnd) and self.m_pModelObject.oclAsType(IAssociationEnd).inverse.oclIsUndefined() and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
init{
//1. create the shape
result:=self.graphElementTypeToIBDBlockProperty(cgiClassChart, rpyAllowedParent);
}
//2. set the represented element
var representedElement:=self.m_pModelObject;
var assoEnd:IAssociationEnd:=self.m_pModelObject.oclAsType(IAssociationEnd);
var resolvedE:Association=representedElement.resolveoneIn(umlrpy::IAssociationEnd::iAssociationEndToUMLAssociation);
var resolvedE2:Property:=resolvedE.memberEnd->select(endd | endd.oclIsKindOf(Property))->select(p | not p.oclAsType(Property).owner.oclIsKindOf(Association))->any(true);
element:=resolvedE2.oclAsType(EObject);
}
/**
*
* Helper used to create the Block Property Shape
*/
helper rpymetamodel::GraphElementsType::graphElementTypeToIBDBlockProperty(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Shape{
var localShape:Shape:=object Shape{
type:="shape_sysml_blockproperty_as_composite";
};
localShape.children+= object DecorationNode{
type:="label_uml_property_label";
};
var basicCpt:BasicCompartment:=object BasicCompartment{
type:="compartment_sysml_blockproperty_structure";
styles+=object TitleStyle{};
};
localShape.children+=basicCpt;
localShape.layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
basicCpt.children+=cgiClassChart.graphElements->select(a | a.isAllowedAsCompartmentChildren(basicCpt)).map graphElementsTypeToIBDShapes(cgiClassChart, self->asSequence());
localShape.children+=cgiClassChart.graphElements->select(a | a.isAllowedAsAffixedChildNode(localShape)).map graphElementsTypeToIBDShapes(cgiClassChart, self->asSequence());
return localShape;
}