ATL : Reference to a target class using a different rule [message #722943] |
Wed, 07 September 2011 09:23 |
fafanellu Messages: 37 Registered: July 2011 |
Member |
|
|
Hello,
I've got a problem with ATL while trying to re-use created classes.
For instance (MMA is the source metamodel, MMB is the target metamodel):
I have one source class, and two target classes. I want to put a reference to the second target class in the first one.
rule R1 {
from
cA : MMA!ClassA
to
c1 : MMB!Class1 (
attribute_c1<- c2
....
),
c2 : MMB!Class2 ()
}
Here, it is possible to use the created target Class2 reference in the Class1 : attribute_c1 will receive the reference to Class 2.
What if I wanted to do so, using two distinct rules ? Let's imagine, I have two sources classes ClassA and ClassB. Rule R2 is used to instanciate Class2, and rule R1 is used to give to the attribute_c1 a reference to the Class2 instanciated in the R2 rule. How can I express that ?
rule R1 {
from
cA : MMA!ClassA
to
c1 : MMB!Class1 (
attribute_c1<- ? (link to Class2 here)
....
)
}
rule R2 {
from
cB : MMA!ClassB
to
c2 : MMB!Class2 ()
}
This time, "c2" will not recognized because it doesn't belong to the same rule. What must I write instead of "?" lol
First solution works, but if there exist n instances of classA in the model, Class2 will be instanciated n times too, while in the second solution, if there is only one instance of ClassB, Class2 will be instanciated only once, then reused with all the attribute_c1 of the instances of ClassA...
Thank you for your help
[Updated on: Wed, 07 September 2011 09:35] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
Re: ATL : Reference to a target class using a different rule [message #723111 is a reply to message #723102] |
Wed, 07 September 2011 16:39 |
fafanellu Messages: 37 Registered: July 2011 |
Member |
|
|
In my example, for instance, the parameter was a string. The value could be a litteral string expression like 'test'. Or a string which could come from the source model. It's possible to create a target class "from nothing", using a called rule, a lazu rule or even a match rule. I tried to make a full example, the lazy rule I wrote above doesn't work any more, but I'll try to post it with all the files I'm using, it will be easier =)
[Updated on: Wed, 07 September 2011 16:40] Report message to a moderator
|
|
|
Re: ATL : Reference to a target class using a different rule [message #723112 is a reply to message #723072] |
Wed, 07 September 2011 16:41 |
fafanellu Messages: 37 Registered: July 2011 |
Member |
|
|
I'll try to illustrate my problem providing the files I'm using :
I've two .ecore files, meta1.ecore and meta2.ecore. All the attributes with a A refer to meta1, while those with B refer to meta2.
Here, ModelA can be seen as a container which contains several ClassA.
module _'meta1.ecore'
package Meta1 : Meta1 = 'Meta1'
{
class ModelA
{
property contains : ClassA[*] { ordered composes };
attribute modelA_name : String[1] { ordered };
}
class ClassA
{
attribute nameA : String[?] { ordered };
}
}
The following metamodel is more or less the same as the first one, I've just added to it the ability to handle Types (and I have an abstract Type class, which children are T1 and T2).
module _'meta2.ecore'
package Meta2 : Meta2 = 'Meta2'
{
abstract class AbstractClass
{
property uses_type : Type[1] { ordered };
}
class ClassB extends AbstractClass
{
attribute nameB : String[?] { ordered };
}
class ModelB
{
property handles_types : Type[+] { ordered };
property contains : ClassB[+] { ordered };
attribute modelB_name : String[1] { ordered };
}
abstract class Type;
class TypeOne extends Type;
class TypeTwo extends Type;
}
I'm working with this model : ModelA.xmi
<?xml version="1.0" encoding="ASCII"?>
<Meta1:ModelA xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Meta1="Meta1" xsi:schemaLocation="Meta1 meta1.ecore" modelA_name="this_is_a_model">
<contains nameA="toto"/>
<contains nameA="tata"/>
<contains nameA="titi"/>
</Meta1:ModelA>
My purpose is to create one instance of ModelB, which contains as many classes as there are in the ModelA.xmi (here, 3 instances of ClassA). Each one of those classes must have a name (the same as the source classes) and a type, T1 or T2. Both of those types must instanciated juste once. A suitable target model would look like this :
<?xml version="1.0" encoding="ASCII"?>
<Meta2:ModelB xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Meta2="Meta2" xsi:schemaLocation="Meta2 meta2.ecore" modelB_name="this_is_a_model">
<handles_types xsi:type="Meta2:TypeOne"/>
<handles_types xsi:type="Meta2:TypeTwo"/>
<contains uses_type="//@handles_types.0" nameB="toto"/>
<contains uses_type="//@handles_types.0" nameB="tata"/>
<contains uses_type="//@handles_types.1" nameB="titi"/>
</Meta2:ModelB>
In the following post, I'll show where my problems are.
|
|
|
|
|
Re: ATL : Reference to a target class using a different rule [message #723129 is a reply to message #723112] |
Wed, 07 September 2011 17:50 |
fafanellu Messages: 37 Registered: July 2011 |
Member |
|
|
-- @path Meta1=/ATL_Test/Meta1.ecore
-- @path Meta2=/ATL_Test/Meta2.ecore
module testATL;
create OUT: meta2 from IN: meta1;
rule M1toM2 {
from
mA:meta1!ModelA
to
mB:meta2!ModelB(
modelB_name<-mA.modelA_name
)
typesB1:meta2!TypeOne,
typesB2:meta2!TypeTwo
}
rule Class2Class {
from
mcA:meta1!ClassA
to
mcB:meta2!ClassB(
nameB<-mcA.nameA
)
}
gives
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:Meta2="Meta2">
<Meta2:ModelB modelB_name="this_is_a_model"/>
<Meta2:TypeOne/>
<Meta2:TypeTwo/>
<Meta2:ClassB nameB="toto"/>
<Meta2:ClassB nameB="tata"/>
<Meta2:ClassB nameB="titi"/>
</xmi:XMI>
which is far away from what we want. Now, when trying this :
rule M1toM2 {
from
mA:meta1!ModelA
to
mB:meta2!ModelB(
modelB_name<-mA.modelA_name,
handles_types<-typesB1,
handles_types<-typesB2,
contains<-thisModule.ClassA2ClassB(meta1!ModelA)
),
typesB1:meta2!TypeOne,
typesB2:meta2!TypeTwo
}
lazy rule ClassA2ClassB {
from
mcA:meta1!ClassA
to
mcB:meta2!ClassB(
nameB<-'test')
}
I get :
<?xml version="1.0" encoding="ISO-8859-1"?>
<Meta2:ModelB xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:Meta2="Meta2" modelB_name="this_is_a_model">
<handles_types xsi:type="Meta2:TypeOne"/>
<handles_types xsi:type="Meta2:TypeTwo"/>
<contains nameB="test"/>
</Meta2:ModelB>
Here, the problems are :
1) My source is ModelA, modelA is unique, so it creates only one matching target classB...but I want to have as many classB as classA
2)If I only write in the lazy rule mcB:meta2!ClassB(), "contains" relation exists, but has no reference to any class.
3)If I don't use a litteral final value for the class B name but a reference to an attribute, i.e. I use : nameB<-mcA.nameA, I get this error :
org.eclipse.m2m.atl.engine.vm.VMException: Feature nameA does not exist on MOF!EClass
at A.ClassA2ClassB(1 : Mmeta1!ClassA;) : ??#26(testATL.atl[26:11-26:20])
local variables = {mcB=OUT!<unnamed>, mcA=meta1!ModelA, self=testATL : ASMModule}
local stack = [OUT!<unnamed>, OUT!<unnamed>, testATL : ASMModule]
[Updated on: Wed, 07 September 2011 21:50] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.06427 seconds