blob: 02cb142d77dd529087eb63ea13b81d94e06d9df3 [file] [log] [blame]
-- @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-------------------------------------------------------------