|
|
|
Re: NPE while eSetting eContainingClass [message #1759524 is a reply to message #1759477] |
Wed, 12 April 2017 06:26 |
Edouard R. Batot Messages: 100 Registered: March 2015 |
Senior Member |
|
|
Ed Merks wrote on Tue, 11 April 2017 22:21I'm not sure why you're trying to do it reflectively when there is generated API for doing this...
Of course if you tried to do it via the API, you'd notice there is no setEContainingClass method and you'd notice the getEContainingClass method is documented like this * @model opposite="eOperations" resolveProxies="false" changeable="false"
* @generated
*/
EClass getEContainingClass();
I.e., it's not a changeable feature so you can't call eSet on it and there is no generated setter you can call either.
In other words, you can modify the eContainingClass of an EOperation only by modifying the opposite, i.e, by adding it to the eOperations of the EClass that you want as the container of the EOperation.
Ok. If I prefer the eSet it's because it allows way more indepth modification and also dynamic instantitation using String (instead of method calls). You can also overpass scope limitations (private/protected).
Anyways, - thanks for telling me the eContainingClass is not changeable - Now I wonder why such limitation ?
(Note that copying the object I manipulate using EcoreUtil.copy() has removed its eContainginClass)
And also, why is that I get a NullPointer and not the assertion : "The feature '" + eStructuralFeature.getName() + "' is not a valid feature" ?
Thanks,
Edouard
PS : Ed willing, I am sincerly annoyed with you and your patriarchist tone. I don't need morale and all you get acting so with me is compassion for the poor kids you may have. So please, if you might keep your mouth shut for a while, it would be much appreciated.
|
|
|
|
Re: NPE while eSetting eContainingClass [message #1759539 is a reply to message #1759531] |
Wed, 12 April 2017 16:17 |
Edouard R. Batot Messages: 100 Registered: March 2015 |
Senior Member |
|
|
Comments follow.
I don't get your eSet comment. It can do no more and no less than the generated API. The code you show is certainly not more readable, not more efficient, and of course has way less static checking for correctness. So it's a very strange preference you have. Kind of inexplicable.
Well, I had in the past some surprises with the features I could change via eSet, but not via the API. I might remember wrong. But then I used to change the features dynamically using their list of features and using eSet became a habit. If it's more or less readable I don't know - this is about standards.
I don't mind the inexplicable perspective, I live with it I'm trying to make a clear point though, sorry.
We intentionally not want modification of the container references. All the corresponding opposites are multi-valued so it seems better to consider where in the list you're adding?
That is correct, yes.
Of course creating a copy doesn't copy the container otherwise you'd never be able to copy just part of a tree.
I get that. My code is intricated in some genetic programming and deep/shallow copy is a nightmare. Anyways, thanks, I did the trick using oldEOperation.eContainer.getEOperations.add(newEOperation).
Thanks.
Yes, dynamic models would throw an exception. In the generated model we could generate cases for such things, but in the end that's just more byte code with little real value, except to help make silly code fail in a less silly way.
Well, it doesn't add value to the one(s) who know(s) the issue. But it is still a brutal NPE - I'm not the first one with that trouble (the unchangeable NPE-prone property).
Qualitatively speaking, if we consider the ease of comprehension of the code, it's not that useless to take it into consideration.
|
|
|
Re: NPE while eSetting eContainingClass [message #1759540 is a reply to message #1759539] |
Wed, 12 April 2017 16:37 |
German Vega Messages: 104 Registered: December 2015 Location: Grenoble, France |
Senior Member |
|
|
Hello,
Regarding your comment on the thrown exception
Quote:And also, why is that I get a NullPointer and not the assertion : "The feature '" + eStructuralFeature.getName() + "' is not a valid feature" ?
You seem to be using an old version of EMF, given the line numbers in your stack trace I would say 2.9.
In EMF version 2.9 this is the implementation of BasicEObjectImpl.eOpenSet
public void eOpenSet(EStructuralFeature eFeature, Object newValue)
{
EStructuralFeature openFeature = ExtendedMetaData.INSTANCE.getAffiliation(eClass(), eFeature);
if (openFeature != null)
{
if (!FeatureMapUtil.isFeatureMap(openFeature))
{
openFeature = ExtendedMetaData.INSTANCE.getGroup(openFeature);
}
FeatureMap featureMap = (FeatureMap)eGet(openFeature);
((FeatureMap.Internal)featureMap).set(eFeature, newValue);
}
else
{
throw new IllegalArgumentException("The feature '" + eFeature.getName() + "' is not a valid changeable feature");
}
}
If you look at EMF version 2.12, the implementation of BasicEObjectImpl.eOpenSet has been changed to
public void eOpenSet(EStructuralFeature eFeature, Object newValue)
{
EStructuralFeature openFeature = ExtendedMetaData.INSTANCE.getAffiliation(eClass(), eFeature);
if (openFeature != null)
{
if (!FeatureMapUtil.isFeatureMap(openFeature))
{
openFeature = ExtendedMetaData.INSTANCE.getGroup(openFeature);
if (openFeature == null)
{
throw new IllegalArgumentException("The feature '" + eFeature.getName() + "' is not a valid changeable feature");
}
}
FeatureMap featureMap = (FeatureMap)eGet(openFeature);
((FeatureMap.Internal)featureMap).set(eFeature, newValue);
}
else
{
throw new IllegalArgumentException("The feature '" + eFeature.getName() + "' is not a valid changeable feature");
}
}
As you can see, in the newer version an additional test has been added, and you would get an informative IllegalArgumentException("The feature '" + eFeature.getName() + "' is not a valid changeable feature");
Do you have any particular constraint to use this old version of EMF?
regards
German Vega
|
|
|
Powered by
FUDForum. Page generated in 0.05345 seconds