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! Feel free to ask Christopher Gerking as project lead of Eclipse QVTo (as of 2024).

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 supported 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

  • M2M-QVTO supports a shorthand notation for if-then-else statements since 2013. It is based on the 'elif' (elseif) keyword:
    • Long: if (i = 0) then log ('i = 0') else if (i < 0) then log ("i < 0") else log ("undefined") endif endif;
    • Short: if (i = 0) log ('i = 0') elif (i < 0) log ("i < 0") else log ("undefined") endif;
    • Note that in the above examples, the "=" comparison operator can not be replaced by the "==" operator (unlike described in the QVT specification).

Switch statement

  • In M2M-QVTO, a 'switch' statement can be used to express conditions as well.
    • The above example including the 'elif' keyword can be rewritten as follows: switch { case (i = 0) log ('i = 0'); case (i < 0) log ("i < 0"); else log ("undefined"); };
    • A 'switch' statement can also be used to collect 'switched' values from a collection. In this case, an iterator variable for the values to be 'switched' can be specified after the switch statement: var values = Sequence{0,-1,1}->switch(i) { case (i = 0) 'i = 0'; case (i < 0) "i < 0"; else "undefined"; }; Note that in the above example, the values to be collected must not be enclosed in curly brackets, e.g., {'i = 0';}. Otherwise, the collected values are treated as blocks which are executed but finally evaluated to 'null' values.

Data Structures

  • The QVT data structures List, Dict & Tuple are supported in M2M-QVTO. Since List and Dict are mutable collection types, their contents can be changed (unlike default OCL collection types like Set or Sequence).
    • A tuple can be defined as follows: var tuple = Tuple{i=1, s='1'};
    • A dictionary can be defined as follows: var dict = Dict {1="1", 2="2"}; The dictionary entries can be changed using operations like 'put(...)', e.g., dict->put(3,"3");
    • A list can be defined as follows: var list = List{1,2}; Changing a list is possible using operations like 'add(...)' or 'removeAt(...)', e.g., list.add(3);

Parameter

  • Out parameters are supported in M2M-QVTO since 2014.
    • A parameter for a query or helper can be defined as in, inout or out in QVT.
    • Parameters of type out or inout are possible, but subject to specific restrictions summarized here.

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(). The operations .toLowerCase() & .toUpperCase(), as defined in the OCL specification, can be used alternatively.

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.