Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » QVT-OML » Change in Helper/Mapping behaviour from QVTO 3.2.2 to 3.3.0
Change in Helper/Mapping behaviour from QVTO 3.2.2 to 3.3.0 [message #1270193] Wed, 12 March 2014 16:47 Go to next message
Gunnar Teege is currently offline Gunnar TeegeFriend
Messages: 3
Registered: March 2014
Junior Member
Hi,

I have been hit by a changed behaviour of mappings in chained in-place transformations from QVTO 3.2.2 to 3.3.0.

I implemented a complex in-place transformation on Ecore models as a sequential chain of simpler in-place transformations. Sometimes, a simple transformation adds model parts which will be removed again by later transformations in the chain. If implemented using nested mappings problems arise beginning with QVTO 3.3.0. However, am not sure whether this is due to my misunderstanding the concept of mappings in in-place transformations. Here is the detailed description of the problem (simplified as much as possible for demonstration purposes):

In a library "LibAnno" (see attached files) I implemented the function "removeAnno" removing EAnnotation details as a mapping and used that in another mapping "setAnno" for replacing EAnnotation details by first removing and then adding them. I have two in-place transformations "Test1Trans" and "Test2Trans" which simply replace at all classes for all EAnnotations with source "Anno" all details with key "initval" by a detail with the same key and value "test1" or "test2", resp. When I apply the transformations one at a time to a test model Examp.ecore with one Class, one EAnnotation and one existing detail with key "initval" all works fine. Now I have another transformation "Chain" which applies both transformations sequentially to the same in-memory model.

In QVTO 3.2.2 (Juno) this also works fine, the result is an EAnnotation with the single detail with value "test2". In QVTO 3.3.0 (in Kepler) and 3.4.0 (in Luna) the same transformation results in an EAnnotation with two details with values "test1" and "test2". It seems that the "test1" detail which has been added by the first transformation could not be removed by the second transformation.

When I replace the mapping "removeAnno" by a handler "hremoveAnno" with the same body it works fine also in 3.3.0 and 3.4.0.

My questions are:
- is this a desired behaviour which has been corrected from 3.2.2 to 3.3.0 or is it a bug?
- I found other cases where a similar problem occurs for nested mappings which add model objects. Again the problem disappears when using helpers instead. However, the QVT 1.1 specification says in 8.2.1.12: "However it is illegal to create or update object instances within a helper operation except for pre-defined types like sets, tuples, and for intermediate properties." I create EStringToStringMapEntry objects, so this should not work at all!?
- what are the exact differences between mappings and helpers and when should I use which one?
- In the specification I found the concept of intermediate data in QVTO, but that seems not to be supported in the implementation (at least not in 3.2.2). Are there other means to remove in a single transformation data which has been created in the same transformation?

Please help me to better understand the situation.

Gunnar
Re: Change in Helper/Mapping behaviour from QVTO 3.2.2 to 3.3.0 [message #1270705 is a reply to message #1270193] Thu, 13 March 2014 11:00 Go to previous messageGo to next message
Sergey Boyko is currently offline Sergey BoykoFriend
Messages: 162
Registered: July 2009
Senior Member
Gunnar Teege wrote on Wed, 12 March 2014 12:47
Hi,

I have been hit by a changed behaviour of mappings in chained in-place transformations from QVTO 3.2.2 to 3.3.0.

...

In QVTO 3.2.2 (Juno) this also works fine, the result is an EAnnotation with the single detail with value "test2". In QVTO 3.3.0 (in Kepler) and 3.4.0 (in Luna) the same transformation results in an EAnnotation with two details with values "test1" and "test2". It seems that the "test1" detail which has been added by the first transformation could not be removed by the second transformation.

When I replace the mapping "removeAnno" by a handler "hremoveAnno" with the same body it works fine also in 3.3.0 and 3.4.0.

My questions are:
- is this a desired behaviour which has been corrected from 3.2.2 to 3.3.0 or is it a bug?
- I found other cases where a similar problem occurs for nested mappings which add model objects. Again the problem disappears when using helpers instead. However, the QVT 1.1 specification says in 8.2.1.12: "However it is illegal to create or update object instances within a helper operation except for pre-defined types like sets, tuples, and for intermediate properties." I create EStringToStringMapEntry objects, so this should not work at all!?
- what are the exact differences between mappings and helpers and when should I use which one?
- In the specification I found the concept of intermediate data in QVTO, but that seems not to be supported in the implementation (at least not in 3.2.2). Are there other means to remove in a single transformation data which has been created in the same transformation?



Hi Gunnar,

The reason of the changing of behavior is that in QVTo 3.2.2 each of the transformation being instantiated uses individual trace pool. This was corrected for QVTo 3.3.0 with https://bugs.eclipse.org/bugs/show_bug.cgi?id=392153.

So the answer to the first question is 'yes'. It's desired behavior.

About mappings and helpers.

Execution semantics of mappings is described in QVTO specification (http://www.omg.org/spec/QVT/1.1/PDF/) section "8.2.1.15 MappingOperation" part "Execution Semantics". In short during invocation of mapping operation the trace pool is checked and mapping is not executed in case it's invoked on the same object with the same parameters. So in your case the invocation of 'removeAnno()' mapping which is initiated in Test2Trans was skipped.

Helpers are different in that they don't use traces. Also QVTo relaxes restriction on helpers so it's possible to create and update any objects by means of them.

I suggest either to redesign scripts or to replace mappings in LibAnno with helpers like follows:
helper ENamedElement :: setAnno(aname: String, k : String, v: String) {
	self.removeAnno(aname, k);
	self.eAnnotations->select(source = aname)->first().details += object EStringToStringMapEntry { key := k; value := v; };
	return
}

helper ENamedElement :: removeAnno(aname: String, k : String) {
	self.eAnnotations->select(source = aname)->forEach(a) {
		a.details := a.details->select(key != k);
	}
}


Btw, I didn't quite understand logic in 'removeAnno()'. To me it should looks like:
helper ENamedElement :: removeAnno(aname: String, k : String) {
	self.eAnnotations->select(source = aname)->forEach(a) {
		a.details := Set{}
	}
}



Regards,
Sergey.
Re: Change in Helper/Mapping behaviour from QVTO 3.2.2 to 3.3.0 [message #1270809 is a reply to message #1270705] Thu, 13 March 2014 14:29 Go to previous messageGo to next message
Gunnar Teege is currently offline Gunnar TeegeFriend
Messages: 3
Registered: March 2014
Junior Member
Sergey Boyko wrote on Thu, 13 March 2014 07:00


About mappings and helpers.

Execution semantics of mappings is described in QVTO specification in section "8.2.1.15 MappingOperation" part "Execution Semantics". In short during invocation of mapping operation the trace pool is checked and mapping is not executed in case it's invoked on the same object with the same parameters. So in your case the invocation of 'removeAnno()' mapping which is initiated in Test2Trans was skipped.


Thanks for this helpful explanation. I already met this semantics in other cases but I did not realize that it also applies here.

Is this the only reason which can cause object removals to be ignored? What happens if a created object in a mapping which has been added to the trace is removed afterwards? Is that possible? What is the correct way to remove objects? I found the unlink expression in the QVT 1.1 spec in section 8.2.2.12 but it seems not to be implemented in QVTo (?)

Quote:

Helpers are different in that they don't use traces. Also QVTo relaxes restriction on helpers so it's possible to create and update any objects by means of them.


Ok. If this is a stable decision for the future development of QVTo then I will replace all corresponding mappings by helpers. I assume that will also improve efficiency since no trace needs to be built.

Is there a description of QVTo where such differences to the QVT spec are documented? Could I have found it before asking here in the forum? Smile

Quote:

Btw, I didn't quite understand logic in 'removeAnno()'. To me it should looks like:
helper ENamedElement :: removeAnno(aname: String, k : String) {
	self.eAnnotations->select(source = aname)->forEach(a) {
		a.details := Set{}
	}
}



The name removeAnno was misleading here. The intention is to remove only those details which have key k and retain the details with other keys.

Thanks again

Gunnar
Re: Change in Helper/Mapping behaviour from QVTO 3.2.2 to 3.3.0 [message #1273546 is a reply to message #1270809] Thu, 20 March 2014 06:48 Go to previous messageGo to next message
Sergey Boyko is currently offline Sergey BoykoFriend
Messages: 162
Registered: July 2009
Senior Member
[quote title=Gunnar Teege wrote on Thu, 13 March 2014 10:29]Sergey Boyko wrote on Thu, 13 March 2014 07:00


Is this the only reason which can cause object removals to be ignored? What happens if a created object in a mapping which has been added to the trace is removed afterwards? Is that possible? What is the correct way to remove objects? I found the unlink expression in the QVT 1.1 spec in section 8.2.2.12 but it seems not to be implemented in QVTo (?)


Trace pool operates only in replenishment mode. You can't undo the mapping thus there's no way to remove given trace record.

QVTo provides a notion of model extent. Without going into details the model extent can be thought as EMF Resource associated with each of model parameter (which are transformation parameters).
Removing of element means moving it out of model extent. This is done with 'Model::removeElement(Element)' call. Removing of object does not lead to destroying it (object itself still exists and valid). Thus trace record is still valid even for removed objects.

Unlink expression is used to remove a value from a multivalued property. It can be a collection of datatypes like p1:String[*] or collection of object instances like p2:Class[*].
You're right that this is not implemented. However it's easily realized by assigning the feature new collection which is obtained from an original one by filtering unneeded elements.

Regards,
Sergey.

Re: Change in Helper/Mapping behaviour from QVTO 3.2.2 to 3.3.0 [message #1277089 is a reply to message #1273546] Tue, 25 March 2014 13:36 Go to previous message
Gunnar Teege is currently offline Gunnar TeegeFriend
Messages: 3
Registered: March 2014
Junior Member
Sergey Boyko wrote on Thu, 20 March 2014 02:48

QVTo provides a notion of model extent. Without going into details the model extent can be thought as EMF Resource associated with each of model parameter (which are transformation parameters).
Removing of element means moving it out of model extent. This is done with 'Model::removeElement(Element)' call. Removing of object does not lead to destroying it (object itself still exists and valid). Thus trace record is still valid even for removed objects.


Thanks for this explanation, that exactly answers my question. I was not aware of Model::removeElement in this context.

Quote:

Unlink expression is used to remove a value from a multivalued property. It can be a collection of datatypes like p1:String[*] or collection of object instances like p2:Class[*].
You're right that this is not implemented. However it's easily realized by assigning the feature new collection which is obtained from an original one by filtering unneeded elements.


Yes, that is how I did it when I found that unlink is not working.

However, for me one question remains. If I filter unneeded elements from a collection they behave differently whether they have been loaded from file with the original model or have been added by an in-place transformation. In the latter case they end up at the topmost level in the model when it is saved to file. In the former case they simply disappear. According to your explanation they should remain part of the model extent in both cases since they are not removed by Model::removeElement.
(If necessary I can provide an example, currently I am a bit in a hurry, sorry.)

Regards
Gunnar
Previous Topic:Pass a type as an argument
Next Topic:I want to give you a QVTo test coverage plugin
Goto Forum:
  


Current Time: Wed Nov 26 00:52:29 GMT 2014

Powered by FUDForum. Page generated in 0.02450 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software