blob: 274e4ba40a5903adbc185ddc32e5f484f53d4482 [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 RpyUtils;
import RpyToPapyrusUtils;
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 ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore';
/**
*
* This file provides useful method to manage SysML Rpy Model
*/
library RpyToPapyrusDiagamCommon;
/**
* Create and initialize the diagram. These fields are initialized:
* <ul>
*<li>name</li>
*<li>type</li>
*<li>measurementUnit</li>
*</ul>
* These styles are added to the diagrams:
*<li>diagram style</li>
*<li>papyrus view style</li>
*<li>diagram_compatibility_version</li>
*In additional we add a EAnnotation (the same that for the UMl Model) indicating that the diagram has been imported from a Rpy Model
*</ul>
*
* In addition we add a named style to know that the diagram has been imported from Rpy. It will be useful if we need to create specific DiagramReconciler to fix bugs due to the import from Rpy model
*/
mapping rpymetamodel::IDiagram::createAndInitDiagram(rpyProject:IProject,newDiagramType:String, diagramElement:EObject, diagramOwner:EObject):Diagram{
name:=self.name;
measurementUnit:= MeasurementUnit::Pixel;
type:= newDiagramType;
element:=diagramElement;
eAnnotations+=rpyProject.createEAnnotationForVersioning();
styles+= object DiagramStyle{};
// styles+= object PapyrusViewStyle {owner:=diagramOwner};
styles+= object StringValueStyle {name:=getDiagramCompatibilityVersionKey(); stringValue:=getDiagramCompatibilityVersion()};
}
/**
*
* Map a CGI Annotation to a UML Comment Shape CN
* @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::CGIAnnotation::CGIAnnotationToCommentCN(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):Shape when {self.m_pModelObject.oclIsTypeOf(IComment) and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
type:="Comment_Shape_CN";
children+= object DecorationNode{
type:="Comment_BodyLabel_CN";
};
layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
element:=self.m_pModelObject.resolveone().oclAsType(EObject);
}
/**
* Create a list compartment with the given name, hide it if the rpy compartment doesn't have name and force the compartment title to hidden if required
*
* if comparmtent are visible when they mustn't be visible, the problem comes from the arg rpyCompartmentName which is probably wrong
*
*/
mapping umlrpy::CGIGenericElement::toListCompartment(papyrusCompartmentName:String, rpyCompartmentName:String) : notation::ListCompartment{
type:=papyrusCompartmentName;
styles := object DrawerStyle{};
styles += object TitleStyle{};
styles += object SortingStyle{};
styles += object FilteringStyle{};
//we hide the compartment by default. We show it only if it the equivalent compartment is shown in Rpy
visible:=false;
var cptList:Set(umlrpy::IProperty) :=self[CGIGenericElement].properties.Subjects->select(subject | subject.Name="ObjectModelGe").Metaclasses->select(metaclass | metaclass.Name="DataType").Properties->select(p | p.Name="Compartments")->asSet();
cptList->forEach(curr){
var isContaining:Boolean:=contains(curr.Value,rpyCompartmentName);
if(isContaining){
visible:=isContaining;
break;
};
};
if(visible){
var showCompartmentTitleProperty:umlrpy::IProperty :=self[CGIGenericElement].properties.Subjects->select(subject | subject.Name="General").Metaclasses->select(metaclass | metaclass.Name="Graphics").Properties->select(p | p.Name="ShowCompartmentsTitle")->any(true);
if((not showCompartmentTitleProperty.oclIsUndefined()) and showCompartmentTitleProperty.Value="False"){
eAnnotations+= object EAnnotation { source:="PapyrusCSSForceValue" ; details+=object EStringToStringMapEntry { key:="showTitle"; value:="false"}};
};
};
//force value to avoid impact of CSS and get the same display between Rpy and Papyrus
eAnnotations+=createCSSForceValue("visible");
}
/**
* Create a list compartment with the given name, hide it if the rpy compartment doesn't have name and force the compartment title to hidden if required
*
* if comparmtent are visible when they mustn't be visible, the problem comes from the arg rpyCompartmentName which is probably wrong
*
*/
//TODO : merge me with previous one
mapping umlrpy::CGIClass::toListCompartment(papyrusCompartmentName:String, rpyCompartmentName:String) : notation::ListCompartment{
type:=papyrusCompartmentName;
styles := object DrawerStyle{};
styles += object TitleStyle{};
styles += object SortingStyle{};
styles += object FilteringStyle{};
//we hide the compartment by default. We show it only if it the equivalent compartment is shown in Rpy
visible:=false;
// var cptList:Set(umlrpy::IProperty) :=self[CGIClass].properties.Subjects->select(subject | subject.Name="ObjectModelGe").Metaclasses->select(metaclass | metaclass.Name="Block").Properties->select(p | p.Name="Compartments")->asSet();
// cptList->forEach(curr){
// log("currValue=" + curr.Value.toString());
// var isContaining:Boolean:=contains(curr.Value,rpyCompartmentName);
// if(isContaining){
// visible:=isContaining;
// break;
// };
// };
if(rpyCompartmentName<>null){
visible:=self.Compartments->selectByKind(CGICompartment)->select(cpt | cpt.m_name=rpyCompartmentName)->notEmpty();
};
if(visible){
var showCompartmentTitleProperty:umlrpy::IProperty :=self[CGIClass].properties.Subjects->select(subject | subject.Name="General").Metaclasses->select(metaclass | metaclass.Name="Graphics").Properties->select(p | p.Name="ShowCompartmentsTitle")->any(true);
if((not showCompartmentTitleProperty.oclIsUndefined()) and showCompartmentTitleProperty.Value="False"){
eAnnotations+= object EAnnotation { source:="PapyrusCSSForceValue" ; details+=object EStringToStringMapEntry { key:="showTitle"; value:="false"}};
};
};
//force value to avoid impact of CSS and get the same display between Rpy and Papyrus
eAnnotations+=createCSSForceValue("visible");
}
//TODO : merge me with previous one
mapping umlrpy::CGIBasicClass::toListCompartment(papyrusCompartmentName:String, rpyCompartmentName:String) : notation::ListCompartment{
type:=papyrusCompartmentName;
styles := object DrawerStyle{};
styles += object TitleStyle{};
styles += object SortingStyle{};
styles += object FilteringStyle{};
//we hide the compartment by default. We show it only if it the equivalent compartment is shown in Rpy
visible:=false;
if(rpyCompartmentName<>null){
visible:=self.Compartments->selectByKind(CGICompartment)->select(cpt | cpt.m_name=rpyCompartmentName)->notEmpty();
};
if(visible){
var showCompartmentTitleProperty:umlrpy::IProperty :=self[CGIBasicClass].properties.Subjects->select(subject | subject.Name="General").Metaclasses->select(metaclass | metaclass.Name="Graphics").Properties->select(p | p.Name="ShowCompartmentsTitle")->any(true);
if((not showCompartmentTitleProperty.oclIsUndefined()) and showCompartmentTitleProperty.Value="False"){
eAnnotations+= object EAnnotation { source:="PapyrusCSSForceValue" ; details+=object EStringToStringMapEntry { key:="showTitle"; value:="false"}};
};
};
//force value to avoid impact of CSS and get the same display between Rpy and Papyrus
eAnnotations+=createCSSForceValue("visible");
}
/**
* Helper to create an EAnnotation to force a value and ignore CSS. It is used to get the same diaply between Rpy model and Papyrus model, ignoring CSS applied on the model
*/
helper createCSSForceValue(detailKey:String):EAnnotation{
var eAnnotation:EAnnotation:= object EAnnotation { source:="PapyrusCSSForceValue" ; details+=object EStringToStringMapEntry { key:=detailKey; value:="true"}};
return eAnnotation;
}
/**
* Return the routing to use for the given connector.
* The current implementations returns always Manual routing to avoid problems with anchors, bendopints and snapToGrid
*/
query umlrpy::GraphElementsType::getConnectorRouting():notation::Routing{
var routing:Routing:=Routing::Manual;
var rpyValue:String;
if(self.oclIsKindOf(CGIObjectLink)){
rpyValue:=self.oclAsType(CGIObjectLink).m_line_style;
}elif(self.oclIsTypeOf(CGIAnchor)){
rpyValue:=self.oclAsType(CGIAnchor).m_line_style;
}elif(self.oclIsTypeOf(CGIAssociationEnd)){
rpyValue:=self.oclAsType(CGIAssociationEnd).m_line_style;
}else{
log("The object " + self.toString() + " is not yet managed to get its routing")
};
routing:=switch{
case (rpyValue="0") Routing::Manual;
case (rpyValue="1") Routing::Manual; //spline in Rpy
case (rpyValue="2") Routing::Rectilinear;
};
//as we currently get trouble with anchos, bendpoints and snap to grid, we always return Manual
routing:=Routing::Manual;
return routing;
}