Home » Modeling » ATL » [ATL] Containment references cannot span across models(They can - ATL collections cause the problem)
[ATL] Containment references cannot span across models [message #1009619] |
Fri, 15 February 2013 11:48 |
Gunnar Arndt Messages: 82 Registered: June 2012 |
Member |
|
|
Hi members,
I have to fight with output elements written to the wrong file in a transformation with several (hierarchic) output metamodels, i.e. there are output metamodels otx.ecore and quantity.ecore, which is a sub-model of otx.ecore.
All output should be written to output.otx, the output file of the main model (otx.ecore); but sometimes, output from the sub-model (quantity.ecore) is written to its output file output.quantity instead.
As I have recently figured out, the problem seems to be caused by the ATL 'collect', which creates its own intermediate collection:
lazy rule SubtractAtom2Term {
from
source: transformate!SubtractAtom
to
otxTerm: otx!Subtract(
-- This works as desired, i.e. the quantity goes to output.otx:
numeral <- source.numeral->createQuantity(),
-- This does not work, i.e. the quantities go to output.quantity:
subtrahend <- source.subtrahends->collect(s | s->createQuantity())
-- Error message: Containment references cannot span across models.
)
}
As posted here before, cross-model references are activated.
Any suggetions? Maybe how to work around using the 'collect'?
Thank you for any input.
|
|
| | | |
Re: [ATL] Containment references cannot span across models [message #1009807 is a reply to message #1009752] |
Fri, 15 February 2013 19:04 |
|
Op 15-02-13 17:29, Hugo Bruneliere schreef:
> I don't know if your error could come from this but helpers are not not
> intended to create elements in the target model(s).
> They are supposed to only navigate input model(s) and return input model
> element(s) (or values of a primitive type), the creation of elements being let
> to matched rules (directly or indirectly by a call to a lazy rule in one of
> their assignments).
No, this works.
The trick might be in the output metamodel identifier you use: quantity
instead of otx. ATL uses the metamodel identifier to determine into which
output model the element should be generated. You lazy rule says
"quantity!Quantity".
Of course, when you then assign an element inside your quantity output model
to a *containment* reference of an element inside your otx metamodel, the
assigned element is *moved* to the otx output model.
Instead of using "quantity!Quantity", you can also use "otx!Quantity". As otx
includes quantity, this should work.
Can you give us your "create..." statement? That will clear up a lot.
Dennis
Cheers,
Dennis
|
|
|
Re: [ATL] Containment references cannot span across models [message #1010814 is a reply to message #1009619] |
Mon, 18 February 2013 09:34 |
Gunnar Arndt Messages: 82 Registered: June 2012 |
Member |
|
|
Hugo and Dennis, thank you for your help. Seems we're going into detail on this...
@Dennis:
- You can find the 'create' helper on top of my second post - it is the helper which calls the lazy rule. Please note that there are many such helpers (in different contexts, but of the same name) in my transformation, which call different lazy rules.
- I do not know how to use the main model identifier (otx) in order to create sub-model (quantity) elements; Hugo and I have discussed that approach in another thread before, with no success on my side.
The name spaces in the XML schemata (otx.xsd imports quantity.xsd) and the Ecore model generated from them are org.iso.otx and org.iso.otx.quantity, but stuff like otx!"org::iso::otx::quantity::Quantity" leads to an error in ATL.
Maybe I should make even clearer why I think that the collection created by ATL is the problem: Both output bindings (numeral and subtrahend) in the given lazy rule call the helper createQuantity, which in both cases returns a sub-model (quantity) element.
If the helper is called directly (numeral), the sub-model element is inserted correctly into the main model output file - there is no containment reference, as it is directly contained. But if the helper is called by an iterator (collect), the sub-model output elements (Quantities) are written to the quantity output file, which would require a cross-file reference.
I'm wondering why that happens when using collect only.
[Updated on: Mon, 18 February 2013 10:37] Report message to a moderator
|
|
|
Re: [ATL] Containment references cannot span across models [message #1035938 is a reply to message #1010814] |
Sun, 07 April 2013 18:00 |
|
Op 18-02-13 10:35, Gunnar Arndt schreef:
> Hugo and Dennis, thank you for your help. Seems we're going into detail on
> this...
>
> @Dennis:
>
> You can find the 'create' helper on top of my second post - it is the helper
> which calls the lazy rule. Please note that there are many such helpers (in
> different contexts, but of the same name) in my transformation, which call
> different lazy rules.
> I do not know how to use the main model identifier (otx) in order to create
> sub-model (quantity) elements; Hugo and I have discussed that approach in
> another thread before, with no success on my side.
> The name spaces in the XML schemata (otx.xsd imports quantity.xsd) and the
> Ecore model generated from them are org.iso.otx and org.iso.otx.quantity, but
> stuff like "org::iso::otx::Quantity" leads to an error in ATL.
Hmm, ATL normally detects the imports closure of Ecore metamodels by following
the outward references/inheritance relationships of each EClass it traverses.
Unless no otx metaclass has an explicit reference to a quantity metaclass,
this approach should be able to find quantity EClasses as part of the otx
metamodel, e.g. OTX!Quantity or OTX!"org::iso::otx::Quantity".
>
> Maybe I should make even clearer why I think that the collection created by
> ATL is the problem: Both output bindings (numeral and subtrahend) in the given
> lazy rule call the helper createQuantity, which in both cases returns a
> sub-model (quantity) element.
> If the helper is called directly (numeral), the sub-model element is inserted
> correctly into the main model output file - there is no containment reference,
> as it is directly contained. But if the helper is called by an iterator
> (collect), the sub-model output elements (Quantities) are written to the
> quantity output file, which would require a cross-file reference.
>
> I'm wondering why that happens when using collect only.
In the first case you're assigning to "numeral" and in the second case you're
assigning to "subtrahend". Those are different properties. Please verify
against both.
Dennis
Cheers,
Dennis
|
|
|
Re: [ATL] Containment references cannot span across models [message #1036295 is a reply to message #1009619] |
Mon, 08 April 2013 07:41 |
Gunnar Arndt Messages: 82 Registered: June 2012 |
Member |
|
|
Dennis, thank you for the idea, but I cannot do that: the property 'numeral' is a NumericTerm[1..*], i.e. an EList<NumericTerm>, whereas 'subtrahend' is just a NumericTerm[0..1]. The value assigned to subtrahend goes to the correct output document (otx), but those assigned through an OCL collection go to the sub-model output document (quantity).
I've recently taken notice of the possibility to explicitely state the target output model in a rule using the keyword 'in', like so:
-- org.iso.otx.quantities is a sub-model of org.iso.otx
create OUT: otx, quant: quantities from IN: transformate;
-- ...
lazy rule QuantityVariable2Quantity {
from
source: transformate!QuantityVariable
to
output: quantity!Quantity in OUT(
-- ...
)
}
I'm going to test that as soon as possible.
[Updated on: Mon, 08 April 2013 08:17] Report message to a moderator
|
|
| | |
Goto Forum:
Current Time: Thu Apr 25 17:29:07 GMT 2024
Powered by FUDForum. Page generated in 0.03851 seconds
|