blob: a3d63d720591e9ba761d772c7212969d0fc8906d [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2017 CEA LIST 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:
* Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
*****************************************************************************/
import org.eclipse.papyrus.uml.m2m.qvto.common.blackboxes.ecore.EcoreHelper;
import org.eclipse.papyrus.interoperability.sysml14.sysml.blackboxes.notation.NotationBlackboxHelper;
import org.eclipse.papyrus.interoperability.sysml14.sysml.SysMLDiagramsUtils;
import org.eclipse.papyrus.interoperability.sysml14.sysml.SysMLDiagramsConstants;
import org.eclipse.papyrus.interoperability.sysml14.sysml.SysMLUtils;
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 viewpoint "strict" uses 'http://www.eclipse.org/papyrus/infra/viewpoints/configuration';
modeltype SysML11 "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/SysML';
modeltype SysML14 "strict" uses 'http://www.eclipse.org/papyrus/sysml/1.4/SysML';
modeltype nattable "strict" uses 'http://www.eclipse.org/papyrus/nattable/model';
transformation SysMLRequirementDiagram(in blockDefinitionViewpoint : viewpoint, in internalBlockViewpoint : viewpoint, in parametricViewpoint : viewpoint, in requirementViewpoint : viewpoint, in umlFile : UML, in inS14Profile : SysML14, in requirementNatTableS11 : nattable, in allocationNatTableS11 : nattable, in requirementNatTableS14 : nattable, in allocationNatTableS14 : nattable, in requirementTableViewPoint : viewpoint, in allocationTableViewPoint : viewpoint, inout notationFile : notation);
// Define needed constants
property diagramName:String = "RequirementDiagram";
property diagramConfigurationName:String = "SysML 1.4 Requirement";
property model:UML::Model = umlFile.rootObjects()[uml::Model]->any(true);
property rootDiagram:notation::Diagram;
property childrenToRemove:OrderedSet(notation::View);
mapping notation::Diagram::fromSysML11RequirementDiagram() : notation::Diagram when {self.type=diagramName} {
init{
var existingChildren:OrderedSet(notation::Node) := self.children;
var existingEdges:OrderedSet(notation::Edge) := self.edges;
result := self;
rootDiagram := result;
result.edges := object OrderedSet(notation::Edge){};
result.edges := existingEdges->map fromSysML11Edge();
result.children := object OrderedSet(notation::Node){};
result.children := existingChildren->map fromSysML11Shape(result);
result.children[notation::Shape]->map fromSysML11ShapeToSysML14Edge(result);
}
type := "PapyrusUMLClassDiagram";
// Create the annotation for versionning
var model:UML::Model := umlFile.rootObjects()[uml::Model]->any(true);
result.eAnnotations += model.createEAnnotationForVersioning();
// Modify or create the compatibility version
setOrCreateCompatibilityVersion(result);
// Add the viewpoint configuration to the papyrus view style
addPapyrusViewStyleConfiguration(result, model, getRequirementPapyrusDiagramConfiguration());
// Remove the needed children
childrenToRemove->forEach(childToRemove){
var parent:ecore::EObject := childToRemove.oclAsType(ecore::EObject).eContainer();
if (parent.oclIsKindOf(notation::View)) {
var parentView:notation::View := parent.oclAsType(notation::View);
removeFromOwnerView(parentView, childToRemove);
};
};
}
// Get the requirement papyrus diagram configuration from the viewpoint file
helper getRequirementPapyrusDiagramConfiguration() : viewpoint::PapyrusDiagram {
return requirementViewpoint.objects()->selectByType(viewpoint::PapyrusDiagram)->any(curr | curr.name = diagramConfigurationName);
}
// Nodes ans shapes management
mapping notation::Node::fromSysML11Shape(parent:notation::View) : notation::Node disjuncts
notation::BasicCompartment::fromSysML11BasicCompartment,
notation::DecorationNode::fromSysML11DecorationNode,
notation::Shape::fromSysML11StereotypeComment,
notation::Shape::fromSysML11RequirementAsClassifier,
notation::Shape::fromSysML11ViewPackageAsClass,
notation::Shape::fromSysML11PackageShapeAsModel, // Must be done before PackageShapeAsPackage
notation::Shape::fromSysML11PackageShapeAsPackage,
notation::Shape::fromSysML11NamedElementDefaultShapeAsCommunicationPath,
notation::Shape::fromSysML11NamedElementDefaultShapeAsGeneralizationSet,
notation::Shape::fromSysML11NamedElementDefaultShapeAsComponent, // Must be done before Class
notation::Shape::fromSysML11NamedElementDefaultShapeAsClass,
notation::Shape::fromSysML11NamedElementDefaultShapeAsEnumeration, // Must be done before DataType
notation::Shape::fromSysML11NamedElementDefaultShapeAsPrimitiveType, // Must be done before DataType
notation::Shape::fromSysML11NamedElementDefaultShapeAsDataType,
notation::Shape::fromSysML11NamedElementDefaultShapeAsDurationObservation,
notation::Shape::fromSysML11NamedElementDefaultShapeAsInformationItem,
notation::Shape::fromSysML11NamedElementDefaultShapeAsInterface,
notation::Shape::fromSysML11NamedElementDefaultShapeAsInstanceSpecification,
notation::Shape::fromSysML11NamedElementDefaultShapeAsSignal,
notation::Shape::fromSysML11DefaultShape
{}
mapping notation::Shape::fromSysML11ViewPackageAsClass(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = PACKAGE_SHAPE_SYSML14 and self.element.oclIsKindOf(UML::Class)} {
init {
result := self;
}
type := CLASS_SHAPE_SYSML14;
// Remove the existing children
var existingChildren:OrderedSet(notation::Node) := self.children;
children := object OrderedSet(notation::Node){};
var isCN:Boolean := not parent.oclIsTypeOf(notation::Diagram);
// Search if the name label is existing
existingChildren->forEach(existingChild){
if (existingChild.type = PACKAGE_NAME_LABEL_DECORATIONNODE_SYSML14 or existingChild.type = PACKAGE_NAME_LABEL_DECORATIONNODE_CN_SYSML14) {
if (isCN) {
existingChild.type := CLASS_NAME_LABEL_DECORATIONNODE_CN_SYSML14;
} else {
existingChild.type := CLASS_NAME_LABEL_DECORATIONNODE_SYSML14;
};
children += existingChild;
} elif (existingChild.type = COMPARTMENT_SHAPE_DISPLAY) {
children += existingChild;
};
};
// Create and set the default DecorationNodes
children += createDefaultFloatingNameLabelDecorationNode(CLASS_FLOATING_LABEL_DECORATIONNODE_SYSML14);
// Create and set the default BasicCompartments
children += createDefaultBasicCompartement(CLASS_ATTRIBUTE_COMPARTMENT_SYSML14);
children += createDefaultBasicCompartement(CLASS_OPERATION_COMPARTMENT_SYSML14);
children += createDefaultBasicCompartement(CLASS_NESTEDCLASSIFIER_COMPARTMENT_SYSML14);
}
mapping notation::Shape::fromSysML11PackageShapeAsModel(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.element.oclIsKindOf(UML::Model)} {
init {
result := self;
}
var isCN:Boolean := not parent.oclIsTypeOf(notation::Diagram);
// Remove the existing children
var existingChildren:OrderedSet(notation::Node) := self.children;
children := object OrderedSet(notation::Node){};
var typeLabel:String = MODEL_SHAPE_SYSML14;
var modelNameLabel:String := MODEL_NAME_LABEL_DECORATIONNODE_SYSML14;
var modelPackagedElementCompartment:String := MODEL_PACKAGEDELEMENT_COMPARTMENT_SYSML14;
// If the shape is not in the diagram, this is a Child node
if (isCN) {
typeLabel := MODEL_SHAPE_CN_SYSML14;
modelNameLabel := MODEL_NAME_LABEL_DECORATIONNODE_CN_SYSML14;
modelPackagedElementCompartment:= MODEL_PACKAGEDELEMENT_COMPARTMENT_CN_SYSML14;
};
type := typeLabel;
if(self.type = NAMEDELEMENT_DEFAULTSHAPE){
children += createDefaultNameLabelDecorationNode(modelNameLabel);
var packageElementCompartment:notation::BasicCompartment := createDefaultBasicCompartement(modelPackagedElementCompartment);
packageElementCompartment.styles += object notation::TitleStyle{};
packageElementCompartment.layoutConstraint := object notation::Bounds{};
children += packageElementCompartment;
}else{
// Search if the packaged element compartment is existing
existingChildren->forEach(existingChild){
if (existingChild.type = PACKAGE_NAME_LABEL_DECORATIONNODE_SYSML14 or existingChild.type = PACKAGE_NAME_LABEL_DECORATIONNODE_CN_SYSML14) {
existingChild.type := modelNameLabel;
setPapyrusCSSForceValueVisible(existingChild, TRUE);
children += existingChild;
} elif (existingChild.type = PACKAGE_PACKAGEDELEMENT_COMPARTMENT_SYSML14 or existingChild.type = PACKAGE_PACKAGEDELEMENT_COMPARTMENT_CN_SYSML14) {
existingChild.type := modelPackagedElementCompartment;
setPapyrusCSSForceValueVisible(existingChild, TRUE);
setShowTitle(existingChild, true);
// Map the existing children shapes
existingChild.children := existingChild.children->map fromSysML11Shape(result);
existingChild.children[notation::Shape]->map fromSysML11ShapeToSysML14Edge(existingChild);
children += existingChild;
} elif (existingChild.type = COMPARTMENT_SHAPE_DISPLAY) {
children += existingChild;
};
};
};
}
mapping notation::Shape::fromSysML11PackageShapeAsPackage(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = PACKAGE_SHAPE_SYSML14 and self.element.oclIsKindOf(UML::Package)} {
init {
result := self;
}
var existingChildren:OrderedSet(notation::Node) := self.children;
children := object OrderedSet(notation::Node){};
children := existingChildren->map fromSysML11Shape(result);
var isCN:Boolean := not parent.oclIsTypeOf(notation::Diagram);
// Search if the packaged element compartment is existing
existingChildren->forEach(existingChild){
if (existingChild.type = PACKAGE_PACKAGEDELEMENT_COMPARTMENT_SYSML14 or existingChild.type = PACKAGE_PACKAGEDELEMENT_COMPARTMENT_CN_SYSML14) {
setPapyrusCSSForceValueVisible(existingChild, TRUE);
setShowTitle(existingChild, true);
// Map the existing children shapes
existingChild.children := existingChild.children->map fromSysML11Shape(result);
existingChild.children[notation::Shape]->map fromSysML11ShapeToSysML14Edge(existingChild);
}
};
}
mapping notation::Shape::fromSysML11RequirementAsClassifier(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = REQUIREMENT_AS_CLASSIFIER_SYSML11} {
init {
var existingChildren:OrderedSet(notation::Node) := self.children;
result := self;
result.children := object OrderedSet(notation::Node){};
result.children := existingChildren->map fromSysML11Shape(result);
}
var isCN:Boolean := not parent.oclIsTypeOf(notation::Diagram);
// If the shape is not in the diagram, this is a Child node
if (not isCN) {
type := CLASS_SHAPE_SYSML14;
// Create the FloatingNameLabel decoration node with its default layout constraint
children += createDefaultFloatingNameLabelDecorationNode(CLASS_FLOATING_LABEL_DECORATIONNODE_SYSML14);
// Create and set the default BasicCompartments
children += createDefaultBasicCompartement(CLASS_ATTRIBUTE_COMPARTMENT_SYSML14);
children += createDefaultBasicCompartement(CLASS_OPERATION_COMPARTMENT_SYSML14);
children += createDefaultBasicCompartement(CLASS_NESTEDCLASSIFIER_COMPARTMENT_SYSML14);
} else {
type := CLASS_SHAPE_CN_SYSML14;
// Create the FloatingNameLabel decoration node with its default layout constraint
children += createDefaultFloatingNameLabelDecorationNode(CLASS_FLOATING_LABEL_DECORATIONNODE_CN_SYSML14);
// Create and set the default BasicCompartments
children += createDefaultBasicCompartement(CLASS_ATTRIBUTE_COMPARTMENT_CN_SYSML14);
children += createDefaultBasicCompartement(CLASS_OPERATION_COMPARTMENT_CN_SYSML14);
children += createDefaultBasicCompartement(CLASS_NESTEDCLASSIFIER_COMPARTMENT_CN_SYSML14);
};
}
mapping notation::Shape::fromSysML11NamedElementDefaultShapeAsCommunicationPath(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.element.oclIsTypeOf(UML::CommunicationPath)} {
init{
result := self;
}
childrenToRemove += result;
}
mapping notation::Shape::fromSysML11NamedElementDefaultShapeAsGeneralizationSet(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.element.oclIsTypeOf(UML::GeneralizationSet)} {
init{
result := self;
}
childrenToRemove += result;
}
mapping notation::Shape::fromSysML11StereotypeComment(parent:notation::View) : notation::Shape when {self.type = STEREOTYPE_COMMENT} {
init {
result := self;
}
childrenToRemove += result;
}
mapping notation::Shape::fromSysML11DefaultShape(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape)} {
init {
var existingChildren:OrderedSet(notation::Node) := self.children;
result := self;
result.children := object OrderedSet(notation::Node){};
result.children := existingChildren->map fromSysML11Shape(result);
}
}
mapping notation::DecorationNode::fromSysML11DecorationNode(parent:notation::View) : notation::DecorationNode disjuncts
notation::DecorationNode::fromSysML11StereotypeLabel,
notation::DecorationNode::fromSysML11DecorationNodeDefault
{}
mapping notation::DecorationNode::fromSysML11StereotypeLabel(parent:notation::View) : notation::DecorationNode when {self.oclIsTypeOf(notation::DecorationNode) and self.type = STEREOTYPE_LABEL_DECORATION_NODE}{
init{
result := self;
if(self.element.oclIsKindOf(UML::Stereotype)){
var stereotype:UML::Stereotype := self.element.oclAsType(UML::Stereotype).toSysML14Stereotype(inS14Profile.objectsOfType(UML::Stereotype));
if (stereotype.oclIsUndefined()) {
// The stereotype was not find in SysML1.4, remove the decoration node
childrenToRemove += result;
} else {
result.element := stereotype.oclAsType(ecore::EObject);
}
};
}
}
mapping notation::DecorationNode::fromSysML11DecorationNodeDefault(parent:notation::View) : notation::DecorationNode when {self.oclIsTypeOf(notation::DecorationNode)} {
init{
result := self;
setPapyrusCSSForceValueVisible(result, TRUE);
}
}
mapping notation::BasicCompartment::fromSysML11BasicCompartment(parent:notation::View) : notation::BasicCompartment disjuncts
notation::BasicCompartment::fromSysML11StereotypeBraceAndCompartment,
notation::BasicCompartment::fromSysML11BasicCompartmentDefault
{}
mapping notation::BasicCompartment::fromSysML11BasicCompartmentDefault(parent:notation::View) : notation::BasicCompartment when {self.oclIsTypeOf(notation::BasicCompartment) and self.type <> REQUIREMENT_IDINFO_COMPARTMENT_SYSML11}{
init{
result := self;
setPapyrusCSSForceValueVisible(result, TRUE);
setShowTitle(result, true);
}
}
mapping notation::BasicCompartment::fromSysML11StereotypeBraceAndCompartment(parent:notation::View) : notation::BasicCompartment when {self.oclIsTypeOf(notation::BasicCompartment) and (self.type = STEREOTYPE_BRACE_COMPARTMENT or self.type = STEREOTYPE_COMPARTMENT_COMPARTMENT) }{
init{
result := self;
if(self.element.oclIsKindOf(UML::Stereotype)){
var stereotype:UML::Stereotype := self.element.oclAsType(UML::Stereotype).toSysML14Stereotype(inS14Profile.objectsOfType(UML::Stereotype));
if (stereotype.oclIsUndefined()) {
// The stereotype was not find in SysML1.4, remove the compartment
childrenToRemove += result;
} else {
result.element := stereotype.oclAsType(ecore::EObject);
}
};
}
}
// Edges management
mapping notation::Edge::fromSysML11Edge() : notation::Edge disjuncts
notation::Edge::fromSysML11ConformDependencyAsGeneralization,
notation::Edge::fromSysML11RealizationEdgeAsInterfaceRealization, // Must be done before Realization
notation::Edge::fromSysML11RealizationEdgeAsSubstitution, // Must be done before Realization
notation::Edge::fromSysML11RealizationEdgeAsRealization,
notation::Edge::fromSysML11DependencyEdgeAsUsage,
notation::Edge::fromSysML11DefaultEdge
{}
mapping notation::Edge::fromSysML11ConformDependencyAsGeneralization() : notation::Edge when {self.oclIsTypeOf(notation::Edge) and self.type = DEPENDENCY_EDGE_SYSML14 and self.element.oclIsKindOf(UML::Generalization)} {
init {
result := self;
}
type := GENERALIZATION_EDGE_SYSML14;
var existingChildren:OrderedSet(notation::Node) := self.children;
children := object OrderedSet(notation::Node){};
existingChildren->forEach(existingChild){
if (existingChild.type = DEPENDENCY_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14) {
existingChild.type := GENERALIZATION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
setPapyrusCSSForceValueVisible(existingChild, TRUE);
children += existingChild;
};
};
}
mapping notation::Edge::fromSysML11StereotypeCommentLink() : notation::Edge when {self.type = STEREOTYPE_COMMENT_LINK} {
init {
result := self;
}
childrenToRemove += result;
}
mapping notation::Edge::fromSysML11DefaultEdge() : notation::Edge {
init {
result := self;
}
}
mapping notation::Shape::fromSysML11ShapeToSysML14Edge(inout parent:notation::View) disjuncts
notation::Shape::fromSysML11SpecificInformationFlow,
notation::Shape::fromSysML11AssociationClass,
notation::Shape::fromSysML11Association
{}
mapping notation::Shape::fromSysML11SpecificInformationFlow(inout parent:notation::View) when {self.oclIsTypeOf(notation::Shape) and not self.element.oclIsUndefined() and self.element.oclIsKindOf(UML::InformationFlow)} {
var informationFlow:UML::InformationFlow := self.element.oclAsType(UML::InformationFlow);
var informationSource:UML::NamedElement := informationFlow.informationSource->any(true);
var informationTarget:UML::NamedElement := informationFlow.informationTarget->any(true);
var sourceShape:notation::Shape := parent.children[notation::Shape]->any(curr | not curr.element.oclIsUndefined() and curr.element.oclIsKindOf(UML::NamedElement) and curr.element.oclAsType(UML::NamedElement) = informationSource);
var informationFlowEdge := object notation::Connector{
element := self.element;
var isSourceCreated:Boolean := false;
if (sourceShape.oclIsUndefined()) {
sourceShape := createShape(parent, informationSource);
var createdBounds:notation::Bounds := object notation::Bounds{};
if (self.layoutConstraint.oclIsKindOf(notation::Bounds)) {
createdBounds.x := self.layoutConstraint.oclAsType(notation::Bounds).x;
createdBounds.y := self.layoutConstraint.oclAsType(notation::Bounds).y;
createdBounds.width := self.layoutConstraint.oclAsType(notation::Bounds).width;
createdBounds.height := self.layoutConstraint.oclAsType(notation::Bounds).height;
};
sourceShape.oclAsType(notation::Shape).layoutConstraint := createdBounds;
isSourceCreated := true;
parent.children += sourceShape;
};
var targetShape:notation::Shape := parent.children[notation::Shape]->any(curr | not curr.element.oclIsUndefined() and curr.element.oclIsKindOf(UML::NamedElement) and curr.element.oclAsType(UML::NamedElement) = informationTarget);
if (targetShape.oclIsUndefined()) {
targetShape := createShape(parent, informationTarget);
var createdBounds:notation::Bounds := object notation::Bounds{};
if (self.layoutConstraint.oclIsKindOf(notation::Bounds)) {
// If the source and the target are created, move the target to 100
var createdX:Integer := self.layoutConstraint.oclAsType(notation::Bounds).x;
if (isSourceCreated) {
createdX := createdX + 100;
};
createdBounds.x := createdX;
createdBounds.y := self.layoutConstraint.oclAsType(notation::Bounds).y;
createdBounds.width := self.layoutConstraint.oclAsType(notation::Bounds).width;
createdBounds.height := self.layoutConstraint.oclAsType(notation::Bounds).height;
};
targetShape.oclAsType(notation::Shape).layoutConstraint := createdBounds;
parent.children += targetShape;
};
source := sourceShape;
target := targetShape;
};
createBendpointsForInformationFlow(informationFlowEdge);
createDefaultInformationFlowDecorationNodes(informationFlowEdge);
rootDiagram.edges += informationFlowEdge;
removeFromOwnerView(parent, self);
}
mapping notation::Shape::fromSysML11Association(inout parent:notation::View) when {self.oclIsTypeOf(notation::Shape) and not self.element.oclIsUndefined() and self.element.oclIsKindOf(UML::Association)} {
var association:UML::Association := self.element.oclAsType(UML::Association);
// Get the [0] and [1] member end for the source and target properties
var sourceProperty:UML::Property := association.memberEnd->any(true);
var targetProperty:UML::Property := association.memberEnd->any(curr | curr <> sourceProperty);
// Get the type of the property (to get or create their shapes)
var sourceType:UML::Type := sourceProperty.type;
var targetType:UML::Type := targetProperty.type;
if(not sourceType.oclIsUndefined() and not targetType.oclIsUndefined()){
// Get the source and the target shapes if exists
var sourceShape:notation::Shape := parent.children[notation::Shape]->any(curr | not curr.element.oclIsUndefined() and curr.element.oclIsKindOf(UML::Type) and curr.element.oclAsType(UML::Type) = sourceType);
var associationEdge := object notation::Connector{
element := self.element;
var isSourceCreated:Boolean := false;
if (sourceShape.oclIsUndefined()) {
sourceShape := createShape(parent, sourceType);
var createdBounds:notation::Bounds := object notation::Bounds{};
if (self.layoutConstraint.oclIsKindOf(notation::Bounds)) {
createdBounds.x := self.layoutConstraint.oclAsType(notation::Bounds).x;
createdBounds.y := self.layoutConstraint.oclAsType(notation::Bounds).y;
createdBounds.width := self.layoutConstraint.oclAsType(notation::Bounds).width;
createdBounds.height := self.layoutConstraint.oclAsType(notation::Bounds).height;
};
sourceShape.oclAsType(notation::Shape).layoutConstraint := createdBounds;
isSourceCreated := true;
parent.children += sourceShape;
};
var targetShape:notation::Shape := parent.children[notation::Shape]->any(curr | not curr.element.oclIsUndefined() and curr.element.oclIsKindOf(UML::Type) and curr.element.oclAsType(UML::Type) = targetType);
if (targetShape.oclIsUndefined()) {
targetShape := createShape(parent, targetType);
var createdBounds:notation::Bounds := object notation::Bounds{};
if (self.layoutConstraint.oclIsKindOf(notation::Bounds)) {
// If the source and the target are created, move the target to 100
var createdX:Integer := self.layoutConstraint.oclAsType(notation::Bounds).x;
if (isSourceCreated) {
createdX := createdX + 100;
};
createdBounds.x := createdX;
createdBounds.y := self.layoutConstraint.oclAsType(notation::Bounds).y;
createdBounds.width := self.layoutConstraint.oclAsType(notation::Bounds).width;
createdBounds.height := self.layoutConstraint.oclAsType(notation::Bounds).height;
};
targetShape.oclAsType(notation::Shape).layoutConstraint := createdBounds;
parent.children += targetShape;
};
source := sourceShape;
target := targetShape;
};
createBendpointsForAssociation(associationEdge);
createDefaultAssociationDecorationNodes(associationEdge);
rootDiagram.edges += associationEdge;
};
removeFromOwnerView(parent, self);
}
mapping notation::Shape::fromSysML11AssociationClass(inout parent:notation::View) when {self.oclIsTypeOf(notation::Shape) and not self.element.oclIsUndefined() and self.element.oclIsKindOf(UML::AssociationClass)} {
// Create the AssociationClass
var existingChildren:OrderedSet(notation::Node) := self.children;
var createdAssociationClassShape:notation::Shape := self;
createdAssociationClassShape.children := object OrderedSet(notation::Node){};
modifyAssociationClassShape(createdAssociationClassShape, parent);
parent.children += createdAssociationClassShape;
// Create the connector and the target and source if needed
var associationClass:UML::AssociationClass := self.element.oclAsType(UML::AssociationClass);
var assocationProperty:UML::Property := associationClass.ownedEnd->any(true);
var association:UML::Association := assocationProperty.association;
// Get the [0] and [1] member end for the source and target properties
var sourceProperty:UML::Property := association.memberEnd->any(true);
var targetProperty:UML::Property := association.memberEnd->any(curr | curr <> sourceProperty);
// Get the type of the property (to get or create their shapes)
var sourceType:UML::Type := sourceProperty.type;
var targetType:UML::Type := targetProperty.type;
// Get the source and the target shapes if exists
var targetShape:notation::Shape := parent.children[notation::Shape]->any(curr | not curr.element.oclIsUndefined() and curr.element.oclIsKindOf(UML::Type) and curr.element.oclAsType(UML::Type) = targetType);
var associationClassEdge := object notation::Connector{
element := self.element;
var isTargetCreated:Boolean := false;
if (targetShape.oclIsUndefined()) {
targetShape := createShape(parent, targetType);
var createdBounds:notation::Bounds := object notation::Bounds{};
if (self.layoutConstraint.oclIsKindOf(notation::Bounds)) {
createdBounds.x := self.layoutConstraint.oclAsType(notation::Bounds).x;
createdBounds.y := self.layoutConstraint.oclAsType(notation::Bounds).y;
createdBounds.width := self.layoutConstraint.oclAsType(notation::Bounds).width;
createdBounds.height := self.layoutConstraint.oclAsType(notation::Bounds).height;
};
targetShape.oclAsType(notation::Shape).layoutConstraint := createdBounds;
isTargetCreated := true;
parent.children += targetShape;
};
var sourceShape:notation::Shape := parent.children[notation::Shape]->any(curr | not curr.element.oclIsUndefined() and curr.element.oclIsKindOf(UML::Type) and curr.element.oclAsType(UML::Type) = sourceType);
if (sourceShape.oclIsUndefined()) {
sourceShape := createShape(parent, sourceType);
var createdBounds:notation::Bounds := object notation::Bounds{};
if (self.layoutConstraint.oclIsKindOf(notation::Bounds)) {
createdBounds.x := self.layoutConstraint.oclAsType(notation::Bounds).x;
var createdY:Integer := self.layoutConstraint.oclAsType(notation::Bounds).y;
// If the source and the target are created, move the target to 200
if (isTargetCreated) {
createdY := createdY + 200;
};
createdBounds.y := createdY;
createdBounds.width := self.layoutConstraint.oclAsType(notation::Bounds).width;
createdBounds.height := self.layoutConstraint.oclAsType(notation::Bounds).height;
};
sourceShape.oclAsType(notation::Shape).layoutConstraint := createdBounds;
parent.children += sourceShape;
};
source := sourceShape;
target := targetShape;
};
createBendpointsForAssociation(associationClassEdge);
createDefaultAssociationClassDecorationNodes(associationClassEdge);
rootDiagram.edges += associationClassEdge;
var associationClassTetherEdge := object notation::Connector{
element := self.element;
type := ASSOCIATIONCLASS_TETHEREDGE_SYSML14;
source := associationClassEdge;
target := createdAssociationClassShape;
styles += object notation::FontStyle{};
};
createBendpointsForAssociationTetherEdge(associationClassTetherEdge);
rootDiagram.edges += associationClassTetherEdge;
}
helper createShape(parent:notation::View, element:UML::NamedElement) : notation::Shape {
var res:notation::Shape;
if (element.oclIsKindOf(UML::Model)) {
res := createModelShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Package)) {
res := createPackageShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Component)) {
res := createComponentShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Class)) {
res := createClassShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Interface)) {
res := createInterfaceShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::InstanceSpecification)) {
res := createInstanceSpecificationShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::DataType)) {
res := createDataTypeShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::DurationObservation)) {
res := createDurationObservationShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::TimeObservation)) {
res := createTimeObservationShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Enumeration)) {
res := createEnumerationShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::InformationItem)) {
res := createInformationItemShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::PrimitiveType)) {
res := createPrimitiveTypeShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Signal)) {
res := createSignalShape(parent, element.oclAsType(ecore::EObject));
} elif (element.oclIsKindOf(UML::Constraint)) {
res := createConstraintShape(parent, element.oclAsType(ecore::EObject));
} else {
res := createNamedElementDefaultShape(element.oclAsType(ecore::EObject));
};
return res;
}