Setting Single Containment Reference of A Model Element's using EMF Reflective API [message #1734718] |
Fri, 10 June 2016 14:39 |
Eclipse User |
|
|
|
Hello everyone,
I have the following (simplified) metamodel:
abstract class A
{
attribute unit : String = 'some unit';
property value : DataDomain { composes }; //This is supposed to be 1..1 reference.
}
abstract class DataDomain;
class DataValueTypeA extends DataDomain
{
attribute minValue : ecore::EInt = '1';
attribute maxValue : ecore::EInt = '1';
}
class SubclassA extends A;
Using Java EMF Reflective API, I want to create an instance of SubclassA and an instance of DataValueTypeA and set value reference accordingly.
I tried the following code segment with two different versions ( the beginning is the same, I have tried Try 1 and Try 2):
EFactory metaFactoryInstanceCreator = myMetamodelPackage.getEFactoryInstance();
EClass A_EC = (EClass) myMetamodelPackage.getEClassifier("A");
EClass DataValueTypeA_EC = (EClass) myMetamodelPackage.getEClassifier("DataValueTypeA");
EObject a_instance = metaFactoryInstanceCreator.create( A_EC );
EObject dataValue_instance = metaFactoryInstanceCreator.create( DataValueTypeA_EC);
EReference valueAttr = (EReference) A_EC.getEStructuralFeature("value");
//Try 1
a_instance.eSet( valueAttr, dataValue_instance );
//Try 2
((EList) a_instance.eGet(valueAttr)).add( dataValue_instance)
Try 1 works, however the created model does not validate since the reference is not properly set.
Try 2 does not work and throws an exception since eGet() returns a null value.
How should solve this problem?
Thank you.
|
|
|
|
Re: Setting Single Containment Reference of A Model Element's using EMF Reflective API [message #1734759 is a reply to message #1734722] |
Sat, 11 June 2016 11:32 |
Eclipse User |
|
|
|
I realized that I didn't provide enough context for the problem. I have the metamodel as given, I am aiming to create an instance of it by writing some Java code. In the metamodel, EClass A has a 1..1 containment reference "value" to a DataDomain instance. In the code,
EObject a_instance = metaFactoryInstanceCreator.create( A_EC );
EObject dataValue_instance = metaFactoryInstanceCreator.create( DataValueTypeA_EC);
the elements a_instance and dataValue_instance are instances of EClass A and DataDomain. I want to set the "value" reference of a_instance to dataValue_instance and I want to learn how to do it.
As Ed stated, my "try 2" only works for multi-valued references, so it does not apply to my case and that is why it does not work. My "try 1" does not do what I expect. The created model afterwards appears like the following:
...
<myMetamodel:DataValueTypeA_EC/>
<myMetamodel:A_EC>
<value xsi:type="myMetamodel:DataValueTypeA_EC" href="#/0"/>
</myMetamodel:A_EC>
...
The created model file does not have any other attributes (such as minValue, maxValue, unit) of either a_instance or dataValue_instance, which were set in the code (not shown in the example code to keep things readable) (Note: These values of other attributes appear in the created model file if I remove Try 1.).
|
|
|
Re: Setting Single Containment Reference of A Model Element's using EMF Reflective API [message #1734760 is a reply to message #1734759] |
Sat, 11 June 2016 11:53 |
Ed Merks Messages: 33137 Registered: July 2009 |
Senior Member |
|
|
Burgra,
Comments below.
On 11.06.2016 13:32, Bugra M. Yildiz wrote:
> I realized that I didn't provide enough context for the problem. I
> have the metamodel as given, I am aiming to create an instance of it
> by writing some Java code. In the metamodel, EClass A has a 1..1
> containment reference "value" to a DataDomain instance. In the code,
> EObject a_instance = metaFactoryInstanceCreator.create( A_EC );
> EObject dataValue_instance = metaFactoryInstanceCreator.create(
> DataValueTypeA_EC);
>
> the elements a_instance and dataValue_instance are instances of EClass
> A and DataDomain. I want to set the "value" reference of a_instance to
> dataValue_instance and I want to learn how to do it.
>
> As Ed stated, my "try 2" only works for multi-valued references, so it
> does not apply to my case and that is why it does not work. My "try 1"
> does not do what I expect. The created model afterwards appears like
> the following:
> ..
> <myMetamodel:DataValueTypeA_EC/>
> <myMetamodel:A_EC>
> <value xsi:type="myMetamodel:DataValueTypeA_EC" href="#/0"/>
> </myMetamodel:A_EC>
> ..
You've added both objects to the root of the resource, but you not shown
the code where you do that. Only A_EC needs to be added to the resource
contents. So at least for the code you've shown, this is how it should
look.
>
> The created model file does not have any other attributes (such as
> minValue, maxValue, unit) of either a_instance or dataValue_instance,
> which were set in the code (not shown in the example code to keep
> things readable)
What were they set to? If it's the default value, a default value isn't
serialized.
> (Note: These values of other attributes appear in the created model
> file if I remove Try 1.).
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: Setting Single Containment Reference of A Model Element's using EMF Reflective API [message #1734763 is a reply to message #1734760] |
Sat, 11 June 2016 14:16 |
Eclipse User |
|
|
|
Yeap, finally I worked. Thanks Ed for or help. Especially your two suggestions solved my problem:
1. Default value isn't serialized: Even if you specify values in the code for setting that are default, it still does not serialize.
2. No need for adding containment object to the resource content: Only the container's addition to the resource content was necessary.
One weird point that I observed: In my code, (1)I first create metamodel and serialize it, afterwards I create the model. After that, (2) I register the created metamodel by right-clicking on it. Following it, (3) I delete both the metamodel and the model. Then (4) I re-run the code. (5) When I try to open the created model using Exeed editor, it gives an error since it does not find the mentioned metamodel in the model. So, I have to register the metamodel every time it is created before I can open the model with Exeed editor. By the way, the model is in correct form and conforms to the metamodel.
|
|
|
Re: Setting Single Containment Reference of A Model Element's using EMF Reflective API [message #1734770 is a reply to message #1734763] |
Sat, 11 June 2016 18:24 |
Ed Merks Messages: 33137 Registered: July 2009 |
Senior Member |
|
|
Bugra,
Comments below.
On 11.06.2016 16:17, Bugra M. Yildiz wrote:
> Yeap, finally I worked. Thanks Ed for or help. Especially your two
> suggestions solved my problem:
>
> 1. Default value isn't serialized: Even if you specify values in the
> code for setting that are default, it still does not serialize.
> 2. No need for adding containment object to the resource content: Only
> the container's addition to the resource content was necessary.
>
> One weird point that I observed: In my code, (1)I first create
> metamodel and serialize it, afterwards I create the model. After that,
> (2) I register the created metamodel by right-clicking on it.
EMF Core itself doesn't provide such a capability. I'm not sure which
project is providing that.
> Following it, (3) I delete both the metamodel and the model. Then (4)
> I re-run the code. (5) When I try to open the created model using
> Exeed editor,
I'm not sure what that is or who provides it.
> it gives an error since it does not find the mentioned metamodel in
> the model. So, I have to register the metamodel every time it is
> created before I can open the model with Exeed editor. By the way, the
> model is in correct form and conforms to the metamodel.
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03360 seconds