Reflective API (eSet) in multiple (parent/child) models [message #425870] |
Wed, 10 December 2008 14:59 |
Morten MacFly Messages: 69 Registered: July 2009 |
Member |
|
|
Dear NG,
I have asked this already but thought I found the solution. Hence I did
not. So I am asking again hereby:
I have a model structure that exist of several ECore models (one root,
several children). Now I am writing an import filter for an external
format that would create a model accordingly. I want to "eSet" all
sub-elements but I receive a "IllegalCastException" when I try to create
the cildren.
Assume this structure:
Resource
- Root (first EObject)
- A (child of Root, but own ecore model)
- B (child of Root, but own ecore model)
- B1 (child of B, inside "B" ecore model)
- B2 (child of B, inside "B" ecore model)
What I am doing is this:
- Creating the ResourceSet / Resource "Resource"
- Obtaining the root structural feature (RootSF)
- Obtaining the root ECLass (RootEC)
.....then:
- Root = RootFactory.create(RootEC)
- Root.eSet(RootSF, EcoreUtil.create((EClass)RootSF.getEType()));
- Resource.getContents().add(Root);
Up to here it's just "copied" from the default (generated) wizard. Now
comes my part accordingly:
- EReference B = RootPackage.eINSTANCE.getB();
- EObject B_O = EcoreUtil.create(B.getEReferenceType());
- Root.eSet(B, B_O);
- This works, I see the child "B" in the model instance if I stop here.
Now I want to add the B1/B2, too the same way:
- EReference B1 = BPackage.eINSTANCE.getB1();
- EObject B1_O = EcoreUtil.create(B1.getEReferenceType());
- B.eSet(B1, B1_O);
But this fails with the "IllegalCastException". :-( Any idea what I am
doing wrong?
Probably I should mention that B is of type "many". But it also fails if
it is not.
The point is: How would I "fill" a model recursively using the
reflective API? I searched so many examples - but all I try just stops
at a certain point, especially if the child is another ECore model (thus
another package, another factory etc...). It works smooth from the
generated editor (obviously) but when I try to emulate this not using
commands (I don't have an editing domain) I am stuck.
|
|
|
Re: Reflective API (eSet) in multiple (parent/child) models [message #425873 is a reply to message #425870] |
Wed, 10 December 2008 16:55 |
Ed Merks Messages: 33141 Registered: July 2009 |
Senior Member |
|
|
Morten,
Comments below.
Morten MacFly wrote:
> Dear NG,
> I have asked this already but thought I found the solution. Hence I did
> not. So I am asking again hereby:
>
> I have a model structure that exist of several ECore models (one root,
> several children). Now I am writing an import filter for an external
> format that would create a model accordingly. I want to "eSet" all
> sub-elements but I receive a "IllegalCastException" when I try to create
> the cildren.
>
> Assume this structure:
> Resource
> - Root (first EObject)
> - A (child of Root, but own ecore model)
> - B (child of Root, but own ecore model)
> - B1 (child of B, inside "B" ecore model)
> - B2 (child of B, inside "B" ecore model)
>
It generally makes little difference how classes are distributed across
packages.
> What I am doing is this:
> - Creating the ResourceSet / Resource "Resource"
> - Obtaining the root structural feature (RootSF)
> - Obtaining the root ECLass (RootEC)
> ....then:
> - Root = RootFactory.create(RootEC)
> - Root.eSet(RootSF, EcoreUtil.create((EClass)RootSF.getEType()));
> - Resource.getContents().add(Root);
> Up to here it's just "copied" from the default (generated) wizard. Now
> comes my part accordingly:
> - EReference B = RootPackage.eINSTANCE.getB();
>
RooPackage.Literals.A__B would be more efficient.
> - EObject B_O = EcoreUtil.create(B.getEReferenceType());
>
And given you know the feature statically, you also know the class
statically...
> - Root.eSet(B, B_O);
> - This works, I see the child "B" in the model instance if I stop here.
>
> Now I want to add the B1/B2, too the same way:
> - EReference B1 = BPackage.eINSTANCE.getB1();
>
Is B1 a feature of B?
> - EObject B1_O = EcoreUtil.create(B1.getEReferenceType());
> - B.eSet(B1, B1_O);
>
> But this fails with the "IllegalCastException". :-( Any idea what I am
> doing wrong?
>
This result seems to indicate that it is not.
> Probably I should mention that B is of type "many". But it also fails if
> it is not.
>
If it's a many you'd need to do ((List<EObject>)B.eGet(B1)).add(B1_O).
> The point is: How would I "fill" a model recursively using the
> reflective API?
Pretty much like you're doing, but of course in general the reference's
type could be abstract so you can't directly create an instance of that.
> I searched so many examples - but all I try just stops
> at a certain point, especially if the child is another ECore model (thus
> another package, another factory etc...).
The EcoreUtil utility makes sure you use the right factory (the class'
package's factory) so this package decomposition shouldn't matter.
> It works smooth from the
> generated editor (obviously) but when I try to emulate this not using
> commands (I don't have an editing domain) I am stuck.
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Powered by
FUDForum. Page generated in 0.02984 seconds