520 likes | 583 Views
ATL. The ATLAS Transformation Language. ATL (ATLAS Transformation Language). ATL transformation pattern ATL metamodel Helpers Operation helpers Attribute helpers Transformation rules Matched rules (Declarative rules) Imperative features ATL tools Execution engine IDE.
E N D
ATL The ATLAS Transformation Language
ATL (ATLAS Transformation Language) • ATL transformation pattern • ATL metamodel • Helpers • Operation helpers • Attribute helpers • Transformation rules • Matched rules (Declarative rules) • Imperative features • ATL tools • Execution engine • IDE
Model transformation • By definition, a model transformation is the automatic creation of target models from source models. • Model transformation is not only about M1 to M1 transformations: • M1 to M2: promotion, • M2 to M1: demotion, • M3 to M1, M3 to M2, etc.
MOF ATL MMa MMb MMa2MMb.atl Ma Mb ATL transformation pattern MMa is the source metamodel MMB is the target metamodel Ma is the source model Mb is the target model
ATL overview • Unidirectional transformation • Source models and target models are distinct. • Source models cannot be modified, only navigated. • Target models cannot be navigated. • The language is a declarative-imperative hybrid: • There are imperative or called rules. • There are declarative or matched rules. • An imperative/called rule is basically a procedure. • A declarative/matched rule specifies: • a source pattern to be matched in the source models, • a target pattern to be created in the target model for each match.
ATL helpers • The term helper comes from the OCL specification • Can only be specified on an OCL type or a source type (coming from a source metamodel) • Are specified in OCL • Have a name, a context and a type • Can be recursively defined
ATL helpers • Operation helpers • Purpose : to perform navigation over source models • Can be used to specify operations in the context of a model element or a module • Can have input parameters • Attribute helpers • Can be considered as a means to decorate source models before transformation execution • Are used to associate read-only named values to source model elements. • Cannot have input parameters, their values are specified by an OCL expression. • Can be associated to a transformation and are not always attached to a metamodel • Can be initialized in a pass performed before running the rest of the transformation but can also be lazily evaluated when the helper value is read for the first time x
ATL operation helper - example helpercontext XML!Element def: getChildren(type : OclType, name : String) : Sequence(XML!Node) = self.children->select(e | e.oclIsKindOf(type) )->select(e | e.name = name ); type can be: XML!Element XML!Attribute XML!Text <module name="My module 1"> <interface name="My interface 1"/> <interface name="My interface 1"/> <module name="My module 2"/> </module> Calling this operation with getChildren(XML!Element,’interface’) gives a sequence containing interface elements A simple XML metamodel
ATL attribute helper - example allAttributes is recursively called helpercontext SimpleClass!Class def : allAttributes : Sequence(SimpleClass!Attribute) = self.attrs->union( ifnot self.parent.oclIsUndefined() then self.parent.allAttributes->select(attr | not self.attrs->exists(at | at.name = attr.name) ) elseSequence {} endif )->flatten(); SimpleClass metamodel
Matched rules (declarative rules) Source pattern • The source pattern is composed of: • Source types coming from the source metamodels, • A guard (Boolean expression in OCL) used to filter matches. • A source pattern is evaluated to a set of matches in source models • A match corresponds to a set of elements coming from the source models that: • Are of the types specified in the source pattern (one element for each type), • Verify the guard.
Matched rules Target pattern • The target pattern is composed of: • A set of target types coming from the target metamodels • For each element of this set, a set of bindings (identified by the symbol <-). • A binding specifies the initialization of a feature of a target element using an expression whose value is used to initialize the feature. • For each match, the target pattern is applied: • Elements are created in the target models (one for each type of the target pattern), • Target elements are initialized by executing the bindings: • First evaluating their value, • Then assigning this value to the corresponding property.
Types of matched rules • There exist three types of matched rules : • Standard rules are applied once for every match that can be found in source models • Lazy rules are triggered by other rules. They are applied on a match as many times as it is referred to by other rules. A lazy rule may be applied multiple times on a single match, each time producing a new set of target elements • Unique lazy rules are also triggered by other rules. They are applied only once for a given match. If a unique lazy rule is triggered later on the same match the already created target elements are used
Matched standard rules - example rule PersistentClass2Table{ from c : SimpleClass!Class ( c.is_persistent and c.parent.oclIsUndefined() ) to t : SimpleRDBMS!Table ( name <- c.name ) } Source pattern Target pattern
Matched lazy rules - example lazy rule R1 { from s : Element to t : Element ( value <- [R2.t]s ) }
Matched uniquely lazy rules - example unique lazy rule Feature2Column { from trace : Sequence(OclAny) to col : SimpleRDBMS!Column ( name <- trace->iterate(e; acc : String = '' | acc + if acc = '' then'' else'_'endif + f.name), type <- trace->last().type ) }
Execution order • The order in which rules are matched and applied is not specified • The order in which bindings are applied is not specified • The execution of declarative rules can however be kept deterministic: • The execution of a rule cannot change source models: it cannot change the set of matches • Target elements are not navigable: the execution of a binding cannot change the value of another
Execution order • Lazy rules may lead to executions that do not terminate • Transformations run in a cycle • Recursive references are present lazy rule R1 { from s : Element to t : Element ( value <- [R2.t]s ) } lazy rule R2 { from s : Element to t : Element ( value <- [R1.t]s ) }
Called rules (imperative rules) • Are basically a procedure • Are invoked by its name and may take arguments. • Its implementation can be native or specified in ATL (e.g. as a target pattern without source pattern since no match is needed). • Can lead to executions that do not terminate due to their imperative nature • Called rules and action block helperdef: id : Integer = 0; rule getId() { -- : Integer do { thisModule.id <- thisModule.id + 1; -- increment id thisModule.id; -- returns id } } • Hybrid rules (matched rule with action block) rule Test { from s : S!Test to t : T!Test do { t.id <- thisModule.getId(); } }
Implementation of ATL • The ATL execution engine is based on a Virtual Machine (VM). • The VM executes bytecode. • There is a compiler from ATL code to bytecode. • The Virtual Machine can handle models that are: • Stored in Eclipse EMF, • Or stored in Netbeans MDR.
ATL engine algorithm - executing rules • This algorithm does not suppose an order in • Rule matching • Creation of target elements for a match • Initialization of target elements for a TraceLink • Initialization of target element’s features. • Action block (if present) must, however, be executed after having applied the declarative part of the rule. • The imperative parts of the algorithm are not completely supported yet. -- START OF ALGORITHM: execute called rule marked as entrypoint -- This results in a traditional imperative control flow. -- Match standard matched rules: ForEach standard rule R { ForEach candidate pattern C of R { -- a candidate pattern is a set of elements matching the -- types of the source pattern of a rule evaluate the guard of R on C If guard is true Then create target elements in target pattern of R create TraceLink for R, C, and target elements Else discard C EndIf } } -- Apply standard matched rules: ForEach TraceLink T { R = the rule associated to T C = the matched source pattern of T P = the created target pattern of T -- Initialize elements in the target pattern: ForEach target element E of P { -- Initialize each feature of E: ForEach binding B declared for E { expression = initialization expression of B value = evaluate expression in the context of C featureValue = resolve value set featureValue to corresponding feature of B } } execute action block of R in the context of C and T -- imperative blocks can perform any navigation in C or T and -- any action on T -- it is the programmer's responsibility to perform valid -- operations } execute called rule marked as endpoint -- We have again an imperative control flow. -- END OF ALGORITHM
The ATL Virtual Machine Architecture ATL Compiler ATL programs ATL Virtual Machine MDR (Netbeans MetaData Repository) EMF (Eclipse Modeling Framework) Etc.
Book to Publication transformation • Metamodel Book • Contains an ordered set of Chapters. • Chapters hold the information of the number of pages of Chapters, the authors. • The metamodel Publication • Contains a class Publication with a title and the total number of pages. • Transformation requirements • All chapters of a Book have to be visited to calculate the • sum of all pages • authors of all chapters
Book +title : String +book *+chapters {ordered} Chapter +title : String +nbPages : Integer +author : String Book to Publication transformation CD of a Book metamodel CD of a Publication metamodel Publication +title : String +nbPages : Integer +author : String CD = Class Diagram
A Book metamodel in KM3 The Book.km3 file package Book { class Book { attribute title :String; reference chapters[*]orderedcontainer: Chapter oppositeOf book } class Chapter { attribute title :String; attribute nbPages :Integer; attribute author :String; reference book : Book oppositeOf chapters; } } package PrimitiveTypes { datatypeInteger; datatypeString; datatypeBoolean; }
A Publication metamodel in KM3 The Publication.km3 file package Publication { class Publication { attribute title:String; attribute authors:String; attribute nbPages:Integer; } } package PrimitiveTypes { datatypeInteger; datatypeString; datatypeBoolean; } To obtain both metamodels in XMI format (.ecore extension in the ATL environment) they must be injected using the injector - KM3 file to KM3 Ecore metamodel
Book +title : String +book *+chapters {ordered} Chapter +title : String +nbPages : Integer +author : String A Book2Publication transformation The Book2Publication.atl file 1/3 module Book2Publication; create OUT : Publication from IN : Book; rule Book2Publication { from b : Book!Book ( b.getSumPages() > 2 -- only Books with more than 2 pages are publications ) to out : Publication!Publication ( title <- b.title, authors <- b.getAuthors(), nbPages <- b.getSumPages() ) } Publication +title : String +nbPages : Integer +author : String
Book +title : String +book *+chapters {ordered} Chapter +title : String +nbPages : Integer +author : String A Book2Publication transformation The Book2Publication.atl file 2/3 -- getSumPages does the same as getNbPages, -- but it uses the OCL sum operation helpercontext Book!Book def : getSumPages() : Integer = self.chapters->collect(f | f.nbPages).sum() ; -- getNbPages collects all nbPages of all chapters -- and calculates the sum helpercontext Book!Book def : getNbPages() : Integer = self.chapters->collect(f | f.nbPages)-> iterate(pages; acc : Integer = 0 | acc + pages) ;
Book +title : String +book *+chapters {ordered} Chapter +title : String +nbPages : Integer +author : String A Book2Publication transformation The Book2Publication.atl file 3/3 -- getAuthors collects all Autors of a Book -- the asSet operation removes all duplicates helpercontext Book!Book def : getAuthors() : String = self.chapters->collect(e | e.author)->asSet()-> iterate(authorName; acc : String = '' | acc + if acc = '' then authorName else' and ' + authorName endif) ;
Global view • Until here, we have : • The Book and Publication metamodels • The Book2Publication transformation
ANTLR Ecore Public metamodel Book2Publ model Book metamdel ATL metamodel ATL grammar KM3 grammar Book2Publ .atl Book .km3 Public .km3 A KM3 file to KM3 Ecore metamodel ATL file to ATL model Global view EBNF ME/EMF M3 M2 M1
Global view • Now, we need to wonder how to define the source model. For this there exist several solutions, for instance • To write an XMI document. ATL transformations use as input XMI documents and generate as output XMI documents. That means that models in ATL are materialized as XMI documents. • To write an XML document, inject it using the XML file to XML model (Ecore) and to make a very simple transformation XML to Book. The second solution is used frequently in the ATL world. We adopt this solution in the rest of this example.
ANTLR Ecore XML metamodel ATL metamodel inputMod .xml ATL grammar An XML schema inputMod- XML.ecore XML2Book model XML2Book .atl XML file to XML model (Ecore) It is generated automatically when an .atl file is saved ATL file to ATL model Global view – XML as input and XML2Book transformation XML ME/EMF EBNF XML schema M3 M2 M1
Book +title : String +book Book metamodel *+chapters {ordered} Chapter XML metamodel +title : String +nbPages : Integer +author : String The input example in XML The inputModelXML.xml file <books> <book title="livre"> <chapter title="chapter 1" nbPages="13" author="toto"/> <chapter title="chapter 2" nbPages="17" author="toto"/> <chapter title="chapter 3" nbPages="20" author="titi"/> </book> <book title="article"> <chapter title="chapter 1" nbPages="13" author="Michel"/> <chapter title="chapter 2" nbPages="1" author="David"/> </book> </books>
A XML metamodel in KM3 package XML { abstractclass Node { attribute startLine[0-1]:Integer; attribute startColumn[0-1]:Integer; attribute endLine[0-1]:Integer; attribute endColumn[0-1]:Integer; attribute name :String; attribute value :String; reference parent[0-1]: Element oppositeOf children; } class Attribute extends Node {} class Text extends Node {} class Element extends Node { reference children[*]orderedcontainer: Node oppositeOf parent; } class Root extends Element {} } package PrimitiveTypes { datatypeBoolean; datatypeInteger; datatypeString; }
A XML2Book transformation module XML2Book; create OUT : Book from IN : XML; helpercontext XML!Element def: getAttrVal(name : String) : String = self.children->select(c | c.oclIsKindOf(XML!Attribute) and c.name = name)->first().value; rule Book { from e : XML!Element ( e.name = 'book' ) to b : Book!Book ( title <- e.getAttrVal('title'), chapters <- e.children->select(c | c.oclIsKindOf(XML!Element))->asSequence() ) } rule Chapter { from e : XML!Element ( e.name = 'chapter' ) to c : Book!Chapter ( title <- e.getAttrVal('title'), nbPages <- e.getAttrVal('nbPages').toInteger(), author <- e.getAttrVal('author') )} Book +title : String +book *+chapters {ordered} Chapter +title : String +nbPages : Integer +author : String
Ecore XML metamodel ATL metamodel Book metamodel Public metamodel outputMod- Public.ecore inputMod- Book.ecore inputMod- XML.ecore XML2Book model Book2Publ model Global view As a last step, we have to execute our Book2Publication transformation! ME/EMF M3 M2 M1
Bibliography • GMT Home page. http://eclipse.org/gmt/ • ATL at GMT Home Page. http://www.eclipse.org/m2m/atl/ • ATL presentation sheet: Short presentation of ATL project. • ATL Starter's Guide: Working draft of the ATL Starter's Guide. • ATL User Manual: Working draft of the ATL User Manual. • Specification of the ATL Virtual Machine: Working draft of the specification of the ATL Virtual Machine. • ATL Transformation Description Template: Working draft of the transformation description template. • ATL home page. http://www.sciences.univ-nantes.fr/lina/atl/atldemo/