/*****************************************************************************
* 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 org.eclipse.papyrus.migration.rhapsody.blackboxes.rhapsody.RhapsodyHelper;
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 primitives:UMLPrimitivesTypes);
property events : Set(IEvent) = null;
/**This variable is used to reference the types created outside of all contexts. (bug 510869)*/
property userTypeDeclaration: Set(Type);
/**
* 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();
//managing the rhapsodyType, importing them in the user model
var rhapsodyLibraries:Sequence(uml::Package):=getISubsystemsFromRhapsodyLibraries(self).map importRhapsodyTypeLibrary();
//we map the packaged elements
packagedElement+=self.Subsystems.map iDefaultSubsystemTypeToPackage();
//we add the rhapsody library at the end
packagedElement+=rhapsodyLibraries;//we add them add the end of the list. it is a kind of feature, to show firstly in the model the user elements
//import uml basic primitives Types by default
var importedPackages: Set(PackageImport);
var models : Set(Model) := primitives.objectsOfType(Model);
models->forEach(package){
var packageImport:=object PackageImport{
importedPackage:=package;
};
importedPackages+=packageImport;
};
packageImport+=importedPackages;
if(userTypeDeclaration->notEmpty()){
packagedElement+= object Package{
name:="UserTypesDeclaration";
packagedElement+=userTypeDeclaration;
}
}
}
/**
*
* dedicated method to import only types from Rhapsody Library
*/
mapping umlrhapsody::ISubsystem::importRhapsodyTypeLibrary():uml::Package{
name:=self.name;
packagedElement += self.Types->selectByType(IType)->selectByKind(EObject).map generalMappingToUMLElement().oclAsType(uml::PackageableElement);
}
/**
* 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()->selectByKind(EObject).map generalMappingToUMLElement().oclAsType(PackageableElement);
};
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->selectByType(IEvent)->selectByKind(EObject).map generalMappingToUMLElement().oclAsType(PackageableElement);
packagedElement+= iSubSystem.Classes->selectByType(IClass)->any(name="TopLevel").Attrs->selectByKind(IAttribute).oclAsType(EObject).map generalMappingToUMLElement().oclAsType(PackageableElement);
//TODO probably more check are required to remove TopLevel without problems (check with MARTE...)
packagedElement+= iSubSystem.Classes->selectByType(IClass)->select(curr | curr.name<>"TopLevel")->selectByKind(EObject).map generalMappingToUMLElement().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->selectByType(IType)->selectByKind(EObject).map generalMappingToUMLElement().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->select(a | (a.oclIsTypeOf(IAnnotation) or a.oclIsTypeOf(IComment)))->oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Comment);
var localComment:Comment:=iSubSystem.description.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Comment);
localComment.annotatedElement:=result;
ownedComment+=localComment;
}
/**
*
* 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 ecore::EObject::generalMappingToUMLElement():uml::Element disjuncts
ecore::EObject::iActorToUMLActor,
ecore::EObject::iCommentToUMLComment,
ecore::EObject::iDescriptionToUMLComment,
ecore::EObject::iAttributeToUMLInstanceSpecification,
ecore::EObject::iClassToUMLInterface,
ecore::EObject::iClassToUMLClass,
ecore::EObject::iEventToUMLSignal,
ecore::EObject::iTypeToUMLDatatype,
ecore::EObject::iTypeToUMLInstanceSpecification,
ecore::EObject::iTypeToUMLEnumeration,
ecore::EObject::iTypeToUMLClass, //TODO : merge me with the existing other way to create a class
ecore::EObject::iTypeToDefault
{}
/**
* 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.body;
if(body=null or body.size()=0){
body:=comment.description.text;
if(body=null or body.size()=0){
body:=comment.description.textRTF.getTextWithoutMarkers();
}
};
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.getTextWithoutMarkers();
};
if(self.eContainer().oclIsKindOf(Element)){
annotatedElement+=self.eContainer().oclAsType(Element);
}
}
/**
* This method remove all markers in the string
*/
helper String::getTextWithoutMarkers():String{
//this code seems me quite specific to my examples, but I don't have better idea
var res:String:=self.replaceAll("\\\\[a-zA-Z0-9]*", ""); //to remove all formatting information
//we remove the end of the string
var lastIndex:Integer:=res.lastIndexOf("\n}");
if(lastIndex<>-1){
res:=res.substring(1,lastIndex-1);
};
var t:="}\n "; //} + carriage return + white space
//we remove the beginning of the string
lastIndex:=res.lastIndexOf(t);
if(lastIndex<>-1){
res:=res.substring(lastIndex+t.length(),res.length());
};
return res;
}
/**
*
* return true if the IClass is representing an interface
*/
mapping ecore::EObject::iClassToUMLInterface() : uml::Interface when {self.oclIsTypeOf(umlrhapsody::IClass) and self.oclAsType(umlrhapsody::IClass).isInterface() /*self.isSysMLFlowSpecification()*/}{
var localIClass:umlrhapsody::IClass:=self.oclAsType(umlrhapsody::IClass);
name:= localIClass.name.replaceAll("\"","");
ownedAttribute+= localIClass.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::DataType.
* We can be here in case of bug, when an existing type has not been resolved
* or when the user use the C type declaration in Rhapsody (declaring a type with a string, see bug 510869)
*/
mapping ecore::EObject::iTypeToDefault():uml::DataType when{self.oclIsTypeOf(IType)}{
var localIType:IType:=self.oclAsType(IType);
if(localIType.name=null or localIType.name.oclIsInvalid()){
if(localIType.declaration<>null){
name:=localIType.declaration;
}
}else{
name:=localIType.name.replaceAll("\"","");
};
}
/**
* 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(EObject).map generalMappingToUMLElement().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;
}
/**
* 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
* IType defined in Rhapsody Library (like PredefinedTypes) must be imported as DatType
*/
query umlrhapsody::IType::isUMLDataType(): Boolean {
var res:=self.isSysMLValueType() and not self.isKindEnumeration();
if(not res){
res:=(self.isRhapsodyDataType() or self.isRhapsodyLibraryType()) and (self.isKindLanguage() or self.isKindTypedef());
};
return res;
}
/**
* Return true if the IType is kind Typedef
*/
query umlrhapsody::IType::isKindTypedef(): Boolean{
return self.kind="Typedef";
}
/**
* Return true if the IType is kind Enumeration
*/
query umlrhapsody::IType::isKindEnumeration(): Boolean{
return self.kind="Enumeration";
}
/**
* Return true if the IType is kind Enumeration
*/
query umlrhapsody::IType::isKindStructure(): Boolean{
return self.kind="Structure";
}
/**
* Return true if the IType has kind Language
*/
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()) //TODO to check : is it required to check isDatatYpe and isSysmlValueType ?
or self.isRhapsodyLibraryType()); //to create Enumeration for Type defined ni RhapsodyLibrary
}
query umlrhapsody::IType::isUMLInstanceSpecification(): Boolean {
return self.isKindLanguage() and (self.isSysMLDimension() or self.isSysMLUnit());
}
mapping umlrhapsody::IAssociationEnd::toAssociationswithoutProp(): 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{
type:= self.container().oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
var type : uml::Class = type.oclAsType(Class);
}
mapping ecore::EObject::iTypeToUMLDatatype() : uml::DataType when {self.oclIsTypeOf(IType) and self.oclAsType(IType).isUMLDataType()}{
var localIType:IType:=self.oclAsType(IType);
name:= localIType.name.replaceAll("\"","");
ownedAttribute+=localIType.Attrs[IAttribute].map iVariableToUMLElement();
localIType.mapToBasicType(result.oclAsType(uml::TemplateableElement));
}
mapping ecore::EObject::iTypeToUMLEnumeration() : uml::Enumeration when {self.oclIsTypeOf(IType) and self.oclAsType(IType).isUMLEnumeration()}{
var localIType:IType:=self.oclAsType(IType);
name:= localIType.name.replaceAll("\"","");
ownedLiteral+=localIType.Literals[IEnumerationLiteral].map toUMLEnumerationLiteral();
localIType.mapToBasicType(result.oclAsType(uml::TemplateableElement));
}
mapping umlrhapsody::IEnumerationLiteral::toUMLEnumerationLiteral() : uml::EnumerationLiteral {
name:= self.name.replaceAll("\"","");
}
mapping ecore::EObject::iTypeToUMLInstanceSpecification() : uml::InstanceSpecification when {self.oclIsTypeOf(IType) and self.oclAsType(IType).isUMLInstanceSpecification()}{
var localIType:IType:=self.oclAsType(IType);
name:= localIType.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 ecore::EObject::iTypeToUMLClass() : uml::Class when {self.oclIsTypeOf(IType) and self.oclAsType(IType).isUMLClass()}{//stereotype Block is added later in the process
var localIType:IType:=self.oclAsType(IType);
name:= localIType.name.replaceAll("\"","");
ownedAttribute+=localIType.Attrs[IAttribute].map iVariableToUMLElement();
localIType.mapToBasicType(result.oclAsType(uml::TemplateableElement));
}
mapping ecore::EObject::iClassToUMLClass(): uml::Class when {self.oclIsTypeOf(umlrhapsody::IClass) and not (self.oclAsType(umlrhapsody::IClass).isInterface())}{
var localIClass:umlrhapsody::IClass:=self.oclAsType(umlrhapsody::IClass);
name:= localIClass.name.replaceAll("\"","");
ownedAttribute+= localIClass.Attrs[IAttribute].map iVariableToUMLElement();
ownedAttribute+= localIClass.Associations[IPart].map iPartToUMLElement().oclAsType(uml::Property);
var associationsToAdd:=localIClass.Associations[IPart].map iPartToUMLAssociation();
nestedClassifier+= localIClass.Associations[IPart]->select(current | current.implicitClass<>null).implicitClass.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Classifier);
nestedClassifier+=localIClass.Declaratives->selectByType(IClass)->selectByKind(EObject).map generalMappingToUMLElement().oclAsType(uml::Classifier);
ownedAttribute+= localIClass.Associations[IAssociationEnd].map toAssociationsEnd();
associationsToAdd+=localIClass.Associations[IAssociationEnd]->select(assoEnd: IAssociationEnd |assoEnd.oclAsType(IAssociationEnd).inverse.oclIsUndefined()).oclAsSet().map toAssociationswithProp();
ownedOperation += localIClass.Operations [IPrimitiveOperation].map toOperations();
ownedReception += localIClass.Operations[IReception].map toReceptions();
generalization += localIClass.Inheritances [IGeneralization].map toPapyrusGeneralization();
ownedBehavior += localIClass.StateCharts[IStateChart].map toStateMachine();
ownedAttribute+=localIClass.Ports.map iRelationToUMLElement().oclAsType(uml::Property);
ownedConnector+=localIClass.ObjectLinks[IObjectLink].map iObjectLinkToUMLElement().oclAsType(uml::Connector);
ownedConnector+=localIClass.Declaratives[IInformationFlow].map iInformationFlowToUMLElement().oclAsType(uml::Connector);
ownedComment+=localIClass.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(EObject).map generalMappingToUMLElement().oclAsType(uml::Type);
if((not self.multiplicity.oclIsUndefined()) and self.multiplicity<>"1"){
lowerValue:=createLowerMultiplicity(self.multiplicity);
upperValue:=createUpperMultiplicity(self.multiplicity);
}
}
mapping umlrhapsody::IPart::iPartToUMLAssociation():uml::Association when {true}{
var part:uml::Property:=self.resolveoneIn(umlrhapsody::IPart::iPartToUMLProperty); //TODO : replace me with a mapping
var propOwner:uml::NamedElement:=part.owner.oclAsType(NamedElement);
var propType:=part.type;
var initialVal:=propType.invresolveone();//TODO is it a good idea to use unresolve ?
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.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
// }elif(sysPort.otherClass.oclIsKindOf(IClass)){
// type := sysPort.otherClass.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
// };
//at this time we don't generate implicite type
if(sysPort.implicitClass<>sysPort.otherClass){
type := sysPort.otherClass.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
};
//a multiplicity has been defined
if(not sysPort.multiplicity.oclIsUndefined()){
lowerValue:= createLowerMultiplicity(sysPort.multiplicity);
upperValue:= createUpperMultiplicity(sysPort.multiplicity);
}else{
lowerValue:= createLowerMultiplicity("1");
upperValue:= createUpperMultiplicity("1");
}
}
/**
* 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()){
// if(sysPort.otherClass.oclIsKindOf(IType)){
// type := sysPort.otherClass.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
// }elif(sysPort.otherClass.oclIsKindOf(IClass)){
// type := sysPort.otherClass.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
// }
// };
if(sysPort.implicitClass<>sysPort.otherClass){
type := sysPort.otherClass.oclAsType(EObject).map generalMappingToUMLElement().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);
}else{
lowerValue:= createLowerMultiplicity("1");
upperValue:= createUpperMultiplicity("1");
}
}
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(EObject).map generalMappingToUMLElement().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->selectByKind(EObject).map iClassToUMLClass()->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).oclAsType(EObject).map iClassToUMLClass();
}
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.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
};
ownedParameter+=return_param;
};
var desiredVisibility := getVisibility(self.protection);
if (desiredVisibility != VisibilityKind::public) { //to avoid green + in UML editor
visibility:= desiredVisibility
};
}
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.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
userTypeDeclaration+=type;
}else{
type := self.typeOf.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
};
}
/**
* We map IAttribute declared in the TopLevel class as instance specifications
*/
helper umlrhapsody::IAttribute::isInstanceSpecification():Boolean{
var owner:EObject:=self.oclAsType(EObject).eContainer();
return owner.oclIsKindOf(IClass) and owner.oclAsType(IClass).name="TopLevel";
}
/**
* This mapping creates InstanceSpecification from IAttribute
*/
mapping ecore::EObject::iAttributeToUMLInstanceSpecification(): uml::InstanceSpecification when {self.oclIsKindOf(IAttribute) and self.oclAsType(IAttribute).isInstanceSpecification()}{
var iAttribute:IAttribute:=self.oclAsType(IAttribute);
name:=iAttribute.name;
classifier+=iAttribute.typeOf.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(uml::Classifier);
var tmp:String:="";
if(not iAttribute.ValueSpecifications.oclIsUndefined()){
tmp:=iAttribute.ValueSpecifications.value;
};
if(classifier->any(true).oclIsTypeOf(Enumeration)){
specification:=object InstanceValue{
name:="InstanceValue1";
instance:=classifier.oclAsType(Enumeration).member->any(name=tmp).oclAsType(InstanceSpecification);
}
}else{
specification:=object OpaqueExpression{
body:=tmp;
}
}
}
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.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
userTypeDeclaration+=type;
}else{
type := self.typeOf.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
};
var desiredVisibility := getVisibility(self.protection);
if (desiredVisibility != VisibilityKind::public) { //to avoid green + in UML editor
visibility:= desiredVisibility
};
//a multiplicity has been defined
if(not self.multiplicity.oclIsUndefined()){
lowerValue:= createLowerMultiplicity(self.multiplicity);
upperValue:= createUpperMultiplicity(self.multiplicity);
};
aggregation:=AggregationKind::composite;
}
/**
* 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.oclAsType(EObject).map generalMappingToUMLElement().oclAsType(Type);
userTypeDeclaration+=type;
}else
{
type := self.typeOf.oclAsType(EObject).map generalMappingToUMLElement().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;
}
mapping umlrhapsody::IEvent::toSignalEvents(): uml::SignalEvent
{
name:= self.name.replaceAll("\"","");
signal:= self[IEvent].resolveone(Signal); //TODO replace me with a mapping
}
mapping ecore::EObject::iEventToUMLSignal(): uml::Signal when {self.oclIsTypeOf(IEvent)}{
var localEvent:IEvent:=self.oclAsType(IEvent);
name:= localEvent.name.replaceAll("\"","");
ownedAttribute += localEvent.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;
}