QVT

Aus SDQ-Wiki

This page contains information about the model2model transformation language QVT. As QVT is not widespread and therefore the amount of information about QVT is limited in the Internet, this should be a central repository of all information concerning QVT.

General information about QVT can be found in the german or english Wikipedia

QVT Operational

General

Tools

According to Siegfried Nolte smartQVT covers nearly all aspects from the QVT-O specification. In M2M QVT Operational some aspects from the specification are still missing. M2M seems to be much easier to use and it evolves faster than smartQVT. It can be expected that the last missing gaps from the specification are already covered or will be covered soon. Therefore, M2M should be the tool of choice.

Examples/Code Snippets

Literature/Tutorials

Experiences, Tips & Tricks

Some of these experiences can be outdated due to the constant development of both the standard and the implementation!

Escaping keywords

  • If for exemple the name of a package is the same as a keyword, then the package name has to be escaped to prevent Eclipse M2M to show a syntax error. Keywords can be escaped with a leading underscore.
  • As map is a keyword the package name: ucm::map::PathNode has to be escaped to ucm::_map::PathNode

Global variables

  • In the QVT-O specification it is possible to create global variables. As in other programming languages this is a standard variable definition, that is outside all functions or procedures.
  • Opposed to that defining a global variable in M2M causes a syntax error. Instead you have to define a global property. This can be used equal to a variable. Attention if you want to initialize the property with a value then you have to use "=" as assignment operator instead of ":=" that is neccesary everywhere else in the transformation.
  • Example: property Global : String = "123";
  • If a global variable is definded as configuration property then this variable can be assigned directly from the LaunchConfiguration.

If statement

  • The Syntax of the 'If' statement in the QVT standard and the implementation in M2M-QVTO are completely different.
    • M2M-QVTO needs the keyword 'then'
    • The 'elif' (elseif) keyword is known but not implemented. If needed this has to be compensated with nested 'if' statements.
    • QVT Spec: if (i == 0) log ('i = 0') elif (i < 0) log ("i < 0") else log ("undefined") endif;
    • M2M-QVTO: if (i = 0) then log ('i = 0') else if (i < 0) then log ("i < 0") else log ("undefined") endif endif;

Switch statement

  • The Syntax of the 'Switch' statement in the QVT standard and the implementation in M2M-QVTO are different.
    • In M2M-QVTO the variable to be 'switched' can not be specified after the switch statement. Instead it has to be repeated in every case condition.
    • QVT Spec: switch (i) { case (0) {} case (1) {} else {} };
    • M2M-QVTO: switch { case (i=0) {} case (i=1) {} else {} };

Data Structures

  • The QVT datastructures List, Dict & Tupel are not supported in M2M-QVTO.
    • Tupel is not supported at all. This means that no tupel can be defined.
    • List & Dicts can be created, but all operations to change them (e.g. add/remove elements) are not implemented!

Parameter

  • Out Parameters are not supported in M2M-QVTO.
    • A parameter for a query or helper can be defined as in, inout or out in QVT.
    • Parameters of type out produce syntax errors because they are generally not supported.
    • Parameters of type inout are possible, but no new value can be assigned to it, which means that they can only be used as in parameters.

Type conversion

  • Via the OCL operations .toString(), .toInteger(), .toReal() numbers and strings can be converted into each other.
  • Strings can be converted to lower- or uppercase via .toLower() & .toUpper() and not as defined in the OCL specification via .toLowerCase & .toUpperCase

Enumerations

  • Internally the values of an enumeration are mapped to integers. Unfortunately there is no possibility to access or change those integers directly.
  • To access an enumeration in QVT-O you have to use the following syntax: ENUMERATION::VALUE
  • E.g.: if (color = COLOR::red) then...

Access to the PCM ResourceType and PrimitiveType Repositories

  • If you want to use the primitive datatypes or the resource types that PCM defines they can be used as input models in the transformation.
    • For the ResourceType Repository define a modeltype as follows: modeltype PCM_RES_TYPE uses 'http://sdq.ipd.uka.de/PalladioComponentModel/ResourceType/4.0';
    • Include the Repository as input model: transformation xyz(... in resTypes : PCM_RES_TYPE ...) {
    • In the QVT LaunchConfiguration set pathmap://PCM_MODELS/Palladio.resourcetype as Model URI
    • The MODEL URI for the PrimitiveTypes Repository is pathmap://PCM_MODELS/PrimitiveTypes.repository

Incremental Execution

  • QVT-O can carry out transformations incrementally but has some limitations
    • no conditional statements with blocks ({})
    • no creation of new elements with object
    • avoid having mappings with the same name even if the context type is different (might result in duplicated object creation)

Using Libraries

  • When using libraries, there might be compilation problems when calling the transformation from java code
    • Editor does not show issues
    • Compiler emits warning: Cannot find imported compilation unit ...
  • Registering the folder containing your libraries might be necessary
    • Extension Point: org.eclipse.m2m.qvt.oml.runtime.qvtTransformationContainer
    • Path: Select the folder containing your library including the folders that make up the namespace (typically this is transforms)
    • Source: Eclipse Forum

QVT Relational

General

Tools

According to Siegfried Nolte mediniQVT is the best tool available for QVT-R. It is integrated into Eclipse, there is a working debugger and the specification is nearly fully covered.

Examples/Code Snippets

Literature/Tutorials

Experiences, Tips & Tricks

Using let in OCL Queries

Medini QVT has problems with type inference when another ocl query is used in a let statement. To make such queries work, one can use the expression directly or create a sub-query having the let value as a parameter.