Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: a122d2ef1fe3d1fc60415cd6e1d61a995c3fe2b3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                                      
                                                                                 













                                                                                       
                                                                                                                            


                                     

                                                                                               

















                                                                                                                




                                                                                                                                
                                                                              




                                                                                                                                                          







                                                                   

                                        






                                                             
 
 





                                                                          
                                                                                                                                                      












                                                                                                                            
                                                                                                                                                          












                                                                                                 
                                                                                                                                                       
        
                                                                                                                                                                                                           
                                                                                                         
                                                                                                                                                                                                    
                                                                                                                                                                                                                                    
                                                                                                                                                            

                                                                                                                                                           
                                                                                                                                                                                                 


                                                                                                                                     






                                                                                                                                         





                                                                           






                                                                                                        
















                                                                                                                                              
                           
                                       



                                                                                  


























                                                                                                                                                                             
                                                                  





                                                                       























                                                                                                       



                                                        



                                                                                                                                                                                                       









                                                                                           


                                                                                                          
  





                                                                                     

                 
                                                          


          








                                                                                        
                                                                                                                             

























                                                                                                                                
 
   







                                                                  
                                                                                         

                                                    



                                                                                                                                      



                   

                                          




                                                   


                                              



                                                       


                                              



                                                     


                                            








                                                                                                 

                                                                                                                                                                                










                                                                                         


                                                                                                                                                                                                                                                                                












                                                                                                                 
                                                                                                    
                                                      

 




                                                                                                                                      

 




                                                                                                                                               





                                                                                               


                                                                                                                                                                             


                                                                                                                     




                                                                                                                                                                             


 





                                                                                                                                                                
        
                                                                                           
        

                                                                                                                                                                                                       
        

                                                                                                                                                                                                            

        







                                                                                                                                
        
                                                                                                                                              
























































































































































































































                                                                                                                                                    
                                                                                                       



                                                                                


                                                                                 
                                                                                                                             

                                                                            
                                                                                             





























                                                                                                                                              








                                                                                                                               




                                                                                   



                                                                  








                                                                                                                       








                                                                                                                               






                                                                                   



                                                                  







































































































































































































                                                                                                                                                                                                                                 
                                                                                                   






                                                                        
                                                                                                                                                            











































                                                                                                                                          
                                                                                                                        


















                                                                        
                                                                                                           


                                     




                                                                                           







                                                                               

 



                                                                                                                       
                                                                                                          
                                          
              
                                                                                                        


          










                                                                                     
                                                                                                                                                                                        

                                                              
                                                                                                                     
















                                                                                                                           





                                                                                                                          
                                                                                                          
                                          
              
                                                                                                        
          



                                                                                           

                                         



                                                                        

                                                













































































                                                                                        
                                                                                                          
                                          

             
                                                                                                

















                                                                                                     



                                                               
                                                                                  


        



                                                                                         






























                                                                                                                               
/*****************************************************************************
 * 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;
	
}

Back to the top