• Keine Ergebnisse gefunden

Query/Views/Transformations (QVT)

2 MODEL DRIVEN SOFTWARE ENGINEERING

2.3 Transformation Approaches

2.3.2 Query/Views/Transformations (QVT)

2.3.1.9 Discussion

In the previous sections different classes of transformation approaches have been pre-sented. This section discusses the advantages and disadvantages of each transformation class regarding the use of it within an MDA approach.

Hard-coded transformations and direct-manipulation approaches are too low-level because transformations have to be implemented directly by the user in some programming lan-guage. Model-to-code approaches could only be used for the last step in an MDA process when models have to be serialized to code. Structure-driven approaches are too specialized because they can only be used for certain kinds of correspondences between source and target elements. Relational approaches are a good compromise between flexibility and de-clarative expressiveness.

From the academic viewpoint approaches based on graph transformations may seem the best choice because of their high expressiveness and declarative nature. The theoretical foundation of graph transformations eases solving formal questions regarding properties of transformations. But also the complexity stemming from the non-determinism in the rule scheduling and application strategy hinders the practical applicability of this approach. For example the termination of the transformation process has to be studied carefully.

Hybrid approaches combine declarative expressiveness and imperative constructs for those parts of a transformation which would be too cumbersome or even impossible to express with declarative constructs.

Model Driven Software Engineering for Web Applications

declarative specification of the relationships between models. It supports complex object pattern matching and has a visual notation similar to UML object diagrams. A Relations model can be mapped to Core, the lower level declarative language of QVT for execution on an engine implementing the Core semantics. The Core language only supports pattern matching over a flat set of variables by evaluating conditions over those variables against a set of models. All model elements of source and target are treated symmetrically. Because of its simplicity it is easier to define semantics for the Core language, see [OMG05b]. As Relations models can be mapped to Core models, Core is mainly used for implementing the declarative part of QVT. As in ATL (see 2.3.3) there is an analogy to Java and the Java Virtual Machine: Relations corresponds to the language Java and Core to the Java Virtual Machine that actually executes the transformation or program respectively. The transfor-mation that maps Relations models to Core models plays the role of the Java Compiler.

There are two mechanisms for invoking imperative implementations of transformations from Relations or Core: one standard language, called Operational Mappings using OCL with side effects, as well as non-standard black-box implementations of MOF operations.

Further there is a one-to-one mapping between operations of imperative implementations to relations in Core or Relations, meaning that even if only the imperative part of QVT is used, there is always an implicit declarative specification that is refined by the imperative implementation.

The relationship between the different parts of QVT is depicted in Figure 8.

Figure 8. Relationships between QVT parts [OMG05b]

39

2.3.2.1 Declarative Rules (Relations)

In the Relations language a transformation is specified as a set of relations that must hold for the participating models. A basic relation definition for an example transformation that maps UML classes to Java classes looks like this:

relation Class2JavaClass {

domain uml c : Class { name = cn } domain java jc : JavaClass { name = cn } }

A relation definition comprises a list of domain pattern definitions. A domain is a distin-guished typed variable that can be matched in a model of a given type. In the example there are two domains for UML and Java models, respectively. A domain pattern can be considered as a template for objects and their properties that must be located, modified, or created in a candidate model to satisfy the relation, see [OMG05b] for the definition of syntax and semantics. In the example given above, the property name in both patterns is bound to the same variable implying that they should have the same value. When execut-ing the transformation the relation above does not have any direction nor will the partici-pating models be modified, but inconsistencies are reported. Thus, this represents a mere model checking transformation.

Domains can be marked as checkonly or enforced. Checkonly domains are merely checked if there exists a valid match that satisfies the relationship. Enforced domains are first checked and when the checking fails, the target model is modified so that the relation holds. For more details about the semantics see [OMG05b]. The direction of the transfor-mation is from checkonly domains to enforced domains. The example with enforcement of creating the Java classes (if they don’t exist yet) looks like this:

relation Class2JavaClass {

checkonly domain uml c : Class { name = cn } enforce domain java jc : JavaClass { name = cn } }

A very important aspect for modeling transformations is how transformation rules can be composed. This allows giving a structure to transformation rules and facilitates reuse by decomposing complex transformations into many small ones. In QVT transformation rules can be composed by using either the when part or the where part of a rule. The when part

Model Driven Software Engineering for Web Applications

defines the guard condition of a rule. It can be used to express which rules have to be exe-cuted before executing a rule. The where part on the other hand can be used to trigger other transformations after a rule is executed. The following example uses the when part to com-pose two rules for mapping packages and their contained classes to Java:

relation Package2Package {

checkonly domain uml p : Package {

name = pn }

enforce domain java jp : Package {

name = pn, isImported = false }

}

relation Class2JavaClass {

checkonly domain uml c : Class {

name = cn,

package = p : Package {}

}

enforce domain java jc : JavaClass {

name = cn,

package = jp : Package {}

} when {

Package2Package( p, jp );

} }

The other variant using the where part (and the first version of Class2JavaClass) looks like this:

relation Package2Package {

checkonly domain uml p : Package {

name = pn,

41

ownedType = c : Class {}

}

enforce domain java jp : Package {

name = pn, isImported = false,

classes = jc : JavaClass {}

} where {

Class2JavaClass( c, jc );

} }

It case of using when the referenced rule is triggered before, in case of where after the ref-erencing rule, thus it depends on the transformation design, which solution is more appro-priate.

In addition to the textual notation there is a graphical notation for the Relations language that is similar to UML object diagrams. The example relation Class2JavaClass in the graphical notation is depicted in Figure 9. The strength of the graphical notation is the visualization of domain patterns in a intuitive way, hence facilitating the acceptance of QVT among users. For more information about the graphical notation see [OMG05b].

c : Class name = cn

jc : JavaClass name=cn

Class2JavaClass

«domain» «domain»

uml : UML java : JAVA

C E

c : Class name = cn

jc : JavaClass name=cn

Class2JavaClass

«domain» «domain»

uml : UML java : JAVA

C E

Figure 9. Graphical notation of QVT Relations

2.3.2.2 Imperative Rules (Operational Mappings)

The Operational Mappings language can either be used for a complete imperative approach or for complementing declarative relations with an imperative implementation (hybrid ap-proach). A transformation in the Operational Mappings language comprises an entry opera-tion called main and a set of mapping operaopera-tions. A mapping operaopera-tion is syntactically de-scribed by a signature of a source element type, a guard (a when clause), a mapping body

Model Driven Software Engineering for Web Applications

and a postcondition (a where clause). Even if it is not explicitly notated in the concrete syntax, a mapping operation is always a refinement of a relation, which is the owner of the when and where clauses. The method body of a mapping operation comprises imperative expressions and object expressions. Imperative expressions are a marriage between OCL expressions and typical imperative expressions as found for example in Java. Object ex-pressions provide a high-level construct for creating and/or updating model elements. For more details about syntax and semantics of Operational Mappings see [OMG05b].

The following example shows the imperative realization of the transformation rules in the previous section. Operations are always called explicitly by using the map operator. The entry point of the transformation is the entry operation main.

main() {

uml.objectsOfType( Package )->map package2Package();

}

mapping Package::package2Package() : Package {

name := self.name;

classes := self.ownedType->map class2JavaClass();

}

mapping Class::class2JavaClass() : JavaClass {

name := self.name;

}

2.3.2.3 Tools

As already stated in the introduction, the specification of QVT is currently in the finaliza-tions phase, and therefore fully compliant tool support is not yet available, although initial efforts have been made. For example, the current version of the modeling tool Together Architect 2006 for Eclipse2 provides a partial implementation of the imperative part of QVT, i.e. an implementation for operational mappings. An alternative could be the (possi-bly bi-directional) mapping from the relational part of QVT to a graph-based transforma-tion approach such as AGG or VIATRA but, as already stated in 2.3.1.9, this would be

2 Together Architect product homepage http://www.borland.com/de/products/together/index.html

43

sufficient without a mapping of the imperative part of QVT. The lack of tool support at the time of writing was one of the major reasons for choosing ATL over QVT, but this deci-sion was not made without interoperability between the approaches in mind, see also 2.3.5.