Home » Modeling » EMF » Best way to get root object of a model
Best way to get root object of a model [message #430235] |
Thu, 14 May 2009 07:49 |
Damian Hofmann Messages: 16 Registered: July 2009 |
Junior Member |
|
|
Hi together,
What is the best way to get the root object of my ecore model from one
of it's children?
Example:
The model has three classes: A, B, C.
Class A has an attribute of type B and class B has an attribute of type
C. The root of my model is an instance of class A called modelA.
The whole model looks like this:
modelA (instance of A)
+ modelB (instance of B)
+ modelC (instance of C)
In modelC, I want to access some attributes of modelA because a method
(implementing a third party interface) of class C should return a value,
depending of those attributes. How do I get the reference to modelA.
I tried with this.eContainer() to get the at least the parent (and later
the parents parent, and so on) but it returns null. If there is a way,
that doesn't depend on the level inside the hierarchy, even better!
Oh, one more thing: the reference shouldn't be persisted but determined
dynamically, because it's only used for the calculation.
Thank you for your help
Damian
|
|
| |
Re: Best way to get root object of a model [message #430238 is a reply to message #430237] |
Thu, 14 May 2009 08:33 |
Damian Hofmann Messages: 16 Registered: July 2009 |
Junior Member |
|
|
Hi Felix,
>> I tried with this.eContainer() to get the at least the parent (and
>> later the parents parent, and so on) but it returns null. If there is
>> a way, that doesn't depend on the level inside the hierarchy, even
>> better!
>
> eContainer() returns null for the root object because the root object is
> contained in a Resource. That somehow answers the question: Recurse up
> until eContainer() returns null...
Sorry, I was not clear about where I use eContainer(). I don't call
eContainer in the root object. I use it in class C. It returns null,
even if the instance of C is an attribute of class B, that is also an
attribute of class A (root). The instance of C isn't defined as a
containment, because there can only be one instance of C for each
instance of B. The same applies for instances of B for instances of A
(root).
> But the best way is to use EcoreUtil.getRootContainer(eObject).
> EcoreUtil seems to always have something in petto for such computations.
Sounds interesting, but it just returns the instance of class C. I
think, because the instance of class C doesn't have a container . Do I
have to tell the model instance, which parent it is contained by? How to do?
Damian
|
|
|
Re: Best way to get root object of a model [message #430239 is a reply to message #430235] |
Thu, 14 May 2009 08:37 |
Eclipse User |
|
|
|
Originally posted by: Tim.Baumgartner.innovations.de
Hi Damian,
> The model has three classes: A, B, C.
> Class A has an attribute of type B and class B has an attribute of type
> C.
I assume you are not talking about attributes but about EReferences with
containment set to true.
> The root of my model is an instance of class A called modelA.
> The whole model looks like this:
> modelA (instance of A)
> + modelB (instance of B)
> + modelC (instance of C)
If it looks like this in the editor, then modelC.eContainer() == modelB
and modelB.eContainer() == modelA
> In modelC, I want to access some attributes of modelA because a method
> (implementing a third party interface) of class C should return a value,
> depending of those attributes. How do I get the reference to modelA.
1) use eContainer() twice
2) EcoreUtil.getRootContainer(EObject)
3) introduce opposite EReferences to generate code that makes it
possible to write
modelC.getB().getA().doSomething()
> I tried with this.eContainer() to get the at least the parent (and later
> the parents parent, and so on) but it returns null. If there is a way,
> that doesn't depend on the level inside the hierarchy, even better!
>
> Oh, one more thing: the reference shouldn't be persisted but determined
> dynamically, because it's only used for the calculation.
This requirement is met by all of the above solutions
>
> Thank you for your help
> Damian
Tim
|
|
|
Re: Best way to get root object of a model [message #430241 is a reply to message #430239] |
Thu, 14 May 2009 08:58 |
Damian Hofmann Messages: 16 Registered: July 2009 |
Junior Member |
|
|
Hi Tim,
>> The model has three classes: A, B, C.
>> Class A has an attribute of type B and class B has an attribute of
>> type C.
>
> I assume you are not talking about attributes but about EReferences with
> containment set to true.
>
Yes, they're EReferences. But containment isn't set, because it's a
one-to-one relation. Please correct me, if I'm doing it wrong.
>> The root of my model is an instance of class A called modelA.
>> The whole model looks like this:
>> modelA (instance of A)
>> + modelB (instance of B)
>> + modelC (instance of C)
>
> If it looks like this in the editor, then modelC.eContainer() == modelB
> and modelB.eContainer() == modelA
>
>> In modelC, I want to access some attributes of modelA because a method
>> (implementing a third party interface) of class C should return a
>> value, depending of those attributes. How do I get the reference to
>> modelA.
>
> 1) use eContainer() twice
> 2) EcoreUtil.getRootContainer(EObject)
> 3) introduce opposite EReferences to generate code that makes it
> possible to write
> modelC.getB().getA().doSomething()
I assume that all options depend on the containment set to true. Is
there a way to ensure the one-to-one relation. And does EMF then still
generate a getter- and setter-Method. This would be nice, because my
model classes implement some third party interfaces, that use the same
method signatures.
>> Oh, one more thing: the reference shouldn't be persisted but
>> determined dynamically, because it's only used for the calculation.
>
> This requirement is met by all of the above solutions
That's good to hear.
Thanks for your quick answer
Damian
|
|
|
Re: Best way to get root object of a model [message #430242 is a reply to message #430238] |
Thu, 14 May 2009 08:59 |
Eclipse User |
|
|
|
Originally posted by: Tim.Baumgartner.innovations.de
Hi Damian,
> Hi Felix,
>
>>> I tried with this.eContainer() to get the at least the parent (and
>>> later the parents parent, and so on) but it returns null. If there is
>>> a way, that doesn't depend on the level inside the hierarchy, even
>>> better!
>>
>> eContainer() returns null for the root object because the root object
>> is contained in a Resource. That somehow answers the question: Recurse
>> up until eContainer() returns null...
>
> Sorry, I was not clear about where I use eContainer(). I don't call
> eContainer in the root object. I use it in class C. It returns null,
> even if the instance of C is an attribute of class B, that is also an
> attribute of class A (root). The instance of C isn't defined as a
> containment, because there can only be one instance of C for each
> instance of B. The same applies for instances of B for instances of A
> (root).
You got something wrong there: Containment makes sense for single-valued
references as well.
eContainer() can only work if the EObject has been added to a
containment reference of some other EObject (this other object then of
course becomes it's container).
For containment references, there is always an implicit opposite
reference (accessable via eContainer()), for non-containment references,
you have to model the opposite in order to access it (or you can use
ECoreUtil.CrossReferencer or ECrossReferenceAdapter, but that's more
heavy weight)
>> But the best way is to use EcoreUtil.getRootContainer(eObject).
>> EcoreUtil seems to always have something in petto for such computations.
>
> Sounds interesting, but it just returns the instance of class C. I
> think, because the instance of class C doesn't have a container . Do I
> have to tell the model instance, which parent it is contained by? How to
> do?
>
>
> Damian
Tim
|
|
| |
Re: Best way to get root object of a model [message #430259 is a reply to message #430250] |
Thu, 14 May 2009 11:00 |
Eclipse User |
|
|
|
Originally posted by: Tim.Baumgartner.innovations.de
Hi Damian,
> But I understand, that an object can only have one container.
Yes, that's an important principle in Ecore. But you should know that
it's possible to generate or modify the editor in such a way that it
displays referenced (not contained) EObjects as children. You can do so
by changing the children property of the GenFeature in the Genmodel editor.
>
> Let's assume my modelA (root) also has a list of items (instances of
> class D). The first item of the list needs a reference to object modelB.
> The other items contain their own instances of class B. But modelB
> should be contained by both, the root object (modelA) and the first item
> of the list.
>
> modelA
> + modelB
> + modelC
> + List
> + item_one
> + ref_to_modelB
> + item_two
> + other_modelB
> + item_three
> + again_an_other_modelB
>
> The problem is, as soon as I set modelB for item_one it is removed from
> modelA. That makes sense, because modelB can only have one container.
> But how can I model the reference for item_one to work as intended?
>
> Damian
It seems to me that you want a reference that sometimes is containment
and sometimes not. You could introduce a containment reference to an
intermediate interface that has two implementations: one with a
containment and one with a non-containment reference to B.
But perhaps this is non-sense. I can't tell for sure because I don't
have enough information about the purpose of your model.
Tim
|
|
|
Re: Best way to get root object of a model [message #430260 is a reply to message #430241] |
Thu, 14 May 2009 11:09 |
Eclipse User |
|
|
|
Originally posted by: Tim.Baumgartner.innovations.de
Hi Damian,
> Yes, they're EReferences. But containment isn't set, because it's a
> one-to-one relation. Please correct me, if I'm doing it wrong.
Perhaps you have background in RDBMS where there is no such thing as a
container. Better think of XML files. Inside <stuff> </stuff> there can
be more nested stuff. So the outer stuff really contains the inner stuff.
>>> In modelC, I want to access some attributes of modelA because a
>>> method (implementing a third party interface) of class C should
>>> return a value, depending of those attributes. How do I get the
>>> reference to modelA.
>>
>> 1) use eContainer() twice
>> 2) EcoreUtil.getRootContainer(EObject)
>> 3) introduce opposite EReferences to generate code that makes it
>> possible to write
>> modelC.getB().getA().doSomething()
>
> I assume that all options depend on the containment set to true.
yes
> Is there a way to ensure the one-to-one relation. And does EMF then still
> generate a getter- and setter-Method. This would be nice, because my
> model classes implement some third party interfaces, that use the same
> method signatures.
You can introduce an EClass Root which contains both A and B. Then A and
B obviously play the same role. If you model back references from A to
Root and from B to Root (perhaps a single reference suffices), you can
access B from A and A from B.
Tim
|
|
| |
Goto Forum:
Current Time: Fri Apr 26 18:24:00 GMT 2024
Powered by FUDForum. Page generated in 0.03335 seconds
|