| -- @atlcompiler atl2006 |
| -- @nsURI uml=http://www.eclipse.org/uml2/2.1.0/UML |
| -- @nsURI kdm=http://www.eclipse.org/MoDisco/kdm |
| --authors: Gabriel Barbier, Mia-Software, gbarbier@mia-software.com |
| --Transform KDM Models to UML 2.1 models |
| |
| module KDMtoUML; |
| create umlOutput : uml from kdmInput : kdm; |
| |
| --------------------------Modified Rules---------------------------------------------------------------------- |
| |
| |
| lazy rule DataElementToAssociation { |
| from src :kdm!DataElement |
| to association :uml!Association ( |
| memberEnd<- src |
| ,memberEnd <- targetProperty |
| ,ownedEnd <- targetProperty |
| ) |
| , targetProperty :uml!Property ( |
| type <- src.refImmediateComposite() |
| ) |
| do { |
| thisModule.resolveTemp(src->getPackageContainer(), 'tgt').packagedElement <- association; |
| -- test if member type is an interface |
| if (thisModule->needRealTypeLink(src)) { |
| for (realType in thisModule->retrieveRealTypes(src)) { |
| thisModule->createDependencyForRealType(association, realType); |
| } |
| } |
| } |
| } |
| |
| |
| |
| --------------------------------End-Rules--------------------------------------------------------------------- |
| |
| --------------------------real types part--------------------------------------------------------------------- |
| -- test if type of MemberUnit or StorableUnit is kind of InterfaceUnit |
| helper def: needRealTypeLink(mbunit: kdm!DataElement) : Boolean = |
| if (mbunit->getDataElementType().oclIsUndefined()) then |
| false |
| else |
| mbunit->getDataElementType().oclIsKindOf(kdm!InterfaceUnit) |
| endif; |
| |
| -- To retrieve real types of an attribute, |
| -- we will use instanciation informations : |
| -- |
| helper def: retrieveRealTypes(mbunit: kdm!DataElement) : Sequence(kdm!Datatype) = |
| thisModule->retrieveRealTypesFromInitializer(mbunit) |
| ->union(thisModule->retrieveRealTypesFromAssignement(mbunit)); |
| -- case 1 : Type fieldName = new TypeImpl(); |
| -- We retrieve all instances of HasValue, |
| -- a first filter select instances related to source attribute |
| -- (field "from" reference mbunit) |
| -- a second filter select instances that are instanciation |
| -- (field "to" reference an object ActionElement which field kind is equals to 'class instance creation') |
| -- |
| -- To collect real type information, we have to iterate over "actionRelation" collection |
| -- of ActionElement object and select only instances of type Creates. |
| -- The real type is referenced by field "to" of Creates object. |
| -- |
| helper def: retrieveRealTypesFromInitializer(mbunit: kdm!DataElement) : Sequence(kdm!Datatype) = |
| kdm!HasValue.allInstances()->select(e | e.from = mbunit) |
| ->select(e | e.to.oclIsKindOf(kdm!ActionElement)) |
| ->select(e | e.to.kind = 'class instance creation') |
| ->collect(e | e.to.actionRelation->select(relation | relation.oclIsKindOf(kdm!Creates))) |
| ->flatten() |
| ->collect(e | e.to); |
| -- case 2 : Type fieldName; ... fieldName = new TypeImple(); |
| -- we retrieve all instances of Addresses, |
| -- we filter instances related to source attribute |
| -- (field "to" reference mbunit) |
| -- |
| -- we navigate to ActionElement which field "kind" has value 'field access', |
| -- we navigate to its container (refImmediateComposite()) |
| -- which should be an ActionElement which field "kind" has value 'assignement' and field "name" has value '=' |
| -- we iterate over "codeElement" collection to retrieve the ActionElement |
| -- which field "kind" has value 'class instance creation'. |
| -- |
| -- To collect real type information, we have to iterate over "actionRelation" collection |
| -- of ActionElement object and select only instances of type Creates. |
| -- The real type is referenced by field "to" of Creates object. |
| -- |
| helper def: retrieveRealTypesFromAssignement(mbunit: kdm!DataElement) : Sequence(kdm!Datatype) = |
| kdm!Addresses.allInstances()->select(e | e.to = mbunit) |
| ->select(e | e.from.oclIsKindOf(kdm!ActionElement)) |
| ->select(e | e.from.kind = 'field access') |
| ->collect(e | e.from.refImmediateComposite()) |
| ->select(e | e.oclIsKindOf(kdm!ActionElement)) |
| ->select(e | e.kind = 'assignment') |
| ->collect(e | e.codeElement->select(instanciation | instanciation.kind = 'class instance creation')) |
| ->flatten() |
| ->collect(e | e.actionRelation->select(relation | relation.oclIsKindOf(kdm!Creates))) |
| ->flatten() |
| ->collect(e | e.to); |
| |
| rule createDependencyForRealType(source :uml!Association, target :kdm!Datatype) { |
| to tgt :uml!Dependency( |
| name <- 'real type' |
| ,client <- source |
| ,supplier <- target |
| ) |
| do { |
| if (source.namespace.oclIsUndefined() = false) { |
| source.namespace.packagedElement <- tgt; |
| } |
| |
| -- and we have to initialize opposite property |
| source.clientDependency <- tgt; |
| } |
| } |
| |
| --------------------------End of real types part------------------------------------------------------------- |