Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
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 Go to next message
Damian Hofmann is currently offline Damian HofmannFriend
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 #430237 is a reply to message #430235] Thu, 14 May 2009 08:18 Go to previous messageGo to next message
Felix Dorner is currently offline Felix DornerFriend
Messages: 676
Registered: July 2009
Senior Member
Hi Damian,

> 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...

You could also do eObject.getResource().getContents().get(0), if you
know that your resources have a single root element.

But the best way is to use EcoreUtil.getRootContainer(eObject).
EcoreUtil seems to always have something in petto for such computations.

Felix
Re: Best way to get root object of a model [message #430238 is a reply to message #430237] Thu, 14 May 2009 08:33 Go to previous messageGo to next message
Damian Hofmann is currently offline Damian HofmannFriend
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 Go to previous messageGo to next message
Eclipse UserFriend
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 Go to previous messageGo to next message
Damian Hofmann is currently offline Damian HofmannFriend
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 Go to previous messageGo to next message
Eclipse UserFriend
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 #430250 is a reply to message #430235] Thu, 14 May 2009 09:49 Go to previous messageGo to next message
Damian Hofmann is currently offline Damian HofmannFriend
Messages: 16
Registered: July 2009
Junior Member
Hi Tim,
hi Felix,

Thank you both for your help. As you recommended I'm using now
containments for my references. This works mostly fine. But I
understand, that an object can only have one container.

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
Re: Best way to get root object of a model [message #430259 is a reply to message #430250] Thu, 14 May 2009 11:00 Go to previous messageGo to next message
Eclipse UserFriend
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 Go to previous messageGo to next message
Eclipse UserFriend
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
Re: Best way to get root object of a model [message #430312 is a reply to message #430259] Thu, 14 May 2009 12:14 Go to previous message
Damian Hofmann is currently offline Damian HofmannFriend
Messages: 16
Registered: July 2009
Junior Member
Thank you again,
you gave me some real useful hints.


> 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.

That was, what I had in mind. But I found an other solution that works
for me.

The model is a of complex timeline with periods. The begin of a period
can be set in different ways like per date or in years after a given
date or the age of a given person. The model root contains the list of
periods, each with it's own begin (a period goes until the begin of the
next period). Usualy the first period's begin defines, where the whole
calculation begins. But the problem domain requires, in some special
cases, that the user can set a global begin to a later date than the
begin of the first period. I thought it would be a good idea to use the
same begin-objet if global begin and the begin of the first period are
the same.

Now I just set the begin of the first period to null. If The begin of
the first period is requested and the periods begin is null, I access
and return the global begin instead.


Damian
Previous Topic:Steful packages
Next Topic:URIConverter and href?
Goto Forum:
  


Current Time: Fri Apr 26 18:24:00 GMT 2024

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

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

Back to the top