Today we dive into a technical and theoretical track on the model transformation. In this post we investigate the existing techniques in Eclipse M2M in order to transform models, going further we replace them in the live-Model context and define what do we need to design such applications. We also present the live Weaver developed by our colleague Olivier Moises, which enables to track model changes. We will see how this kind of framework can be used in live transformation.
Do we need model transformations ?
The model transformation is the possibility to transform one model in another or n models in m others. As soon as we speak about designing models, we need to speak about transforming them.
Scenarios and applications of model transformation
In this section we describe the traditional usage of model transformation. I must confess that’s a bit theoretic, if you do not want to delve into those details, skip this part. However don’t underestimate the power of such concepts in a family discussion, this can really enjoy your Christmas dinner.
In the MDA approach, source and target models are defined conforming to certain metamodels. Those metamodels can be the same or different. We speak respectively about endogenous and exogenous transformations. Two other distinctions are made of models transformations depending on the difference between the abstraction level of source and target models: horizontal and vertical transformations. These four scenarios of transformations can be mixed: an endogenous or exogenous transformation can also be a horizontal or vertical transformation as explained in [7] and illustrated in the following table.
Endogenous model transformation: transformation where source and target models are expressed in the same language (conform to the same metamodel). For examples, endogenous transformations are used for:
- Optimization: improves the performance of a program.
- Refactoring: makes structural changes in models to improve some characteristics (increasing modularity for instance) without modifying the level of abstraction and the behavior of models.
- Simplification or normalization: reduces the syntactical complexity of a program.
Exogenous model transformation: also called translation, it’s a transformation where source and target models are expressed in different languages (conform to different metamodels). For examples, exogenous transformations are used for:
- Synthesis: decreases the level of abstraction of models. For example UML Class Diagram can be translated to Java code.
- Reverse engineering: increase the level of abstraction of models. For example, Java code can be translated to UML Class Diagram (but it’s more difficult than a synthesis).
- Migration: transforms a program written in a certain language to another language belonging to the same level of abstraction. For example, a C++ program to Java program.
You can find more information about Horizontal and vertical transformations in [7].
I have heard something about ATL and Qvt in Eclipse M2M, what are they?
Query/View/Transformation (QVT)
In 2002, the OMG issued a Request For Proposals (RFP) [4] to standardize the definition of model transformation and therefore proposed the QVT standard to ensure interoperability between other standards recommended for the MDA (MOF, UML, OCL, etc.). This RFP proposes three main concepts Query, View, Transformation (QVT) whose formal definitions given by the OMG, are the following:
- Query: a query is an expression that is evaluated on a MOF model. The result of a query is one or more instances of types defined in the source model, or defined in the Query language;
- View: a view is a model that is completely derived from another model (original model);
- Transformation: a model transformation is a process for generating a target model from a source model.
The requirements are divided into two categories, here is a summary of them [6]:
Mandatory Requirements
- Query Language: a query language to make queries on MOF models;
- Language for creating views: a language used to create views of meta-models or models. However, it has not been implemented in the proposed standard;
- Transformation language: a language used to make transformations on MOF models. The definitions of transformations describe the relationship between source and target models;
- Declarative language: definition of a transformation is declarative;
- Abstract syntax of QVT in MOF: the abstract syntax of QVT languages are described in MOF 2.0.
Optional Requirements
- Bidirectional transformations: the changes could take place in both directions (transformation of a source model to a model target, and conversely, the possibility to rebuild the source from the target model);
- Traceability between source and target models: mechanisms providing the ability to save links between elements of source and target models during the transformation;
- Reusable transformations: possibility to reuse transformation definitions and to execute transactionally a transformation;
- In-place updates: a transformation where the source and target models may be the same.
QVT architecture
The QVT specification document [5] defines three languages and metamodels that are arranged in a layered architecture as shown in the figure below. These three languages are used to define model transformations of models and models are classified into two categories: declarative and imperative. Relations and Core are declarative languages and Operational Mappings is an imperative and an extension of the other two [5].
Relations able you to specify transformations as a set of relations between MOF models. It is essentially based on objects pattern matching.
Core language is simpler than Relations. It is a minimal extension of EMOF and OCL. One of its goal is to provide the basis for the specification of the semantics of Relations language, given as a transformation RelationsToCore.
In addition to these two declarative languages that reflect the same semantics at two different levels of abstractions, the standard QVT provides two mechanisms for extending Relations and Core: the Operational Mappings language and a mechanism for invoking transformation functions implemented in an arbitrary language, the Black Box. These two extensions have been proposed because it is sometimes difficult to provide a complete solution only in a declarative form.
Operational Mappings language is an imperative language standard providing OCL extensions with side effects that allow a more procedural programming approach with a concrete syntax similar to other imperative languages (loops, conditions, etc.)
The Black Box mechanism offers the possibility to add plugins and execute external code during the transformation process, which is particularly interesting. Indeed, you can code complex algorithms in any other language supporting MOF (eg Java), reuse existing libraries and make some parts of the implementations not transparent, but it can become dangerous: the implementation of a plugin can access references of obejcts in the models during the transformatin and therefore likely to perform arbitrary operations on these objects without any control.
ATLAS Transformation Language
ATL is a hybrid language: declarative and imperative. Simple transformations can be written in the declarative form, based on the principle of mapping between source and target elements. However, the code quickly becomes unreadable when trying to encode a complex transformation In this case the imperative form will be used. The main idea of ATL is that everything is a model, including the transformations. For instance, we can apply a transformation where the source models and/or targets are also transformations (ie Higher Order Processing).
ATL transformations are unidirectional, in which the source models are in a readonly mode (ie, navigable) and target models in a writeonly mode (ie not navigable). So the elements of a source model can be browsed without being able to modify them, so it is not possible to make an in-place transformation (ie changing directly to the source model). But this is a contradiction with QVT, which allows such a transformation. The navigation of elements of a target model is not allowed because they will be only initialized after completing the transformation.
The metamodels are expressed in the XMI serailization standard format or by using the INRIA metamodeling language KM3 (Kernel Meta Meta Model).
Here is a formal description of ATL based on the QVT definition [8]:
- Query: ATL query is an expression written in OCL which can return primitive values (Boolean, Integer, String etc.), elements of a model, collections, tuples, etc.
- View: the views are specific representations of models. The use of views is limited: it is difficult to update them. But it is possible to overcome this limitation by integrating two properties to a transformation language:
- Support incremental transformation: you can update a view from its source model. This avoids running the whole transformation again;
- Support for bidirectional transformation: changes in one view are propagated directly to the source model.
Currently, these properties are not supported by ATL, but according to Jean Bézivin et al. [11] bidirectional changes could be obtained by using the property of traceability.
- Transformation: ATL can transform one or more source models in one or more target models. The models must be conform to their respective MOF metamodel.
ATL architecture
As explained in [9], the architecture of ATL is divided into three layers, ATLAS Model Weaving, ATL and ATL Virtual Machine, each representing a level of abstraction. The figure below illustrates this architecture.
- AMW: a component of GMT project (Generative Modeling Technologies) (for more info: http://www.eclipse.org/gmt/amw/). This tool supports the creation of different kinds of links between model elements. These links are stored in a model (weaving model) conforming to an extensible metamodel (weaving metamodel);
- ATL Language: transformations are defined in a hybrid language declarative and imperative;
- ATL VM: the ATL compiler translates the code defined in the upper layer into byte-code, an executable code on the VM. The VM language provides a limited set of instructions grouped by categories (instructions for manipulating models, stack, memory and flow control).
Let’s see snippets
Now let’s give two practical examples of QVT Operational Mappings and ATL languages.
QVT example
Let’s take from [5] the transformation example converting an UML class diagram into a RDBMS schema. To declare a QVT transformation, transformation keyword is used followed by parentheses containing the name of models, the direction of the transformation and eventually other parameters:
modeltype UML uses SimpleUml; modeltype RDBMS uses SimpleRdbms; transformation Uml2Rdb(in srcModel:SimpleUML,out destModel:SimpleRDBMS); main() { srcModel.objectsOfType(Class)->map class2table(); srcModel.objectsOfType(Association)->map asso2table(); }
Uml2Rdbsm transformation takes in inpout a source model conforming to its metamodel SimpleUML and returns in output a target model conforming to its metamodel SimpleRDBMS. In the main section, class2table is a mapping function called to map Class type elements of source model and Table type elements of target model. Then another mapping is performed between elements of Assocation and Table by the ass2table mapping function.
Mapping operation is one of the most common operation of a QVT program. It associates one or a several elements of a source model to one or several elements of a target model. To declare a mapping function, the mapping keyword is used, then we specify the type on which the mapping will be performed (Class), followed by the the name of the function and eventually its parameters between parentheses, and at the end we specify the created type (Table).
mapping Class::class2table () : Table { name := 't_' + self.name; column := self.attributes->map attribute2column(); key_ := object Key { name := 'k_'+ self.name; column := result.column->select(c|c.kind='primary'); }; } mapping Attribute::attribute2column(): Column { type := self.type.name; name := self.name; kind := self.kind; }
class2table mapping returns a Table having the next characteristics: a name corresponding to the Class name with prefix t_, a column created from attribute2column mapping and result.column, containing the result of this operation, is used to create the primary key key_.
mapping Association::asso2table() : Table { name := self.name; column := OrderedSet{ object Column{ name := self.source.name; kind := self.source.kind; type:= 'Association'; } , object Column{ name := self.destination.name; kind := self.destination.kind; type:= 'Association'; } }; key_ := object Key{ name := self.name; column := if(self.isPersistent()) then result.column else result.column->select(c:Column | c.kind='persistent') endif; }; foreignKey := null; }
asso2table mapping transforms an association into a table. A collection of object couples (source and destination) are ordered and affected to colum attribute. isPersistent is a query testing the persistence of an association.
query UML::Association::isPersistent() : Boolean = (self.source.kind='persistent' and self.destination.kind='persistent');
To compile Operational Mappings transformation, you can use SmartQVT (an open source an Eclipse-based project implementing QVT Operational language, more info on http://smartqvt.elibel.tm.fr/). An example illustrating a result of this transformation is given by the following figure, showing an UML source model (left) transformed into a RDBMS target model (right).
ATL example
To illustrate the ATL language, we will take the simple Families2Persons example from [10]. This transformation converts a model representing the composition of a family into a model representing each member of to this family as a person. This is illustrated in the two figures below.
The header section contains the name of the transformation (Families2Persons) and the name of the source and target models (IN and OUT) which are respectively conform to Families and Persons metamodels.
module Families2Persons; create OUT : Persons from IN : Families;
A helper (also available in Operational QVT) is an operation that performs an auxiliary computation on source elements and return a result.
helper context Families!Member def: familyName : String = if not self.familyFather.oclIsUndefined() then self.familyFather.lastName else if not self.familyMother.oclIsUndefined() then self.familyMother.lastName else if not self.familySon.oclIsUndefined() then self.familySon.lastName else self.familyDaughter.lastName endif endif endif;
familyName helper returns a string containing the family name (= lastName) of a person. But this information is not available Member class. Thanks to the relation between Family and Member, it is possible to get this information by navigation.
helper context Families!Member def: isFemale() : Boolean = if not self.familyMother.oclIsUndefined() then true else if not self.familyDaughter.oclIsUndefined() then true else false endif endif;
isFemale helper checks if a member is a female by testing the familyMother and familyDaugther parameters. If the member is a mother or a daugther, the function would return a boolean with true value.
The two following rules will be used to generate in target model a Male or Female person, depending on the result of the test isFemale(). In both case, a Person has an attribute (fullName) which corresponds to the concatenation of firstName from Member and familyName from Family.
rule Member2Male { from s : Families!Member (not s.isFemale()) to t : Persons!Male ( fullName <- s.firstName + ' ' + s.familyName ) } rule Member2Female { from s : Families!Member (s.isFemale()) to t : Persons!Female ( fullName <- s.firstName + ' ' + s.familyName ) }
To compile your ATL transformation, ATL offers a complete development environment. It provides a set of tools, ATL Development Tools (ADT), integrated into the Eclipse platform (for more info, http://www.eclipse.org/m2m/atl/). An example illustrating a result of the Families2Persons transformation is given by the following figure, showing the Simpson family model (left) transformed into a Person model (right).
What’s the incremental support ?
One of the most challenging issue of model transformation is to assure consistently a synchronization between the source model and the target model. Basically, an user could change models at anytime he wants. Modification made on source model is either an atomic operation (create, delete, or update) or a set of complex atomic operations. So, the main question is: how to apply modifications made on source model elements to target model elements?
A simple solution would be to rerun the entire transformation on the modified model. This approach is not optimized because it could easily become heavy (loss of execution time) if multiple models are involved in making changes. In addition, if we use live representation of models, the instance of the target models will be overridden.
A more effective solution is to transform only the source model elements that are changed and then update some elements of the target model (and not the whole model). Formally, a transformation is called incremental if individual changes in a source model lead to execution of only those rules which matched the modified elements. To support incremental model transformations, two main approaches are presented in [11] as illustrated in the following figure.
- Re-transformation: executes a sequence of transformations generating either a target models which must be merged with the original target models, or change sets which can be directly applied to existing target models. In order to know which source elements have been modified and which haven’t. In re-transformation approach, these elements will always be re-calculated thanks to trace information (only if traceability is supported), because the execution state of the model transformation system is not maintained in this approach.
- Live transformation: change made in source model models are instantly propagated to target models. In this approach, transformation context is continuously maintained, so trace information of the current state of execution will be used to know which source elements have been modified and which haven’t. Therefore, live transformation is more efficient than re-transformation approach.
The support of incremental change is among the mandatory requirements of the QVT RFP. Core languages and declarative QVT Relations allow incremental updates (both directions) but not the imperative Operational Mappings language. So, a future improvement of SmartQVT would be the support of this property.
Regarding ATL, the current version does not directly support incremental processing. Each time a transformation is launched, the source model is fully read and the target model is completely rebuilt. Also if you launch the transformation again, the change made to the target model by the user will be lost [7]. However it would be possible to implement incremental transformation by using the traceability property, but it is still a research topic of the ATLAS group [8].
OK but why do I need live transformations?
We need to have live transformations as soon as we have live models! The first post on this blog was inaugurated by a article on Wazaabi the live EMF model Ui framework. In Wazaabi the Ui are live models, and in this case it become interesting to have live M2M to transform you UI in anything else. For instance, Architect, the Wazaabi modeler, which by the way, has been proposed as the E4 workbench editor, is based on M2M.
In Architect, the developer can design a JSF UI model. Behind the scene the editor renders a view of this model by transforming it into an SWT model. This SWT model is then rendered in a Wazaabi view which is copied in the Architect editor. As a result, you can Edit any kind of UI model and by transformations, you directly edit this model through an SWT model. For more technical information about architect check out [1], it is a good example of live M2M, and that is a cool architecture as well. If it is not clear do not mind, I will dedicated a post next week to Architect.
The Live-M2M could also be used in conjunction with live model repository such as CDO [2]. In this case, the models are stored in the repository and clients can access to their live representations. Eike Stepper shown us a cool demo of the eDine restaurant application in Eclipse summit 09 [3] based on shared live-models.
In his demo Eike adapts the model in order to visualize the result into a UI. We could imagine updating this application by transforming models. Let’s imagine that we have an “order model” which contains the content of your order. Now we could imagine that the “bill model” is just a transformation of the order according to some rules. Finally we could ultimately imagine that the UI is another transformation between the bill model and an Wazaabi UI bill model.
In order to design such kind of applications, we need to define models, transformations between them and just adapting those models to specific business logic. That’s all ! But it is an important change in design and modelling. By using live models we change the way we design applications and live Weaving is just a piece of this change.
Therefore, what’s your Live-Weaver? Is it another yet ATL?
Not at all. As we have seen, the traditional transformation method provides poor mechanisms for incremental support, but provide a full support for transformation semantics. More over, in order to define which field of which part of the model has changed, we need to define a notification system able to detect any change from input or output models. That is exactly what the Live-Weaver does, detecting changes and starting a custom process. This change can be either a value change or structural change, typically when a model elements are structurally modified, removed, moved, etc. The framework is able to detect, specific kind of change on specific parts of models.
We can attach a listener to the change notification in order to start a “synchronisation process”. This process can contain ATL transformations, custom code, WS call, etc. The aim is to be as open as possible.
By implementing a complete framework and by enabling to listen any kind of changes on models, we provide a convenient way to support live transformations, therefore, we can investigate new modelling approaches for designing live-model based applications, by (1) defining models, (2) transformation and weaving between them and (3) adapting them for specific business logic. In addition, the ability to listen any kind of changes from models can be coupled to specialized elements, such as rule engines, in order to detect “notable” event, and triggering a corresponding action. Actually, that’s noting else than a Complex Event Processing [12] applied to models change event notifications.
References
[1] Wazaabi Architect documentation, http://wazaabi.org/documentation/technical-description/architect-modeler
[2] CDO Wiki, http://wiki.eclipse.org/CDO
[3] Edine Application, http://thegordian.blogspot.com/2009/04/modeling-goes-enterprise.html
[4] Object Management Group (OMG), Meta Object Facilitiy (MOF) 2.0 Query/View/Transformation RFP. 2003.
http://www.omg.org/
[5] Object Management Group (OMG), Meta Object Facilitiy (MOF) 2.0 Query/View/Transformation Specification. 2008.
http://www.omg.org/spec/QVT/1.0/PDF/
[6] Ivan Kurtev, State of the Art of QVT: A Model Transformation Language Standard. Springer-Verlag, 2008.
http://www.springerlink.com/content/2g55gw5260q2740h/
[7] Philipp Huber’s Master Thesis, The Model Transformation Language Jungle – An Evaluation and Extension of Existing Approaches. Vienna University of Technology, 2008. http://www.big.tuwien.ac.at/teaching/theses/ma/huber.pdf
[8] Jean Bézivin, Grégoire Dupé, Frédéric Jouault, Gilles Pitette, Jamal Eddine Rougui, First experiments with the ATL model transformation language: Transforming XSLT into XQuery. In OOPSLA 2003 Workshop, Anabeim, California, 2003. http://www.softmetaware.com/oopsla2003/bezivin.pdf
[9] Frédéric Jouault, Ivan Kurtev, On the Architectural Alignment of ATL and QVT. Springer-Verlag 2006.
http://www.sciences.univ-nantes.fr/lina/atl/www/papers/ATLandQVT-PRELIMINARY%20VERSION.pdf
[10] Freddy Allilaire, Frederic Jouault, A simple illustration of model-to-model transformation. ATLAS group, INRIA & University of Nantes 2007.
http://www.eclipse.org/m2m/atl/doc/ATLUseCase_Families2Persons.pdf
[11] Istán Ráth, Gabor Bergmánn, András Örös, Dániel Varró, Live Model Transformations Driven by Incremental Pattern Matching. Springer-Verlag, 2008.
http://www.springerlink.com/content/g43052uj0p27428v/
[12] Complex Event Processing definition, Wikipedia, http://en.wikipedia.org/wiki/Complex_event_processing
Post written by S. Skhiri and C. Topak.