Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Lorenzo2016-12-09 07:21:46 -0500
committerGerrit Code Review @ Eclipse.org2016-12-11 13:45:33 -0500
commitf322a843964826fa916026e17958a22d2ffb6aa2 (patch)
tree47a800dd556523541795107253d8b17830db0234 /extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/transform/Rhapsody2PapyrusSemanticElements.qvto
parent6237c597f4b1c6ceb984687c7e0fefcef8912278 (diff)
downloadorg.eclipse.papyrus-f322a843964826fa916026e17958a22d2ffb6aa2.tar.gz
org.eclipse.papyrus-f322a843964826fa916026e17958a22d2ffb6aa2.tar.xz
org.eclipse.papyrus-f322a843964826fa916026e17958a22d2ffb6aa2.zip
Bug 496176: [Importer][Rhapsody] Papyrus must provide a tool to import Rhapsody SysML Model into Papyrus.
First commit of the Migration Tool for Rhapsody SysML Models Change-Id: I460f47cdb7b9ab485465731d6be0d3801e2b8a2f Signed-off-by: Vincent Lorenzo <vincent.lorenzo@cea.fr>
Diffstat (limited to 'extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/transform/Rhapsody2PapyrusSemanticElements.qvto')
-rw-r--r--extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/transform/Rhapsody2PapyrusSemanticElements.qvto1272
1 files changed, 1272 insertions, 0 deletions
diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/transform/Rhapsody2PapyrusSemanticElements.qvto b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/transform/Rhapsody2PapyrusSemanticElements.qvto
new file mode 100644
index 00000000000..c762f6dc4f3
--- /dev/null
+++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/transform/Rhapsody2PapyrusSemanticElements.qvto
@@ -0,0 +1,1272 @@
+/*****************************************************************************
+ * 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 org.eclipse.papyrus.migration.rhapsody.blackboxes.uml.AssociationOwnerHelper;
+import RhapsodyToPapyrusUtils;
+import SysMLRhapsodyUtils;
+
+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 umlrhapsody "strict" uses 'http://www.eclipse.org/Papyrus/UMLRhapsody/1.0.0';
+modeltype notation "strict" uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation';
+modeltype UMLPrimitivesTypes "strict" uses 'http://www.eclipse.org/uml2/5.0.0/Types' ;
+//add syml profile
+modeltype sysml11 "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/SysML';
+
+/**
+* Transformation rules for importing a Rhapsody Semantic model into a UML model
+*/
+transformation Rhapsody2PapyrusSemanticElements(in inModel:umlrhapsody, out outModel:uml, in ancyCprimitiveTypes:uml, in primitives:UMLPrimitivesTypes);
+
+property events : Set(IEvent) = null;
+
+
+/**
+* Maunch the semantic transformation
+*/
+main() {
+ log('Start UML Semantic QVTo Transfo');
+ inModel.rootObjects()[IProject]->map iProjectToPapyrusModel();
+ setAssociationOwnerAndClear();
+ log('Finish UML Semantic QVTO Transfo');
+}
+
+/**
+*
+* Create a Model from the IProject
+*/
+mapping umlrhapsody::IProject::iProjectToPapyrusModel() : uml::Model {
+ name:=self.name.replaceAll("\"","");
+ eAnnotations+=inModel.rootObjects()->selectByType(IProject)![IProject].createEAnnotationForVersioning();
+ packagedElement+=self.Subsystems.map iDefaultSubsystemTypeToPackage();
+
+ // import primitves types and C type
+ //import uml basic primitives Types
+ var importedPackages: Set(PackageImport);
+ var models : Set(Model) := primitives.objectsOfType(Model);
+ models->forEach(package){
+ var packageImport:=object PackageImport{
+ importedPackage:=package;
+ };
+ importedPackages+=packageImport;
+ };
+
+
+ //import ansi C library : TODO should be done by an other QVTo file!
+ models := ancyCprimitiveTypes.objectsOfType(Model);
+ models->forEach(package){
+ var packageImport:=object PackageImport{
+ importedPackage:=package;
+ };
+ importedPackages+=packageImport;
+ };
+
+
+ packageImport+=importedPackages;
+
+
+}
+
+/**
+* Create packages from DefaultSubsystemType
+*/
+mapping umlrhapsody::DefaultSubsystemType::iDefaultSubsystemTypeToPackage():uml::Package when{self.oclIsKindOf(ISubsystem)}{
+ var iSubSystem:ISubsystem:=self.oclAsType(ISubsystem);
+ name:=iSubSystem.name;
+
+ //no idea about this code coming from the initial prototype
+ if(iSubSystem.SignalEvents()[IEvent].oclAsSet()->notEmpty()){
+ var SignalsPackage := object Package{
+ name:= "Signals";
+ packagedElement:= iSubSystem.SignalEvents()[IEvent].map toSignals();
+ };
+ nestedPackage+=SignalsPackage;
+ };
+
+ //no idea about this code coming from the initial prototype
+ if(iSubSystem.SignalEvents()[IEvent].oclAsSet()->notEmpty()){
+ var SignalEventPackage := object Package{
+ name:= "Signal Events";
+ packagedElement:= iSubSystem.SignalEvents()[IEvent].map toSignalEvents();
+ };
+ nestedPackage+=SignalEventPackage;
+ };
+
+ packagedElement+=iSubSystem.Events[IEvent].map toSignals();
+
+ //TODO probably more check are required to remove TopLevel without problems (check with MARTE...)
+ packagedElement+= iSubSystem.Classes[IClass]->select(curr:IClass | curr.name<>"TopLevel").oclAsSet().map toUMLElement().oclAsType(uml::PackageableElement);
+ packagedElement += iSubSystem.Classes[IClass].Associations[IAssociationEnd]->select(assoEnd: IAssociationEnd |not (assoEnd.oclAsType(IAssociationEnd).inverse.oclIsUndefined()))->any(true).map toAssociationswithoutProp();
+ packagedElement += iSubSystem.Types[IType].oclAsSet().map iTypeToUMLElement().oclAsType(uml::PackageableElement);
+ packagedElement += iSubSystem.Actors->selectByKind(IActor)->oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::PackageableElement);
+ packagedElement +=iSubSystem.Declaratives[DefaultSubsystemType].oclAsSet().map iDefaultSubsystemTypeToPackage();
+ ownedComment += iSubSystem.Annotations->selectByKind(IComment)->oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Comment);
+ ownedComment += iSubSystem.description->oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Comment);
+}
+
+/**
+*
+* This method has been created to be the common entry point for all the semantic transformations from the Rhapsody Model to the UML Model
+* TODO : rewrite all transformations in order to use me everywhere
+*/
+mapping EObject::generalMappingToUMLElement():uml::Element disjuncts
+ EObject::iActorToUMLActor,
+ EObject::iCommentToUMLComment,
+ EObject::iDescriptionToUMLComment
+{}
+
+/**
+* This mapping convert an IActor into a UML Actor
+*/
+mapping EObject::iActorToUMLActor():uml::Actor when {self.oclIsTypeOf(umlrhapsody::IActor)}{
+ var actor:IActor:=self.oclAsType(IActor);
+ name:=actor.name;
+ ownedComment += actor.Annotations->selectByType(IComment).oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Comment);
+}
+
+/**
+*
+* This mapping convert a IComment into a UML Comment
+*/
+mapping EObject::iCommentToUMLComment(): uml::Comment when {self.oclIsTypeOf(IComment)}{
+ var comment:IComment:=self.oclAsType(IComment);
+ body:=comment.description.text;
+ if(body=null or body.size()=0){
+ body:=comment.description.textRTF;
+ };
+ comment.Anchors->forEach(anchor){
+ var rpyAnnotatedElement:EObject:=anchor.dependsOn.oclAsType(EObject);
+ //this is the generic method to call to create/find mapped element
+ var resolvedContext:Element:=rpyAnnotatedElement.map generalMappingToUMLElement();
+
+ //TODO : the code of the transformation should be refactored to use the previous one, nevertheless, waiting for this refactoring, we use this code
+ if(resolvedContext=null){
+ var metaClassName:String:= rpyAnnotatedElement.metaClassName();
+ annotatedElement+=switch{
+ case (metaClassName="IPart") rpyAnnotatedElement.oclAsType(umlrhapsody::IPart).map iPartToUMLElement().oclAsType(uml::Element);
+ case (metaClassName="IAttribute") rpyAnnotatedElement.oclAsType(umlrhapsody::IAttribute).map iVariableToUMLElement().oclAsType(uml::Element);
+ };
+ }else{
+ annotatedElement+=resolvedContext;
+ }
+ }
+}
+
+/**
+*
+* This mapping convert a IDescription into a UML Comment
+*/
+mapping EObject::iDescriptionToUMLComment(): uml::Comment when {self.oclIsTypeOf(IDescription)}{
+ var description:IDescription:=self.oclAsType(IDescription);
+ body:=description.text;
+ if(body=null or body.size()=0){
+ body:=description.textRTF;
+ };
+ if(self.eContainer().oclIsKindOf(Element)){
+ annotatedElement+=self.eContainer().oclAsType(Element);
+ }
+}
+
+
+/**
+* a common method to call for the creation of all UML Element
+*/
+mapping umlrhapsody::IClass::toUMLElement() : uml::Element //TODO merge me with generalMappingToUMLElement
+ disjuncts
+ umlrhapsody::IClass::toUMLInterface,
+ umlrhapsody::IClass::toClasses{} //TODO : rename me
+
+/**
+*
+* return true if the IClass is representing an interface
+*/
+mapping umlrhapsody::IClass::toUMLInterface() : uml::Interface when {self.oclIsTypeOf(IClass) and self.isInterface() /*self.isSysMLFlowSpecification()*/}{
+ name:= self.name.replaceAll("\"","");
+ ownedAttribute+= self.Attrs[IAttribute].map iVariableToUMLElement();
+// ownedAttribute+= self.Associations[IAssociationEnd].map toAssociationsEnd();
+// ownedOperation := self.Operations [IPrimitiveOperation].map toOperations();
+// ownedReception:= self.Operations[IReception].map toReceptions();
+// generalization:= self.Inheritances [IGeneralization].map toPapyrusGeneralization();
+}
+
+
+
+/**
+*
+* When we match any condition, we create a uml::Class.
+* If we are are, there is a bug!
+*/
+mapping umlrhapsody::IType::iTypeToDefault():uml::Class{
+ if(self.name=null or self.name.oclIsInvalid()){
+ if(self.declaration<>null){
+ name:=self.declaration;
+ log("We don't found the good type for an unamed element, with has this declaration: " + self.declaration);
+ }else{
+ log("We don't found the good type for an unamed element");
+ }
+ }else{
+ log("We don't found the good type for " + self.name + " so we used the default type mapping for it");
+ name:=self.name.replaceAll("\"","");
+ };
+}
+
+/**
+* a common method to map a Rhapsody iType to the expected UMLElement
+*/
+mapping umlrhapsody::IType::iTypeToUMLElement() : uml::Element
+ disjuncts
+ umlrhapsody::IType::iTypeFromRhapsodyPredefinedTypesWithUMLPrimitivesTypes,
+ umlrhapsody::IType::iTypeFromRhapsodyToUML_ANSI_C_CPPType,
+ umlrhapsody::IType::toUMLDatatype,
+ umlrhapsody::IType::toUMLInstanceSpecification,
+ umlrhapsody::IType::toUMLEnumeration,
+ umlrhapsody::IType::iTypeToUMLClass,
+ umlrhapsody::IType::iTypeToDefault
+ //don't forget to call the query mapToBasicType for created element instance of uml::TemplateableElement
+ {}
+
+
+/**
+* This method allows to map a RhapsodyType on an other type
+*/
+query umlrhapsody::IType::mapToBasicType(inout templateableElement:TemplateableElement){
+ //we assurme here that the UML PrimitiveTypes are already imported
+ var baseType:IUnit := self.typedefBaseType;
+ if(not(baseType.oclIsUndefined()) and baseType.oclIsTypeOf(IType)){
+// var name:String:=baseType.metaClassName();
+ var umlType:uml::Type :=baseType.oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ if(not(umlType.oclIsUndefined())){//should never appends
+ var templateBinding := object uml::TemplateBinding{
+
+ };
+// var redefinableTemplateSignature:=object uml::RedefinableTemplateSignature {
+//
+// };
+ var templateParameterSubstitution:= object TemplateParameterSubstitution{
+
+ };
+// var classifierTemplateParameter:= object ClassifierTemplateParameter{
+//
+// };
+
+ templateableElement.templateBinding+=templateBinding;
+ templateBinding.boundElement:=templateableElement;
+// //templateBinding.source:=templatableElement; //read only
+// //templateBinding.target:=templateParameterSubstitution; //read only
+// templateBinding.signature:=redefinableTemplateSignature;
+ templateBinding.parameterSubstitution+=templateParameterSubstitution;
+ templateParameterSubstitution.actual:=umlType;
+ };
+ };
+// return templateableElement;
+}
+
+/**
+*
+* This method allows to map Rhapsody Type defined into the file PredefinedTypes with the UML Primitives Types.
+* So, only these types are managed :
+* <ul>
+* <li>Boolean</li>
+* <li>Integer</li>
+* <li>Real</li>
+* <li>String</li>
+* <li>UnlimitedNatural</li>
+* </ul>
+*/
+mapping umlrhapsody::IType::iTypeFromRhapsodyPredefinedTypesWithUMLPrimitivesTypes():uml::Type when {self.isTranslatableIntoUMLPrimitivesTypes()}{
+ init{
+ var name:=self.name;
+ var umlTypeName:String=null;
+ umlTypeName:= switch{
+ case (name="RhpBoolean") "Boolean";
+ case (name="RhpInteger") "Integer";
+ case (name="RhpReal") "Real";
+ case (name="RhpString") "String";
+ case (name="RhpUnlimitedNatural") "UnlimitedNatural";
+ //others case not possible
+ };
+
+ if(not(umlTypeName.oclIsUndefined())){ //should always be true
+ result:=primitives.objectsOfKind(Type)->select(t | t.name=umlTypeName)->selectOne(true);
+ };
+ }
+}
+
+/**
+*
+* Returns true if the IType can be mapped with a UML PrimitiveTypes from the UML Library
+*/
+helper umlrhapsody::IType::isTranslatableIntoUMLPrimitivesTypes():Boolean{
+ var r:Boolean:=false;
+ if(self.isRhapsodyPredefinedType()){
+ var name:=self.name;
+ r:=switch{
+ case (name="RhpBoolean") true;
+ case (name="RhpInteger") true;
+ case (name="RhpReal") true;
+ case (name="RhpString") true;
+ case (name="RhpUnlimitedNatural") true;
+ else {false};
+ };
+ };
+ return r;
+}
+
+/*
+* Return true if the object must be converted into a UML DataType
+*
+* For JUnit SysML test1:
+* must be converted into UML Datatype :
+* MyBool : kind = Typedef and stereotype = DataType
+* MyArrayOfInt : kind = Typedef and stereotype DataType
+* MyPrimitivesTypes : kind = Language and stereotype = DataType
+* MySpeed : kind = kind = Typedef and ValueType
+*/
+query umlrhapsody::IType::isUMLDataType(): Boolean {
+ var res:=self.isRhapsodyDataType();
+ if(res){
+ res:= self.isKindLanguage() or self.isKindTypedef();
+ }else{
+ res:=(self.isKindTypedef() or self.isKindLanguage()) and self.isSysMLValueType();
+ };
+ return res;
+}
+
+
+/*
+* Return true if the IType kind if Typedef
+*/
+query umlrhapsody::IType::isKindTypedef(): Boolean{
+ return self.kind="Typedef";
+}
+
+
+query umlrhapsody::IType::isKindEnumeration(): Boolean{
+ return self.kind="Enumeration";
+}
+
+query umlrhapsody::IType::isKindStructure(): Boolean{
+ return self.kind="Structure";
+}
+
+
+query umlrhapsody::IType::isKindLanguage(): Boolean {
+ return self.kind="Language";
+}
+
+query umlrhapsody::IType::isUMLClass(): Boolean{
+ return self.isKindStructure() and (self.isRhapsodyDataType() or self.isSysMLValueType());
+}
+
+query umlrhapsody::IType::isUMLEnumeration():Boolean{
+ return self.isKindEnumeration() and (self.isRhapsodyDataType() or self.isSysMLValueType());
+}
+
+query umlrhapsody::IType::isUMLInstanceSpecification(): Boolean {
+ return self.isKindLanguage() and (self.isSysMLDimension() or self.isSysMLUnit());
+}
+
+
+
+
+
+
+mapping umlrhapsody::IAssociationEnd::toAssociationswithoutProp(): uml::Association
+{
+ init {
+
+ result := object uml::Association
+ {
+ var assoEnd:Set(umlrhapsody::IAssociationEnd) =inModel.rootObjects()[IProject].defaultSubsystem[ISubsystem].Classes[IClass].Associations[IAssociationEnd]->select(assoEnd: IAssociationEnd |not (assoEnd.oclAsType(IAssociationEnd).inverse.oclIsUndefined()))->asSet();
+ memberEnd:=assoEnd.map toAssociationsEnd();
+
+ }
+
+ }
+
+}
+
+mapping umlrhapsody::IAssociationEnd::toAssociationswithProp(): uml::Association {
+ //please keep this order (O source and 1 target) -> if we change this property we broke the BDD of test2
+ var localMemberEnd:=self.map toAssociationsEnd();
+ memberEnd+= localMemberEnd;
+ var localOwnedEnd:=self.map toOwnedAssociationEnd();
+ ownedEnd+= localOwnedEnd;
+ name:=localOwnedEnd.type.name + " refers to " + localMemberEnd.type.name + " as " + localMemberEnd.name;
+
+}
+
+mapping umlrhapsody::IAssociationEnd::toOwnedAssociationEnd(): uml::Property{
+ // map toClasses() maps the IClass to Class
+ type:= self.container().oclAsType(IClass).map toUMLElement().oclAsType(Type);
+ var type : uml::Class = type.oclAsType(Class);
+
+}
+
+mapping umlrhapsody::IType::toUMLDatatype() : uml::DataType when {self.isUMLDataType()}{
+ name:= self.name.replaceAll("\"","");
+ self.mapToBasicType(result.oclAsType(uml::TemplateableElement));
+
+}
+
+mapping umlrhapsody::IType::toUMLEnumeration() : uml::Enumeration when {self.isUMLEnumeration()}{
+ name:= self.name.replaceAll("\"","");
+ ownedLiteral+=self.Literals[IEnumerationLiteral].map toUMLEnumerationLiteral();
+ self.mapToBasicType(result.oclAsType(uml::TemplateableElement));
+}
+
+mapping umlrhapsody::IEnumerationLiteral::toUMLEnumerationLiteral() : uml::EnumerationLiteral {
+ name:= self.name.replaceAll("\"","");
+}
+
+mapping umlrhapsody::IType::toUMLInstanceSpecification() : uml::InstanceSpecification when {self.isUMLInstanceSpecification()}{
+ name:= self.name.replaceAll("\"","");
+}
+
+//TODO : refactore me, there is at least 2 method to create a class, on efrom an IType and an other one from a IClass
+mapping umlrhapsody::IType::iTypeToUMLClass() : uml::Class when {self.isUMLClass()}{//stereotype Block is added later in the process
+ name:= self.name.replaceAll("\"","");
+ ownedAttribute+=self.Attrs[IAttribute].map iVariableToUMLElement();
+ self.mapToBasicType(result.oclAsType(uml::TemplateableElement));
+}
+
+
+mapping umlrhapsody::IClass::toClasses(): uml::Class when {self.oclIsTypeOf(IClass) and not (self.isInterface())}{
+ name:= self.name.replaceAll("\"","");
+ ownedAttribute+= self.Attrs[IAttribute].map iVariableToUMLElement();
+ ownedAttribute+= self.Associations[IPart].map iPartToUMLElement().oclAsType(uml::Property);
+
+ var associationsToAdd:=self.Associations[IPart].map iPartToUMLAssociation();
+
+ nestedClassifier+= self.Associations[IPart]->select(current | current.implicitClass<>null).implicitClass.map toUMLElement().oclAsType(uml::Classifier);
+ nestedClassifier+=self.Declaratives[IClass].map toUMLElement().oclAsType(uml::Classifier);
+
+ ownedAttribute+= self.Associations[IAssociationEnd].map toAssociationsEnd();
+ associationsToAdd+=self.Associations[IAssociationEnd]->select(assoEnd: IAssociationEnd |assoEnd.oclAsType(IAssociationEnd).inverse.oclIsUndefined()).oclAsSet().map toAssociationswithProp();
+
+
+ ownedOperation += self.Operations [IPrimitiveOperation].map toOperations();
+ ownedReception += self.Operations[IReception].map toReceptions();
+ generalization += self.Inheritances [IGeneralization].map toPapyrusGeneralization();
+ ownedBehavior += self.StateCharts[IStateChart].map toStateMachine();
+
+ ownedAttribute+=self.Ports.map iRelationToUMLElement().oclAsType(uml::Property);
+ ownedConnector+=self.ObjectLinks[IObjectLink].map iObjectLinkToUMLElement().oclAsType(uml::Connector);
+ ownedConnector+=self.Declaratives[IInformationFlow].map iInformationFlowToUMLElement().oclAsType(uml::Connector);
+
+ ownedComment+=self.Annotations.oclAsType(IComment).oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Comment);
+
+ registerAssociationToStore(result, associationsToAdd);
+}
+
+
+/**
+* This method map a IObjectLink with a UML Element
+*
+*/
+mapping umlrhapsody::IInformationFlow::iInformationFlowToUMLElement():uml::Element disjuncts
+ umlrhapsody::IInformationFlow::iInformationFlowToUMLConnector
+{}
+
+/**
+* This method map a IInformationFlow with a UML Connector
+*
+*/
+mapping umlrhapsody::IInformationFlow::iInformationFlowToUMLConnector():uml::Connector when{self.isUMLConnector() }{
+ name:= self.name.replaceAll("\"","");
+ _end+=self.map iInformationFlowSourceToUMLConnectorEnd();
+ _end+=self.map iInformationFlowTargetToUMLConnectorEnd();
+}
+
+/**
+* This method map a IInformationFlow with a UML Connector End used as source
+*
+*/
+mapping umlrhapsody::IInformationFlow::iInformationFlowSourceToUMLConnectorEnd():uml::ConnectorEnd{
+ var end1:umlrhapsody::End1_Type:=self.end1_;
+ var end1ObjectPort:umlrhapsody::IInstance:=self.end1ObjectPort_;
+
+ var mappingEnd1:uml::Element;
+ var mappingEnd1ObjectPort:uml::Element;
+ //1. we manage the end1 property
+ if(end1<>null){
+ if(end1.oclIsTypeOf(umlrhapsody::IPart)){
+ mappingEnd1:=end1.oclAsType(umlrhapsody::IPart).map iPartToUMLElement().oclAsType(uml::Property);
+ }elif(end1.oclIsTypeOf(umlrhapsody::IAttribute)){
+ mappingEnd1:=end1.oclAsType(IAttribute).map iVariableToUMLElement();
+ }elif(end1.oclIsKindOf(umlrhapsody::IRelation)){
+ mappingEnd1:=end1.oclAsType(IRelation).map iRelationToUMLElement();
+ };
+ };
+
+ //2. we manage the end1ObjectPort_ property when required
+ if(end1ObjectPort<>null and end1ObjectPort.oclIsKindOf(umlrhapsody::IRelation)){
+ mappingEnd1ObjectPort:=end1ObjectPort.oclAsType(umlrhapsody::IRelation).map iRelationToUMLElement().oclAsType(uml::Element);
+ };
+
+ if(mappingEnd1ObjectPort=null){
+ if(mappingEnd1.oclIsTypeOf(uml::Property)){
+ role:=mappingEnd1.oclAsType(uml::Property);
+ }
+ }else{
+ if(mappingEnd1ObjectPort.oclIsTypeOf(uml::Property)){
+ role:=mappingEnd1ObjectPort.oclAsType(uml::Property);
+ }elif(mappingEnd1ObjectPort.oclIsTypeOf(uml::Port) and mappingEnd1.oclIsTypeOf(uml::Property)){
+ //not sure, not example for this usecase
+ role:=mappingEnd1ObjectPort.oclAsType(uml::Property);
+ partWithPort:=mappingEnd1.oclAsType(uml::Property);
+ };
+
+ };
+}
+
+/**
+* This method map a IInformationFlow with a UML Connector End used as target
+*
+*/
+mapping umlrhapsody::IInformationFlow::iInformationFlowTargetToUMLConnectorEnd():uml::ConnectorEnd{
+ var end2:umlrhapsody::End1_Type:=self.end2_;
+ var end2ObjectPort:umlrhapsody::IInstance:=self.end2ObjectPort_;
+
+ var mappingEnd2:uml::Element;
+ var mappingEnd2ObjectPort:uml::Element;
+ //1. we manage the end2 property
+ if(end2<>null){
+ if(end2.oclIsTypeOf(umlrhapsody::IPart)){
+ mappingEnd2:=end2.oclAsType(umlrhapsody::IPart).map iPartToUMLElement().oclAsType(uml::Property);
+ }elif(end2.oclIsTypeOf(umlrhapsody::IAttribute)){
+ mappingEnd2:=end2.oclAsType(IAttribute).map iVariableToUMLElement();
+ }elif(end2.oclIsKindOf(umlrhapsody::IRelation)){
+ mappingEnd2:=end2.oclAsType(IRelation).map iRelationToUMLElement();
+ };
+ };
+
+ //2. we manage the end2ObjectPort_ property when required
+ if(end2ObjectPort<>null and end2ObjectPort.oclIsKindOf(umlrhapsody::IRelation)){
+ mappingEnd2ObjectPort:=end2ObjectPort.oclAsType(umlrhapsody::IRelation).map iRelationToUMLElement().oclAsType(uml::Element);
+ };
+
+ if(mappingEnd2ObjectPort=null){
+ if(mappingEnd2.oclIsTypeOf(uml::Property)){
+ role:=mappingEnd2.oclAsType(uml::Property);
+ }
+ }else{
+ if(mappingEnd2ObjectPort.oclIsTypeOf(uml::Property)){
+ role:=mappingEnd2ObjectPort.oclAsType(uml::Property);
+ }elif(mappingEnd2ObjectPort.oclIsTypeOf(uml::Port) and mappingEnd2.oclIsTypeOf(uml::Property)){
+ //not sure, not example for this usecase
+ role:=mappingEnd2ObjectPort.oclAsType(uml::Property);
+ partWithPort:=mappingEnd2.oclAsType(uml::Property);
+ };
+ };
+}
+
+/**
+*
+* Returns true of the object is a UML Connector
+*/
+query umlrhapsody::IInformationFlow::isUMLConnector(): Boolean{
+ return self.Stereotypes[IStereotype]->select(ste | ste.name="BindingConnector").oclAsSet()->notEmpty()
+}
+
+
+
+/**
+* This method map a IObjectLink with a UML Element
+*
+*/
+mapping umlrhapsody::IObjectLink::iObjectLinkToUMLElement():uml::Element disjuncts
+ umlrhapsody::IObjectLink::iObjectLinkToUMLConnector
+{}
+
+/**
+* This method map a IObjectLink with a UML Connector
+*
+*/
+mapping umlrhapsody::IObjectLink::iObjectLinkToUMLConnector():uml::Connector when{self.isUMLConnector() }{
+ name:= self.name.replaceAll("\"","");
+ _end+=self.map iObjectLinkSourceToUMLConnectorEnd();
+ _end+=self.map iObjectLinkTargetToUMLConnectorEnd();
+}
+
+/**
+* This method map a IObjectLink with a UML Connector End used as source
+*
+*/
+mapping umlrhapsody::IObjectLink::iObjectLinkSourceToUMLConnectorEnd():uml::ConnectorEnd{
+ var fromLink:umlrhapsody::FromLinkType:=self.fromLink;
+ var fromPort:umlrhapsody::IRelation:=self.fromPort;
+ //1. we manage the from link property
+ if(fromLink<>null){
+ if(fromLink.oclIsTypeOf(umlrhapsody::IPart)){
+ partWithPort:=fromLink.oclAsType(umlrhapsody::IPart).map iPartToUMLElement().oclAsType(uml::Property);
+ }elif(fromLink.oclIsTypeOf(umlrhapsody::IAssociationEnd)){
+ partWithPort:=fromLink.oclAsType(IAssociationEnd).map toAssociationsEnd();
+ }elif(fromLink.oclIsKindOf(umlrhapsody::IRelation)){
+ role:=fromLink.oclAsType(umlrhapsody::IRelation).map iRelationToUMLElement().oclAsType(uml::Port);
+ };
+ };
+
+ //2. we manage the fromPort property when required
+ if(fromPort<>null and fromPort.oclIsKindOf(umlrhapsody::IRelation)){
+ if(role=null){
+ role:=fromPort.oclAsType(umlrhapsody::IRelation).map iRelationToUMLElement().oclAsType(uml::Port);
+ }
+ //I don't know what to do in other case!
+ };
+}
+
+/**
+* This method map a IObjectLink with a UML Connector End used as target
+*
+*/
+mapping umlrhapsody::IObjectLink::iObjectLinkTargetToUMLConnectorEnd():uml::ConnectorEnd{
+ var toLink:umlrhapsody::FromLinkType:=self.toLink;
+ var toPort:umlrhapsody::IRelation:=self.toPort;
+ //1. we manage the from link property
+ if(toLink<>null){
+ if(toLink.oclIsTypeOf(umlrhapsody::IPart)){
+ partWithPort:=toLink.oclAsType(umlrhapsody::IPart).map iPartToUMLElement().oclAsType(uml::Property);
+ }elif(toLink.oclIsTypeOf(umlrhapsody::IAssociationEnd)){
+ partWithPort:=toLink.oclAsType(IAssociationEnd).map toAssociationsEnd();
+ }elif(toLink.oclIsKindOf(umlrhapsody::IRelation)){
+ role:=toLink.oclAsType(umlrhapsody::IRelation).map iRelationToUMLElement().oclAsType(uml::Port);
+ };
+ };
+
+ //2. we manage the fromPort property when required
+ if(toPort<>null and toPort.oclIsKindOf(umlrhapsody::IRelation)){
+ if(role=null){
+ role:=toPort.oclAsType(umlrhapsody::IRelation).map iRelationToUMLElement().oclAsType(uml::Port);
+ }
+ //I don't know what to do in other case!
+ };
+}
+
+/**
+*
+* Returns true of the object is a UML Connector
+*/
+query umlrhapsody::IObjectLink::isUMLConnector(): Boolean{
+ return self.isStereotypedWith("connector");
+}
+
+mapping umlrhapsody::IRelation::iRelationToUMLElement():uml::Element disjuncts
+ umlrhapsody::IRelation::iRelationToSysMLPort,
+ umlrhapsody::IRelation::iRelationToUMLProperty
+{}
+
+/**
+*
+* This mapping convert a IPart into a uml Element
+*/
+mapping umlrhapsody::IPart::iPartToUMLElement():uml::Element disjuncts
+ umlrhapsody::IPart::iPartToUMLProperty
+{}
+
+/**
+* This method convert an IPart into a uml Property
+*
+*/
+mapping umlrhapsody::IPart::iPartToUMLProperty():uml::Property when {self.oclIsTypeOf(IPart)}{
+ name:= self.name.replaceAll("\"","");
+ //TODO : manage aggregation kind
+ aggregation:=AggregationKind::composite;
+ type:=self.otherClass.oclAsType(IClass).map toUMLElement().oclAsType(uml::Type);
+}
+
+mapping umlrhapsody::IPart::iPartToUMLAssociation():uml::Association when {true}{
+ var part:uml::Property:=self.resolveoneIn(umlrhapsody::IPart::iPartToUMLProperty);
+ var propOwner:uml::NamedElement:=part.owner.oclAsType(NamedElement);
+ var propType:=part.type;
+ var initialVal:=propType.invresolveone();
+ var res:Boolean:=false;
+ if(initialVal.oclIsTypeOf(umlrhapsody::IClass)){
+ //TODO : make a util for this stereotype application
+ res:=initialVal.oclAsType(umlrhapsody::IClass).Stereotypes[IStereotype]->select(ste | ste.name="ConstraintBlock")->notEmpty();
+ };
+ if(res){
+ name:=propOwner.name + " has constraint " + propType.name + " applied as " + part.name;
+ }elif(part.aggregation.toString()=AggregationKind::composite.toString()){
+ name:=propOwner.name + " owns a " + propType.name + " as " + part.name;
+ };
+
+
+ var ownedEnd2:uml::Property:= object Property{};
+
+ ownedEnd2.name:=propOwner.name.toLowerCase();
+ ownedEnd2.type:=propOwner.oclAsType(uml::Type);
+ memberEnd+=ownedEnd;
+ memberEnd+=part;
+ ownedEnd+=ownedEnd2;
+}
+
+
+/**
+* This mapping convert a IRelation instanceof ISysMLPort into a uml Property
+*
+*/
+mapping umlrhapsody::IRelation::iRelationToUMLProperty(): uml::Property when {self.isRhapsodySysMLPortRepresentingUMLProperty()}{
+ var sysPort:umlrhapsody::ISysMLPort:=self.oclAsType(ISysMLPort);
+ name:= sysPort.name.replaceAll("\"","");
+ aggregation:=AggregationKind::composite;
+ if (not sysPort.otherClass.oclIsUndefined()){
+ type := sysPort.otherClass [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ };
+ //a multiplicity has been defined
+ if(not sysPort.multiplicity.oclIsUndefined()){
+ lowerValue:= createLowerMultiplicity(sysPort.multiplicity);
+ upperValue:= createUpperMultiplicity(sysPort.multiplicity);
+ };
+}
+
+/**
+* This mapping convert a IRelation instanceof ISysMLPort into a uml Port
+*
+*/
+mapping umlrhapsody::IRelation::iRelationToSysMLPort(): uml::Port when {self.isRhapsodySysMLPortRepresentingUMLPort()}{
+ var sysPort:umlrhapsody::ISysMLPort:=self.oclAsType(ISysMLPort);
+ name:= sysPort.name.replaceAll("\"","");
+ if (not sysPort.otherClass.oclIsUndefined()){
+ type := sysPort.otherClass [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ };
+ aggregation:=AggregationKind::composite;
+ isConjugated:=sysPort.isConjugated();
+ //a multiplicity has been defined
+ if(not sysPort.multiplicity.oclIsUndefined()){
+ lowerValue:= createLowerMultiplicity(sysPort.multiplicity);
+ upperValue:= createUpperMultiplicity(sysPort.multiplicity);
+ };
+}
+
+
+query umlrhapsody::IRelation::isRhapsodySysMLPortRepresentingUMLPort(): Boolean{
+ if(self.isRhapsodyPort()){
+ return self.oclAsType(ISysMLPort).Stereotypes[IStereotype]->select(ste | ste.name="flowPort")->notEmpty();
+ //we could do an additional check, checking that owner is stereotyped by Block?
+ };
+ return false;
+}
+
+
+query umlrhapsody::IRelation::isRhapsodySysMLPortRepresentingUMLProperty(): Boolean{
+ if(self.isRhapsodyPort()){
+ return self.oclAsType(ISysMLPort).Stereotypes[IStereotype]->select(ste | ste.name="ConstraintParameter")->notEmpty();
+ //we could do an additional check, checking that owner is stereotyped by ConstraintParamater?
+ };
+ return false;
+}
+
+//TODO : merge me with previous one
+query umlrhapsody::IRelation::isRhapsodySysMLPortContraintParameter(): Boolean{
+ if(self.isRhapsodyPort()){
+ return self.oclAsType(ISysMLPort).Stereotypes[IStereotype]->select(ste | ste.name="ConstraintParameter")->notEmpty();
+ //we could do an additional check, checking that owner is stereotyped by ConstraintParamater?
+ };
+ return false;
+}
+
+
+mapping umlrhapsody::IStateChart::toStateMachine(): uml::StateMachine
+{
+ //get hierarchic states
+ var parentStates:Set(IState) :=self.getCompositeStates();
+ var allsubStates:Set(IState):= self.getallSubStates();
+ name:=self.name.replaceAll("\"","");
+
+ // create the default region : for the default ROOT region concept did not exist in rhap
+ region := object Region
+ {
+
+ name:="Region1";
+ subvertex += self.States[IState]->select(s|allsubStates->excludes(s) and parentStates->excludes(s)).map toStates();
+
+ var pseudo := object Pseudostate {
+ name :="initial";
+ kind:= PseudostateKind::initial;
+ };
+
+ subvertex+=pseudo;
+
+ //only the first default transition
+ transition += self.Transitions[IDefaultDrvdTrans]->select(t|parentStates->excludes(t.ofState)).map toInitialTransition(pseudo);
+ subvertex+= self.States[IState]->select(s|parentStates->includes(s)).map toCompositeStates(self);
+ // only transitions that its states are in the firest regions
+ transition+=self.Transitions[ITransition]->select(t|((allsubStates->excludes(t.itsTarget.oclAsType(IState))) and (allsubStates->excludes(t.itsSource.oclAsType(IState))))).map toTransitions();
+ // other mix transition (source and target not in the same region)
+ transition+=self.getMixTransitions(parentStates, allsubStates).map toTransitions();
+ };
+
+
+}
+
+query umlrhapsody::IStateChart::getMixTransitions(parentStates:Set(umlrhapsody::IState), allsubStates:Set(umlrhapsody::IState)): Set(umlrhapsody::ITransition)
+{
+var mixTrnasitions:Set(umlrhapsody::ITransition);
+var outTransitions :=self.Transitions[ITransition]->select(t|((allsubStates->excludes(t.itsTarget.oclAsType(IState))) and (allsubStates->excludes(t.itsSource.oclAsType(IState)))));
+var innerTransitions := self.Transitions[ITransition]->select(t|allsubStates->includes(t.itsSource.oclAsType(IState)) and allsubStates->includes(t.itsTarget.oclAsType(IState)));
+ mixTrnasitions := self.Transitions[ITransition]->select(t| (innerTransitions->excludes(t) and outTransitions->excludes(t)));
+return mixTrnasitions;
+}
+
+query umlrhapsody::IStateChart::getSubStates(parentstate: umlrhapsody::IState ): Set(umlrhapsody::IState)
+{
+var subStates:Set(umlrhapsody::IState);
+ self.States->forEach(state)
+ {
+ if (state.parent.oclAsType(IState)=parentstate)
+ {
+ subStates+=state.oclAsType(IState);
+ }
+ };
+ return subStates;
+}
+query umlrhapsody::IStateChart::getCompositeStates(): Set(umlrhapsody::IState)
+{
+var parentStates:Set(umlrhapsody::IState);
+ self.States->forEach(state)
+ {
+
+ if (not(state.parent.oclAsType(IState).name.replaceAll("\"","")="ROOT"))
+ {
+ parentStates+=state.parent.oclAsType(IState);
+ }
+ };
+
+ return parentStates;
+}
+
+query umlrhapsody::IStateChart::getallSubStates(): Set(umlrhapsody::IState)
+{
+var allSubStates:Set(umlrhapsody::IState);
+ self.States->forEach(state)
+ {
+ if (not(state.parent.oclAsType(IState).name.replaceAll("\"","")="ROOT"))
+ {
+ allSubStates+=state.oclAsType(IState);
+ }
+ };
+ return allSubStates;
+}
+
+mapping umlrhapsody::IDefaultDrvdTrans::toInitialTransition(pseudo:uml::Vertex): uml::Transition
+{
+
+ name:=self.name;
+ target:= self.itsTarget[IState].resolveone(State);
+ source:=pseudo;
+
+
+}
+
+mapping umlrhapsody::IState::toCompositeStates(statechart:umlrhapsody::IStateChart): uml::State
+{
+
+var allsubStates:Set(IState):= statechart.getSubStates(self);
+
+
+ name:=self.name.replaceAll("\"","");
+ result.oclAsType(State).region:= object Region
+ {
+ name:="Region1";
+ subvertex += allsubStates.map toStates();
+ var pseudo := object Pseudostate {
+
+
+ name :="initial";
+ kind:= PseudostateKind::initial;
+
+
+ };
+
+ subvertex+=pseudo;
+ transition += statechart.Transitions[IDefaultDrvdTrans]->select(t|t.ofState=self).map toInitialTransition(pseudo);
+ transition += statechart.Transitions[ITransition]->select(t|allsubStates->includes(t.itsSource.oclAsType(IState)) and allsubStates->includes(t.itsTarget.oclAsType(IState))).map toTransitions();
+
+ }
+}
+
+mapping umlrhapsody::IState::toStates(): uml::State
+when {not(self.name.replaceAll("\"","")="ROOT")}
+
+{
+ name:=self.name.replaceAll("\"","");
+}
+
+
+mapping umlrhapsody::ITransition::toTransitions(): uml::Transition
+{
+
+ name:=self.name;
+ target:= self.itsTarget[IState].resolveone(State);
+ source:=self.itsSource[IState].resolveone(State);
+ trigger:=self.itsLabel[ILabel].itsTrigger [IInterfaceItemTrigger].map toTrigger();
+ //take the first guard
+ guard:=self.itsLabel[ILabel].itsGuard[IGuard]->any(true).map toGuard();
+ effect:= self.itsLabel[ILabel].itsAction[IAction]->any(true).map toBehavior();
+}
+
+
+mapping umlrhapsody::IAction::toBehavior(): uml::OpaqueBehavior
+{
+
+ body:=self.body.trim();
+ language:= "C++";
+
+
+}
+
+mapping umlrhapsody::IGuard::toGuard(): uml::Constraint
+{
+
+ result.specification := object OpaqueExpression
+ {
+ body:=self.body.trim();
+ language:= "C++";
+ }
+
+}
+
+mapping umlrhapsody::IInterfaceItemTrigger::toTrigger(): uml::Trigger
+{
+
+ event:= self.itsInterfaceItem.resolveone(SignalEvent);
+
+
+}
+
+mapping umlrhapsody::IAssociationEnd::toAssociationsEnd(): uml::Property when{self.oclIsTypeOf(IAssociationEnd)}{
+ name:=self.name.replaceAll("\"","");
+ type:= self.otherClass.oclAsType(IClass).map toUMLElement().oclAsType(Type);
+ aggregation:=AggregationKind::none;
+}
+
+mapping umlrhapsody::IClass::fromClasse2Associations(): uml::Association
+{
+
+//TODO FIXME: default subsystem : bad code
+var classes : Set(uml::Class) :=inModel.rootObjects()[IProject].defaultSubsystem[ISubsystem].Classes[IClass].map toClasses()->asSet();
+var associations: Set(uml::Association);
+var i : Integer=0;
+classes->forEach(element)
+{
+var newasso: uml::Association;
+ // collect the classes with AssociationEnd and create an association with both classes
+ if (not (element.oclAsType(IClass).Associations[IAssociationEnd]->isEmpty()))
+ then
+ {
+ newasso := object uml::Association
+
+ {
+ var otherClass : IClass:= element.oclAsType(IClass).Associations[IAssociationEnd].otherClass->any(true).oclAsType(IClass);
+ memberEnd+= element.oclAsType(IClass).Associations[IAssociationEnd].map toAssociationsEnd();
+ memberEnd+= otherClass.Associations[IAssociationEnd].map toAssociationsEnd();
+ memberEnd->asSet();
+
+ };
+ if (i=0){
+ associations+=newasso;
+ i:= i+1;
+ };
+
+ if (not (associations->isEmpty()))
+ {
+ associations->forEach(asso)
+ {
+ if( not (asso.memberEnd->includesAll(newasso.memberEnd)))
+ associations+=newasso;
+
+ }
+ }endif;
+
+ }endif;
+
+
+
+ };
+
+}
+
+
+mapping umlrhapsody::IGeneralization::toPapyrusGeneralization(): uml::Generalization
+{
+ general:= self.oclAsType(IGeneralization).dependsOn.oclAsType(IClass).map toClasses();
+
+}
+
+mapping umlrhapsody::IReception::toReceptions(): uml::Reception
+{
+ name:= self.event.name.replaceAll("\"","");
+ signal := self.event[IEvent].resolveone(Signal);
+
+
+}
+
+mapping umlrhapsody::IPrimitiveOperation::toOperations(): uml::Operation
+{
+ name:= self.name.replaceAll("\"","");
+ // with the return type inside
+ ownedParameter:= self.Args[IArgument]->map toArguments();
+ if (not self.returnType.oclIsUndefined()){
+ var return_param:= object uml::Parameter {
+ direction:= ParameterDirectionKind::_return;
+ type:= self.returnType[IType]->any(true).map iTypeToUMLElement().oclAsType(Type);
+ };
+ ownedParameter+=return_param;
+ };
+ visibility:=getVisibility(self.protection);
+
+}
+
+mapping umlrhapsody::IVariable::iVariableToUMLElement():uml::Property disjuncts
+ umlrhapsody::IArgument::iArgumentToUMLElement,
+ umlrhapsody::IAttribute::iAttributeToUMLElement
+{}
+
+mapping umlrhapsody::IArgument::iArgumentToUMLElement(): uml::Property when {self.oclIsTypeOf(umlrhapsody::IArgument)}{
+ name:= self.oclAsType(IArgument).name.replaceAll("\"","");
+ // should add the PtR Stereotpe if the type is a C++ Declaration : i,e: Class *;
+ if (self.typeOf.oclIsUndefined()){
+ type := self.myTypeOf [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ }else{
+ type := self.typeOf [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ };
+}
+
+mapping umlrhapsody::IAttribute::iAttributeToUMLElement(): uml::Property when {self.oclIsTypeOf(umlrhapsody::IAttribute)}{
+ name:= self.name.replaceAll("\"","");
+ // should add the PtR Stereotpe if the type is a C++ Declaration : i,e: Class *;
+
+
+ if (self.typeOf.oclIsUndefined()) {
+ type := self.myTypeOf [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ }else{
+ type := self.typeOf [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ };
+ visibility:=getVisibility(self.protection);
+ var lower:String;
+ var upper:String;
+ //a multiplicity has been defined
+ if(not self.multiplicity.oclIsUndefined()){
+ lowerValue:= createLowerMultiplicity(self.multiplicity);
+ upperValue:= createUpperMultiplicity(self.multiplicity);
+ };
+}
+
+
+/**
+* Create LiteralInteger to represent the lower multiplicity
+*/
+helper createLowerMultiplicity(multiplicity:String):LiteralInteger{
+ if(multiplicity.oclIsUndefined() or multiplicity.size()=0){
+ return null;
+ };
+ var lower:String;
+ if(multiplicity.indexOf("..")<>0){
+ lower:=multiplicity.substringBefore("..");
+ }elif(multiplicity.indexOf(",")<>0){
+ lower:=multiplicity.substringBefore(",");
+ }else{
+ lower:=multiplicity;
+ };
+ var lit:LiteralInteger:= object LiteralInteger{};
+ lit.value:=lower.toInteger();
+ return lit;
+
+
+}
+
+/**
+* Create LiteralUnlimitedNatural to represent the upper multiplicity
+*/
+helper createUpperMultiplicity(multiplicity:String):LiteralUnlimitedNatural{
+ if(multiplicity.oclIsUndefined() or multiplicity.size()=0){
+ return null;
+ };
+ var upper:String;
+
+ if(multiplicity.indexOf("..")<>0){
+ upper:=multiplicity.substringAfter("..");
+ }elif(multiplicity.indexOf(",")<>0){
+ upper:=multiplicity.substringAfter(",");
+ }else{
+ upper:=multiplicity;
+ };
+
+ var lit:LiteralUnlimitedNatural:= object LiteralUnlimitedNatural{};
+ if(upper.equalsIgnoreCase("*")){
+ lit.value:=-1;
+ }else{
+ lit.value:=upper.toInteger();
+ };
+ return lit;
+}
+
+
+/**
+* Return the visibility kind for an IAttribtue or an operation
+*/
+helper getVisibility(protection:String):uml::VisibilityKind{
+ if(protection="iPublic"){
+ return VisibilityKind::public;
+ }elif(protection="iProtected"){
+ return VisibilityKind::protected;
+ }elif(protection="iPrivate"){
+ return VisibilityKind::private;
+ };
+ //seems not possible in Rhapsody
+ // elif(self.protection="iPackage"){
+ // return VisibilityKind::package;
+ // };
+ return VisibilityKind::public;
+}
+
+
+mapping umlrhapsody::IArgument::toArguments(): uml::Parameter
+{
+ name:= self.name.replaceAll("\"","");
+ direction:= getDirectionKind(self.argumentDirection);
+ // should add the PtR Stereotpe if the type is a C++ Declaration : i,e: Class *;
+ if (self.typeOf.oclIsUndefined())
+ {
+ type := self.myTypeOf [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ }else
+ {
+ type := self.typeOf [IType]->any(true).oclAsType(IType).map iTypeToUMLElement().oclAsType(Type);
+ }
+
+
+}
+
+
+query getDirectionKind(s:String): uml::ParameterDirectionKind{
+var direction: uml::ParameterDirectionKind;
+ direction:= switch {
+ case (s="in") ParameterDirectionKind::_in;
+ case (s="out") ParameterDirectionKind::_out;
+ case (s="inout") ParameterDirectionKind::_inout;
+ // there is no return direction in Rhapsody there is a returnType attribute instead,
+ };
+ return direction;
+}
+
+
+
+/**
+* Map Rhapsody Predefined Type on a Papyrus UML Predefined Types from ANSI C/CPP Lilbrary
+*
+*/
+mapping umlrhapsody::IType::iTypeFromRhapsodyToUML_ANSI_C_CPPType():uml::PrimitiveType when {self.isAManagedRhapsodyPredefinedTypes()}{
+ init{
+ result:= switch {
+ case (self.name="bool") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="bool")->any(true);
+ case (self.name="char") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="char")->any(true);
+ case (self.name="double") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="double")->any(true);
+ case (self.name="float") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="float")->any(true);
+ case (self.name="int") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="int")->any(true);
+ case (self.name="long") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="long")->any(true);
+ case (self.name="long double") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="long double")->any(true);
+ case (self.name="unsigned char") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="unsigned char")->any(true);
+ case (self.name="unsigned int") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="unsigned int")->any(true);
+ case (self.name="unsigned long") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="unsigned long")->any(true);
+ case (self.name="void") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="void")->any(true);
+ //TODO unsigned short
+ //TODO void*
+ //TODO OMBoolean
+ //TODO : OMString
+ //TODO short
+ //TODO char*
+ //TODO : RiCString
+ //TODO :RiCBoolean
+
+
+ //from Rhapsody PredefinedTypes
+ case (self.name="RhpCharacter") ancyCprimitiveTypes.objectsOfType(uml::PrimitiveType)->select(t|t.oclAsType(uml::PrimitiveType).name="char")->any(true);
+
+ };
+ }
+}
+
+/**
+*
+* Returns true if the IType is a Rhapsody Predefined Types mapped on a Papyrus UML ANSI C/C++ type
+*/
+query umlrhapsody::IType::isAManagedRhapsodyPredefinedTypes():Boolean{
+ var res:Boolean = false;
+ if(self.isRhapsodyPredefinedType() or self.isRhapsodyPredefinedC_Type() or self.isRhapsodyPredefinedCPP_Type()){
+ var name:String:=self.name;
+ res:= switch {
+ case (name="bool") true;
+ case (name="char") true;
+ case (name="double") true;
+ case (name="float") true;
+ case (name="int") true;
+ case (name="long") true;
+ case (name="long double") true;
+ case (name="unsigned char") true;
+ case (name="unsigned int")true;
+ case (name="unsigned long") true;
+ case (name="void")true;
+
+ //from Rhapsody Predefined Types
+ case (self.name="RhpCharacter") true;
+ else{false};
+ };
+ };
+ return res;
+}
+
+mapping umlrhapsody::IEvent::toSignalEvents(): uml::SignalEvent
+{
+ name:= self.name.replaceAll("\"","");
+
+ signal:= self[IEvent].resolveone(Signal);
+
+}
+
+mapping umlrhapsody::IEvent::toSignals(): uml::Signal
+{
+ name:= self.name.replaceAll("\"","");
+
+ ownedAttribute += self.Args[IVariable]->map iVariableToUMLElement();
+
+}
+
+//collect the call events from the umlrhapsody file
+
+query umlrhapsody::ISubsystem::callEvents() : Set(umlrhapsody::IEvent)
+{
+ return self.Events.oclAsType(Set(IEvent))->asSet();
+ }
+
+//collect the signal events from the umlrhapsody file
+
+query umlrhapsody::ISubsystem::SignalEvents() : Set(umlrhapsody::IEvent)
+{
+var allSignalEvents : Set(umlrhapsody::IEvent);
+var classes : Set(umlrhapsody::IClass) :=inModel.rootObjects()[IProject].defaultSubsystem[ISubsystem].Classes[IClass]->asSet();
+classes->forEach(classe)
+{
+ if (not(classe.Operations[IReception]->isEmpty()))
+ {
+
+ classe.Operations[IReception]->forEach(reception)
+ {
+ if (not(reception.oclAsType(IReception).event.oclIsUndefined()))
+ allSignalEvents+= reception.oclAsType(IReception).event;
+ }
+
+ }endif;
+};
+ return allSignalEvents;
+
+}

Back to the top