Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » M2M (model-to-model transformation) » [QVTo] Recursive extension of targetelement's parent element(How to recursively extend a relation of the target element's parent)
[QVTo] Recursive extension of targetelement's parent element [message #521730] Thu, 18 March 2010 15:39 Go to next message
C. Kopf is currently offline C. KopfFriend
Messages: 37
Registered: November 2009
Member
Hello again everybody,

I got a new issue Embarrassed .

I would like to do a recursive flattening of an object-hierarchy.

In the input model the following structure may exist:
Each model has exactly one element of type Main.
An element of type Main may have several Packages, realized with the relation topLevelPackages.
Each Package may have several Packages recursively using the relation subPackages.

The target model has the following structure:
Each model has one (or more - this is not important) elements of type Specification.
Each Specification may have several Modules realized with the relation modules.
A Module may not have other "Submodules".

In my tranformation I would like to flatten the hierarchy as follows:


  • An element of type Main will be mapped to an element of type Specification.
  • topLevelPackages will be mapped to modules, this means: package will be mapped to Module
  • all subPackages of each Package will be mapped (added) to the overlaying Specification's modules; recursively


so I wrote the following in my QVTo-project:

mapping ARSEP::Main::main2specification() : Specification {
	modules := self.topLevelPackages.map package2module(result)->asOrderedSet();
}

mapping ARSEP::Package::package2module(inout parentSpec:Specification) : Module {
	name := self.name;
             self.elements->forEach(elem) {
             -- here a simple if-cascade is used to map some other relations and elements
             };
             parentSpec.modules += self.subPackages.map package2module(parentSpec)->asOrderedSet();
}



But this does result in some strange stuff:

I get the following structure in my target model:

---Specification
------Module1
---Module2
---Module3
---Module4
---...

as we can see the Module1 was placed at modules of Specification. The other Modules were placed as siblings of Specification instead of children.

the input model has the following structure:

---Main
------Package1
---------Package2
---------Package3
---------Package4
---------...

Package1 is the only topLevelPackage. Package1 has all the other packages as subPackages.

(the numbers show the mappings, e.g. Package1->Module1 etc.)



When I implement it the following way it works perfect:

mapping ARSEP::Main::main2specification() : Specification {
	modules := self.topLevelPackages.map package2module(result)->asOrderedSet();
             modules += self.topLevelPackages.subPackages.map package2module(result)->asOrderedSet();
             // this is just for testing issues, so no recursive stuff here
}

mapping ARSEP::Package::package2module(inout parentSpec:Specification) : Module {
	name := self.name;
             self.elements->forEach(elem) {
             -- here a simple if-cascade is used to map some other relations and elements
             };
}


Arrow
So far I expect something in the statement
parentSpec.modules += self.subPackages.map package2module(parentSpec)->asOrderedSet();

does not work as expected. The assignment to parentSpec.modules does not come off.

in the qvtotrace-file I can see that, also for the first code-example seen above, parentSpec is always (in all occurances) pointing towards the correct element.
Re: [QVTo] Recursive extension of targetelement's parent element [message #521819 is a reply to message #521730] Thu, 18 March 2010 19:32 Go to previous messageGo to next message
PBarendrecht is currently offline PBarendrechtFriend
Messages: 36
Registered: November 2009
Location: Eindhoven, Netherlands
Member
Hmm are you allowed to post pictures of the meta-model?

Some time ago I noticed weird behaviour of returning sets of elements, see this topic: http://www.eclipse.org/forums/index.php?t=msg&goto=51746 0&#msg_517460
The main problem is, that returning sets are returned as siblings instead of children.

If I understand your case correctly, all Packages and their Sub-Packages should be mapped to Modules, these modules all on the same level.
There is a nice function to accomplish this:

self.allSubobjectsOfType(Package) returns a set of all Packages, it works recursively. Maybe you could use this function?

[Edit]
I understand your first piece of code, however I'm not sure whether it is possible to return other objects in a mapping than the result-objects. Maybe you could add the "modules"-object as result object? I don't have any experience with this.

It is always useful to add some log()-functions to your mappings, to check whether things are still working OK. By assigning an unique name to your module, you can check whether it is still the right module you add the packages to.

Your second piece only works for a input model with just two levels of Packages, but you indicated that yourself already.

[Updated on: Thu, 18 March 2010 19:46]

Report message to a moderator

Re: [QVTo] Recursive extension of targetelement's parent element [message #524251 is a reply to message #521730] Wed, 31 March 2010 10:36 Go to previous messageGo to next message
C. Kopf is currently offline C. KopfFriend
Messages: 37
Registered: November 2009
Member
Hi P.,

Quote:
Hmm are you allowed to post pictures of the meta-model?

I will try to find out and create some nice ones.

Quote:
Some time ago I noticed weird behaviour of returning sets of elements, see this topic: http://www.eclipse.org/forums/index.php?t=msg&goto=51746 0&#msg_517460
The main problem is, that returning sets are returned as siblings instead of children.


Looks somehow familiar, but I am not sure whether it is the same problem. Actually the solutions mentinoned there did not help me along. But yours might! Smile

Quote:
self.allSubobjectsOfType(Package) returns a set of all Packages, it works recursively. Maybe you could use this function?


I think it should be possible to write a work-around for my issue using
allSubobjectsOfType(Package)->oclAsType(Package).map ...
So you made my day again! Cool Pretty cool, thanks.



On the other hand this issue still exists for several use-cases. So I am still looking for a solution.


Quote:
I understand your first piece of code, however I'm not sure whether it is possible to return other objects in a mapping than the result-objects

What do you mean? I though it should be possible to add an object as inout parameter. I found no restriction concerning this in the QVT-Spec.
Quote:
Maybe you could add the "modules"-object as result object? I don't have any experience with this.

I do not know how? Do you mean as another inout-parameter? Well yes probably, but I expect the problem then being somehow the same. From my understanding it does not matter of wihich type the inout-parameter is. Or do you mean just as an out-parameter?
Well I shall try. I will post my findings asap.
icon3.gif  Re: [QVTo] Recursive extension of targetelement's parent element [message #524592 is a reply to message #524251] Thu, 01 April 2010 14:32 Go to previous message
C. Kopf is currently offline C. KopfFriend
Messages: 37
Registered: November 2009
Member
Quote:
I think it should be possible to write a work-around for my issue using
Quote:
allSubobjectsOfType(Package)->oclAsType(Package).map ...

So you made my day again! Pretty cool, thanks.



Well, as far as I can see my workaround works fine, so I though I should at least share it with you. I will post some more semantics than before, maybe it makes it easier to understand what I wanted to do. I took out the log-statements, but be sure: I used them a lot Very Happy . So her it is:

mapping ARSEPGenIA::ARSEP::arsep2specification() : Specification {
	result.modules := self.allSubobjectsOfType(Package)->oclAsType(Package)->select(p|not p.emptyPackage()).map package2module()->asOrderedSet();
}


where emptyPackage is a simple helper (i know I should have used reject instead of the select, but anyway it does the same Wink ):

helper ARPackage::emptyPackage() : Boolean {
	if ( self.subobjects() -> select(e|not (e.oclIsTypeOf(ARPackage))) -> isEmpty() ) then {
		return true;
	}
	endif;
	return false;
}


for completion here is the mapping for the Packages (here also some refactoring shall be done [e.g. if-cascade -> generalized mapping] Smile ) :

mapping ARSEPGenIA::Package::package2module() : Module {
	name := createPackageName(self);
	self.elements->forEach(elem) {
		if (elem.oclIsKindOf(Interface)) then {
		... -- not of interest ;)
                           }
		endif;
	};
}


well ok, and createPackageName is a query for generating a name of the modules where all the 'parent packages' names are aggregated. It looks like this (pPackage points to the overlaying Package):

query createPackageName(in pack:Package) : String {
	var name:String := pack.shortName;
	var curPack:Package := pack;
	while ((curPack.pPackage <> null)and(curPack.pPackage <> curPack)) {
		curPack := curPack.pPackage;
		name := curPack.shortName+"."+name;
	};
	return name;
}


So thanks again P!

Anyway the issue mentioned, as already said, still exists, so probably, someone familiar with the QVTo implementation in Eclipse might know some solution or look for one. Smile
Previous Topic:[ATL] Deadline Extension: 2nd International Workshop on Model Transformation with ATL (MtATL 2010)
Next Topic:[QVTo] Transformation from one to N models
Goto Forum:
  


Current Time: Fri Apr 19 22:15:35 GMT 2024

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

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

Back to the top