Model Driven Engineering : Basic Concepts
Lesson 3 Model to Text Transformations : ACCELEO
Guglielmo De Angelis CNR - IASI / ISTI [email protected]
model transformation
MMM
model transformation MMM M2M
model transformation MMM M2M
M2T
what is ACCELEO ● it is a framework supporting automatic model transformations – programming language – execution framework – originally developed by Obeo, now in the Eclipse Modeling Framework
● ACCELEO has been designed following MDE principles – enabling the automatic generation of text form a given metamodel (e.g. UML, MOF, EMF)
● available documentation : – Acceleo 3 Web Site
● http://www.eclipse.org/acceleo/ – The Official Documentation
● http://www.eclipse.org/acceleo/documentation/
– The Offical Acceleo Wiki
● http://wiki.eclipse.org/Acceleo about ACCELEO
● ACCELEO is a framework supporting the implementation, and the execution of MODEL 2 TEXT transformations
about ACCELEO
● Acceleo is a framework supporting the implementation, and the execution of MODEL 2 TEXT transformations
Acceleo Transformator (i.e. the program)
Acceleo Execution Engine
about templates – 1
● a template can be seen as a document which it is partially specified – common structure for all the instances of the document – “empty fields” containing istance-specific information ● examples of documents are : – textual documents – models – source codes
about templates – 2
about templates – 3 e s r t u r t a c P u r d t e S t
a n r o e n m e m G o C
definition
● the type of the elements which can be elaborated in each “empty field” of a template is referred context
– all the possible contexts (so all the admissible type of information) depend from the referred metamodel
about templates – 4 s r o h t
c u
o a
n
t
e =
x o
t t
s
= e
t
t
i n
l t i
l o
e a c m e
=
o t s e t n o c
definition
● the type of the elements which can be elaborated in each “empty field” of a template is referred context
– all the possible contexts (so all the admissible type of information) depend from the referred metamodel
● example : – if we consider the metamodel of UML2, the example of context are:
● class, attribute, package, behavior, action
syntax – 1 ● the “empty fields” represents the variable part of a template
● they are “filled” by script areas which can emit text, according to both the context they are executed, and the given input model
● any script area is marked by means of specific tags – [
syntax – 2 ● the acceleo programming language forseen also “comment area” : [comment ... /]
● la direttiva module, definisce il modulo Acceleo che si sta implementando ed il tipo di linguaggio dei modelli in ingresso – il metamodello può essere considerato la grammatica sulla quale sono basati i modelli oggetto della trasformazione [module
example ● refer in an ACCELEO program the UML 2.0 metamodel – URI: http://www.eclipse.org/uml2/3.0.0/UML
[module myGenerate('http://www.eclipse.org/uml2/3.0.0/UML') /]
syntax – template
● the statement template declares a trasformator and it defines the elements that will match [template public myGenerator(instance : myType)] … [/template]
● the declaration of a template can include: – overriding properties – pre-conditions : ?(
● templates can be called each-other – please always think to templates as “functions”, and design them with modularity
syntax – file
● the statement file declares on which file the emitted text will be redirected [template public myGenerator(instance : myType)/] [file(fileName, appendMode, charEncoding)] … [/file] [/template]
● fileName is the file that will be created during the execution ( the ext. must be given)
● appendMode and charEncoding are optional parameters
template && file – example
[template public myGenerator(uc : UseCase)] [file (uc.name.concat('.txt'), false)] These are all the instructions for the script “generate”. [/file] [/template]
template && file – example
[template public myGenerator(uc : UseCase)] [file (uc.name.concat('.txt'), false)] These are all the instructions for the script “generate”. [/file] [/template]
● the attributes of an element are accessed like in most of the object- oriented notations
● but, some conditional expression will use the syntaxt “->” (see the following example on the IF statement) – the reason is that such expression are not attributes, but functions in the OCL constraint language
context
[template public generate(uc : UseCase)] * Explicit Reference @ Name : [uc.name/] Implicit Reference @ Name : [name/] [/template]
● the “context” is given by the element of the metamodel (i.e. a type) that is considered for that specifc portion of code
● the “context” subsumes the visibility of the functionalities and the properties that are accessible
● it is possible to refer properties both explicitely or implicetely
syntax – for ● the for statement defines loops on the matching modelied elements
● usage:
[for (
[for (
● it defines an implicit context-switch
for – example ● ... for any use case in the input model generate a list (e.g. HTML list item tag) with the names of all the contained extension point [template public generate(uc : UseCase)] [file (uc.name.concat('.html'), false)] …
- [for (uc.extensionPoint)]
- [name/] [/for]
for – example
● another implementation :
[template public generate(uc : UseCase)] [file (uc.name.concat('.html'), false)] …
- [for ( e : ExtensionPoint | uc.extensionPoint ) ]
- [name/]
- [e.name/] [/for]
syntax – if ● the statement if enables conditional generations: [if (
● where condition is a boolean
● admissible operators are : – = , <> , < , <= , > , >= , or , and , not ● operands: values, objects, call to scripts, call to services, links to metamodels
if – example [template public generate(uc : UseCase)] [file (uc.name.concat('.html'), false)] … [if (uc.extensionPoint>isEmpty())]
No Extension Points
[/fi]- [for ( e : ExtensionPoint | extensionPoint ) ]
- [e.name/] [/for]
syntax – let ● ACCELEO in mostly declarative!!! Nevertheless ...
syntax – let ● the statement let stores the result of an expression within a local variable
● a local variable is accessible only within the scope of its declaration block
● a local variable CANNOT have modified its value after the initialization
[let
ACCELEO services : advanced features ● the ACCELEO services are primitives which extend the minimal (default) language – typically they implements functionalities which are difficult to be directly coded within a “.mtl”file ● two type of services: – native services offered by the ACCELEO platform
● among the others services for the OCL support – services developed by the user of the platform
● coded directly in Java ● basically, a service is a(ny) public method offered by a Java class ● the Java classes providing services must be – imported within the templates – integrated with the generator ACCELEO services – example ● the service indexOf : – it can be applied to a sting R ( i.e. the input ) – it takes a string S as parameter – it returns the position of the first occurrence of S in R ● its signature in a Java class would be : public int indexOf (String R, String S)
● defining a service by means of a Java class: – the first parameter of (public) method is the receiver of the service
● the receiver defines the type of the objects where that service can be applied – the other parameters of the (public) method are the (ordered) parameters of the service – the return type of the (public) method matches with the type returned by the service
ACCELEO services : how to ● how to define/import services in ACCELEO? – this part is well explained in several tutorials: – http://wiki.eclipse.org/Acceleo/Getting_Started – receipt “I want see what happens under the hood”:
● implement a Java class ● implement the public method offering the service – ATTENTION!!: remember the convention about the receiver ● link the service in Java to an ACCELEO query
[query public
● import the query, if defined in some other template [import
ACCELEO services – example 1.1 public class MyService { public String firstUpper(String s){ if (s.length() > 0) s = Character.toUpperCase(s.charAt(0)) + s.substring(1); return s; } … }
ACCELEO services – example 1.2 public class MyService { public String firstUpper(String s){ if (s.length() > 0) s = Character.toUpperCase(s.charAt(0)) + s.substring(1); return s; } … } [query public acceleoFirstUpper (rec : String) : String = invoke('MyService', 'firstUpper(java.lang.String)', Sequence{'rec'}) /]
ACCELEO services – example 2
● write an ACCELEO service which counts the occurrences of a given char (as integer in ASCII) in an input string.
ACCELEO services – example 2.1 public class MyService { public int count(String str, int asciiCodeCar){ int counter=0; char c = (char) asciiCodeCar; for (int i=0; i < str.length(); i++) if (str.charAt(i) == c) counter++; return counter; } }
ACCELEO services – example 2.2 public class MyService { public int count(String str, int asciiCodeCar){ int counter=0; char c = (char) asciiCodeCar; for (int i=0; i < str.length(); i++) if (str.charAt(i) == c) counter++; return counter; } } [ query public acceleoCount (rec:String,code:Integer): Integer = invoke('MyService','count(java.lang.String,int)', Sequence{'rec','code'}) /]
basic biblio
● Marco Brambilla, Jordi Cabot, Manuel Wimmer : Model-Driven Software Engineering in Practice. Synthesis Lectures on Software Engineering, Morgan & Claypool Publishers (2012)
● J. Arlow, I. Neustadt: “UML2 e Unified Process - analisi e progettazione Object-Oriented”, 2a Ed., McgrawHill. 2007
● Acceleo
– The Official Documentation
● http://www.eclipse.org/acceleo/documentation/ – The Offical Acceleo Wiki
● http://wiki.eclipse.org/Acceleo – Acceleo 3 Web Site
● http://www.eclipse.org/acceleo/