Medini QVT was one of the first QVT tools to be available to the community – if not the first. To my knowledge, it is still the only functional QVT Relations tool. It was developed by IKV++ Technologies, and it has a remarkable compatibility with QVT and OCL standards, being a great tool to work with QVT Relations. Moreover, it can be used inside an application and has an integrated development environment with a debug feature. However, the debugging has a problem: it does not work for queries. The tool simply ignores them…
Depending on the complexity of your solution, queries can have a very important part of your logic. So, how can we debug them? Moreover, how can we test them? Because sometimes you need a query to call another query, sometimes it is very difficult to understand what exactly have happened in a transformation. Here I will present how to use OCL Tools for this end, but it is also possible to use the QVTo plug-in if you want (you will need to learn QVT Operational).
The idea is to create operations in the metamodel and execute them using the OCL interpreter available in the OCL Tools. The steps are:
- Install OCL tools. Go to “Help->Install Modeling Components” and select “OCL Tools” (it is the last option – I have installed the version 3.0.1).
- Create a project (can be a “General Project”) and copy you ecore file. We will change it to add some operations.
- Open the ecore file and select the class where you want to create the operation and right click it “New Child->EOperation”. Write the information:
- EType: the return type (if you want to return a Set of A’s, just select A).
- Lower Bound: minimum value of returned elements.
- Name: the name of the operation.
- Ordered: if the collection returned is ordered or not.
- Unique: if the collection returned can have repeated values or not.
- Upper bound: maximum value of returned elements. -1 represents unbounded.
For example, for an OrderedSet of A’s, put Lower Bound=0, Ordered=true, Unique=true, and Upper bound=-1.
- Right click the operation and create an “EParameter” for each query parameter. The information needed is similar to the ones in the operation signature.
- Right click the operation and add an “EAnnotation”. Write as source
- In the EAnnotion created, right click and create a “Details Entry”. Now we will write the operation body. In the key put “body” and in the value put the operation body. Normally you will need just to copy-paste the body of the operation that was written in Medini QVT (there are some details I will discuss next).
- After you have created all the operations, you will have to execute them in a model. I will use a small workaround to avoid creating a new instance of Eclipse (you can also right click on a metaclass in the ecore and select “Create Dynamic Instance to create a model).
- Copy or create a model conforming to the edited metamodel.
- Change its extension to “.xmi” (for instance, change “source.abc” to “source.xmi”.
- Open it. You will get the following message: “Problems encountered. Click the ‘Details’ button for further information”. Click on “Open with Text Editor”. In the line where it is defined the metamodel, add the following code:
xsi:schemaLocation="NsURI EcoreFile", where
URIis the NsURI defined in the ecore file and
EcoreFileis the Ecore file. For instance, for the ABC metamodel, write
xsi:schemaLocation="http:///ABC.ecore ABC.ecore. Here it is a full example of a XMI file, highlighting the changed element:
<?xml version="1.0" encoding="UTF-8"?> <ABC:Root xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ABC="http:///ABC.ecore" xsi:schemaLocation="http:///ABC.ecore ABC.ecore"> <element xsi:type="ABC:A" id="1" a="Hello"/> <element xsi:type="ABC:A" a="World"/> <element xsi:type="ABC:C" id="1" c="Something"/> </ABC:Root>
Close the editor and see that the message “There are no problems with this file” appears.
- Open again the xmi file. Select the element in the xmi file where you want the operation to be executed. Right click and select “Show OCL Console” (to change the element you just have to select another one).
- Now you can call the operation using OCL. For instance, if you want to test a query named “test” in an element, just do:
and click enter.
- Every time you want to change the operation, close the xmi file.
If you prefer, you can edit the operations – and the metamodel itself – using the “OCLinEcore (Ecore) Editor” (select it in “Open With”). In my experience, sometimes you may get OCLInvalid after changing the operation. Close all the files and open the ecore using OCLinEcore Editor. Open again the xmi and it will work.
There are some differences between the code that can be used in MediniQVT and the code that can be written in OCL Tools. It seems that the OCL Tools is more compliant to the OCL standard, and, therefore, you may have to edit the query code when pasting it in the Ecore operation.
Some differences that I’ve found:
- “union”, “excluding’, and “including” is NOT defined for OrderedSet in the OCL Specification. They do not work in OCL Tools, but work in Medini QVT.
- “collect” does not work in Medini QVT.
- In general, “let” expressions does not work in Medini QVT.
- “result” is a reserved keyword in OCL (never declares a variable named “result” in the query).
That’s it. Good luck!