Home » Archived » M2M (model-to-model transformation) » References in iterative target model elements
References in iterative target model elements [message #39357] |
Sun, 20 May 2007 08:42  |
Eclipse User |
|
|
|
Originally posted by: priit.best.ee
Hi!
My model transformation uses iterative target pattern elements. The problem is, I am not
able to also create referenced elements iteratively and keep the references intact.
To illustrate this, I extended the example mentioned in section 4.5.2.4 of the ATL User
Manual.
I have a model of Journals, that contain 0..* Articles. I want to transform this model
into Books, that contain 0..* Chapters. In the target model I want to have 2 Books for
every Journal, that both contain the respective Chapters.
My ATL transformation looks like this:
----------------------------------------------
module TestIterativeTarget; -- Module Template
create OUT : Book from IN : Journal;
rule Journal2Book {
from
j: Journal!Journal
using {
editions:Sequence(String) = Sequence {'library', 'bookshop'};
}
to
b: distinct Book!Book foreach (e in editions) (
title <- j.title,
edition <- e,
chapter <- j.article
)
}
rule Article2Chapter {
from
a: Journal!Article
to
c: Book!Chapter (
name <- a.name
)
}
----------------------------------------------
Here is my test model:
----------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Journal">
<Journal title="Journal 1">
<article name="a_2_1"/>
<article name="a_2_2"/>
<article name="a_2_3"/>
</Journal>
</xmi:XMI>
----------------------------------------------
I'd like to transform it into something like this:
----------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Book">
<Book title="Journal 1" edition="library">
<chapter name="a_2_1"/>
<chapter name="a_2_2"/>
<chapter name="a_2_3"/>
</Book>
<Book title="Journal 1" edition="bookshop">
<chapter name="a_2_1"/>
<chapter name="a_2_2"/>
<chapter name="a_2_3"/>
</Book>
</xmi:XMI>
----------------------------------------------
But instead, I only get this:
----------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Book">
<Book title="Journal 1" edition="library">
<chapter name="a_2_1"/>
</Book>
<Book title="Journal 1" edition="bookshop">
<chapter name="a_2_2"/>
</Book>
<Chapter name="a_2_3"/>
</xmi:XMI>
----------------------------------------------
I have tried creating the Chapters also in the iterative way, but so far have
not yet reached the goal.
Do you have any ideas what I should change?
Thanks in advance for your help,
Priit
|
|
| | | |
[ATL] Re: References in iterative target model elements [message #39765 is a reply to message #39422] |
Mon, 21 May 2007 14:33   |
Eclipse User |
|
|
|
Originally posted by: priit.best.ee
Hi Régis,
I'm sorry to say, but it still doesn't work as expected. The number of Chapters created was
correct, but only the first chapter was linked to the Book:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Book">
<Book title="Journal 1" edition="library">
<chapter name="a_1_1"/>
</Book>
<Book title="Journal 1" edition="bookshop">
<chapter name="a_1_2"/>
</Book>
<Chapter name="a_1_2"/>
<Chapter name="a_1_3"/>
<Chapter name="a_1_1"/>
<Chapter name="a_1_3"/>
</xmi:XMI>
What am I still doing wrong?
If you are interested, you can see all the relevant files here: http://priit.eu/ATL/
PS. I changed includes() for including() in the helper function, I guess it was a typo...
Priit
Régis wrote:
> Hi Priit,
>
> Your problem is completly normal with ATL: an element is matched only
> one time, so you obtain only tree chapters after transformation because
> you have only tree Article in input. The containment are unpredictable
> in relation with the execution order (which cannot be considered in
> declarative form).
>
> You need to use called rules or lazy rules to do what you want here
> (here, I use called rules with an iterate, but someone have perhaps an
> idea in order to stay in declarative form :) ):
>
> ------------------------------------------------------------ -
> rule Journal2Book {
> from
> j: Journal!Journal
> using {
> editions:Sequence(String) = Sequence {'library', 'bookshop'};
> }
> to
> b: distinct Book!Book foreach (e in editions) (
> title <- j.title,
> edition <- e,
> chapter <- thisModule.Article2ChapterIterator(j.article);
> )
> }
> ------------------------------------------------------------ -
> helper def: Article2ChapterIterator(articles :
> Sequence(Journal!Article)) : Sequence(Book!Chapter) =
> articles->iterate(anArticle ; chapters : Sequence(Book!Chapter) =
> Sequence{} |
> chapters->includes(thisModule.Article2Chapter(anArticle))
> )
> ;
> ------------------------------------------------------------ -
> rule Article2Chapter(article : Journal!Article) {
> to
> c: Book!Chapter (
> name <- article.name
> )
> do {
> c;
> }
> }
> ------------------------------------------------------------ -
>
> I have not tested the code but I think it will work :)
>
> Regards,
>
> *Régis CHEVREL* <mailto:rchevrel@sodius.com>
>
>
> SODIUS*
> *6, rue Cornouaille
> 44319 Nantes - France
>
> Phone: +33 (0)2 28 23 54 34
>
> ***www.mdworkbench.com* <http://www.mdworkbench.com/>* *
> Draw more value from your model
|
|
|
Re: [ATL] Re: References in iterative target model elements [message #39796 is a reply to message #39765] |
Mon, 21 May 2007 15:38  |
Eclipse User |
|
|
|
Hello,
> rule Journal2Book {
> from
> j: Journal!Journal
> using {
> editions:Sequence(String) = Sequence {'library', 'bookshop'};
> }
> to
> b: distinct Book!Book foreach (e in editions) (
> title <- j.title,
> edition <- e,
> chapter <- j.article
> )
> }
Because of the way iterative target pattern elements (i.e.,
"distinct"-"foreach") work, you have to write something like:
chapter <- editions->collect(e | j.article)
This is because when the value of the right-hand part is a collection,
each of its element is assigned to a separate target element. Therefore,
by building a collection of collection, we solve the problem.
This is also probably the reason why Régis' solution did not work as
expected.
Note that the outer collection should contain the same number of
elements as in the iterated collection (i.e., "editions" here).
The behavior of the iterative target pattern element is definitely not
very intuitive, which is why it has been deprecated in favor of lazy rules.
The most elegant declarative solution I can think of would require the
editions to come from a model (i.e., the IN source model, or another
model). Note that this somehow makes sense: you may want to extend your
transformation to support more kinds of editions later, and it is
simpler to change a source model than a hard-coded value in the
transformation.
Here is what it could look like:
-- @atlcompiler atl2006
module TestIterativeTarget;
create OUT : Book from IN : Journal, editions : Edition;
rule Journal2Book {
from
j : Journal!Journal,
e : Edition!Edition
to
b : Book!Book (
title <- j.title,
edition <- e.name,
chapter <- j.article->collect(e |
thisModule.Article2Chapter(e)
)
)
}
lazy rule Article2Chapter {
from
a: Journal!Article
to
c: Book!Chapter (
name <- a.name
)
}
Regards,
Frédéric Jouault
Priit wrote:
> Hi Régis,
>
> I'm sorry to say, but it still doesn't work as expected. The number of
> Chapters created was
> correct, but only the first chapter was linked to the Book:
>
> <?xml version="1.0" encoding="ISO-8859-1"?>
> <xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Book">
> <Book title="Journal 1" edition="library">
> <chapter name="a_1_1"/>
> </Book>
> <Book title="Journal 1" edition="bookshop">
> <chapter name="a_1_2"/>
> </Book>
> <Chapter name="a_1_2"/>
> <Chapter name="a_1_3"/>
> <Chapter name="a_1_1"/>
> <Chapter name="a_1_3"/>
> </xmi:XMI>
>
> What am I still doing wrong?
>
> If you are interested, you can see all the relevant files here:
> http://priit.eu/ATL/
>
> PS. I changed includes() for including() in the helper function, I guess
> it was a typo...
>
>
> Priit
>
>
>
> Régis wrote:
>> Hi Priit,
>>
>> Your problem is completly normal with ATL: an element is matched only
>> one time, so you obtain only tree chapters after transformation
>> because you have only tree Article in input. The containment are
>> unpredictable in relation with the execution order (which cannot be
>> considered in declarative form).
>>
>> You need to use called rules or lazy rules to do what you want here
>> (here, I use called rules with an iterate, but someone have perhaps an
>> idea in order to stay in declarative form :) ):
>>
>> ------------------------------------------------------------ -
>> rule Journal2Book {
>> from
>> j: Journal!Journal
>> using {
>> editions:Sequence(String) = Sequence {'library', 'bookshop'};
>> }
>> to
>> b: distinct Book!Book foreach (e in editions) (
>> title <- j.title,
>> edition <- e,
>> chapter <- thisModule.Article2ChapterIterator(j.article);
>> )
>> }
>> ------------------------------------------------------------ -
>> helper def: Article2ChapterIterator(articles :
>> Sequence(Journal!Article)) : Sequence(Book!Chapter) =
>> articles->iterate(anArticle ; chapters : Sequence(Book!Chapter) =
>> Sequence{} |
>> chapters->includes(thisModule.Article2Chapter(anArticle))
>> )
>> ;
>> ------------------------------------------------------------ -
>> rule Article2Chapter(article : Journal!Article) {
>> to
>> c: Book!Chapter (
>> name <- article.name
>> )
>> do {
>> c;
>> }
>> }
>> ------------------------------------------------------------ -
>>
>> I have not tested the code but I think it will work :)
>>
>> Regards,
>>
>> *Régis CHEVREL* <mailto:rchevrel@sodius.com>
>>
>>
>> SODIUS*
>> *6, rue Cornouaille
>> 44319 Nantes - France
>>
>> Phone: +33 (0)2 28 23 54 34
>>
>> ***www.mdworkbench.com* <http://www.mdworkbench.com/>* *
>> Draw more value from your model
|
|
|
Goto Forum:
Current Time: Mon May 12 00:27:58 EDT 2025
Powered by FUDForum. Page generated in 0.03315 seconds
|