Search code examples
javaemf

Get EClass from EMF model instance class


Given any Class<?> clazz object, is there an API to get the EClass whose model instances implement clazz? (i.e. the eClass for which eClass.getInstanceClass().equals(clazz) is true)

If I had an eObject, I could simply call eObject.eClass() to get the EClass. But in my case I have no such instance. I only have a model instance class and need the associated EClass to call EcoreUtil.create(eClass).


Solution

  • In order to illustrate the answer, I will asume that we have a metamodel called Foo as in your previous answer and that the associated package is FooPackage and the associated factory is FooFactory. In this metamodel I will suppose we have A and B which are EClass.

    In order to get the associated EClass to a A.class, you can use this:

    String aName = A.class.getSimpleName();
    EClassifier classif = FooPackage.eInstance.getEClassifier(aName);
    if (classif != null && classif instanceof EClass) {
      // At this point, you have the right EClass, 
      // you can now create an instance using the factory
      EObject myinstance = FooFactory.eInstance.create((EClass)classif);
    }
    

    After that, you will need to deal with dynamic instances (your EObject) unless you explicitally castmyinstance into an A using this:

    A instance = (A) myinstance;
    // or 
    A instance = A.class.cast(myinstance);
    

    If you put all of this in a method, it could look like this:

    public static <T> T create(java.lang.Class<T> clazz) {
      String iName = clazz.getSimpleName();
      EClassif classif = FooPackage.eInstance.getEClassifier(iName);
      if (classif != null && classif instanceof EClass) {
        return clazz.cast(FooFactory.eInstance.create((EClass)classif));
      }
      return null; // or throw exception, clazz not found or stuff like that
    }
    

    Please note that at this point, you have to be sure that the interface you will try to create (A.class) is indeed EClass and is not abstract, otherwise an exception will be raised.

    In order to handle this kind of stuffs, I began to code a kind of library for this few month ago: https://github.com/aranega/dynemf

    It is not yet fully documented, but you can do stuffs like this:

    EPackageWrapper mymm = ePackage(FooPackage.eINSTANCE);
    mymm.create(A.class)
      .set("name", "MyAInstance")
      .set("bRels", mymm.create(B.class)
                      .set("name", "MyB1"));
    

    You can browse the code, perhaps it could help you.

    Hope I understood right your issue.