Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access certain EStructuralFeatures of an EMF Model?

I know that there are ways to access an EAttribute of an Eclipse EMF model by its featureID or by its name via different indirect approaches. For that I found the following: Eclipse EMF: How to get access EAttribute by name?

But what if I don't know the name of the attribute I want to get? Let's say, based on the design, the model has some fixed attributes by the developer, along with the features that can be set dynamically by the user.

So, for the time being I use the getEAllStructuralFeatures() and use indexes via get() to reach to the by-the-user-created attributes, since I know that the list I get will have the fixed attributes of the model as its first elements beginning with the index 0. But I find this solution unclear and inefficient. Also in some cases, that I want to work, not suitable.

E.g: IEMFEditProperty prop = EMFEditProperties.list(editingDomain, EMFMODELPackage.Literals.EMFMODEL.getEAllStructuralFeatures().get(X));

Do you know a solution or a workaround for this problem? As far as I can see, there are no direct methods to get such dynamically created features of the model.

Every help will be appreciated.

like image 546
DanglingElse Avatar asked Nov 08 '13 19:11

DanglingElse


1 Answers

I have been working on a similar case recently where I first tried to define an EStructuralFeature to access exactly the setting/attribute of the object that I needed.

But if you look at how things work internally in ECore, you will find out, that there is no way this will ever work, since the indices are bound to the object identity of the EStructuralFeature objects created at runtime for the specific context (i.e. EClass instance).

My approach was then to either inspect the features proposed by EClass.getEAllStructuralFeatures or to iterate over the features and inspect the object returned by EObject.eGet for this very feature (where EClass eClass = eObject.eClass()).

Example: In a UML profile I have defined a UML Stereotype called "Bean" with a property called FactoryEntity. The property shall reference a UML Class with the Stereotype "Entity" that is closest to this very bean and for which a static factory method will be generated.

enter image description here

In the model I would then have one UML Class typed as Bean and one as Entity.

enter image description here

And for the Class typed as "Bean" I would then set a value for the attribute/property factoryEntity defined in the profile.

enter image description here

The question was then how the property value would be accessible in ECore. I ended up iterating the List of available EStructuralFeature of the EClass of the EObject and checking the type of the object returned by eGet.

final EObject eObject = (EObject) holdingClass.getValue(stereotype, stereoTypePropertyName);

final EList<EStructuralFeature> allEStructFeats = eObject.eClass().getEAllStructuralFeatures();

for(EStructuralFeature esf : allEStructFeats)
{
    final Object o = eobject.eGet(esf);

    if(o instanceof org.eclipse.uml2.uml.Class)
    {
        return (org.eclipse.uml2.uml.Class) o;
    }
}

Maybe that is not the most elegant way to access structural features but it is the only one I thought was robust enough to last.

Please let me know if you have any suggestions on how to improve this.

like image 140
mwhs Avatar answered Oct 09 '22 15:10

mwhs