从 EMF 模型实例获取 EClass class
Get EClass from EMF model instance class
给定任何 Class<?> clazz
对象,是否存在 API 来获取其模型实例实现 clazz
的 EClass
? (即 eClass.getInstanceClass().equals(clazz)
为真的 eClass
)
如果我有 eObject
,我可以简单地调用 eObject.eClass()
来获得 EClass
。但就我而言,我没有这样的例子。我只有一个模型实例 class 并且需要关联的 EClass
来调用 EcoreUtil.create(eClass)
。
我找不到任何 API。 EClass
与其实例 class 之间的关系由生成的初始化方法设置,但没有任何反向映射。这样做的原因似乎是没有一对一的关系,因为多个模型元素可以使用同一个实例接口。
如果您确定每个 class 使用不同的接口,则可以迭代所有 EClassifiers
并自己构建映射。
Map<Class<?>, EClass> eClasses = new HashMap<>();
for (final EClassifier eClassifier : FooPackage.eINSTANCE.getEClassifiers()) {
if (eClassifier instanceof EClass) {
if(eClasses.put(eClassifier.getInstanceClass(), (EClass) eClassifier) != null) {
throw new RuntimeException(
"Failed to create distinct instance class to EClass mapping for "
+ Classifier.getInstanceClass());
}
}
}
为了说明答案,我将假设我们有一个名为 Foo
的元模型,就像您之前的答案一样,并且关联的包是 FooPackage
,关联的工厂是 FooFactory
.在这个元模型中,我假设我们有 A
和 B
,它们是 EClass
.
为了得到关联的 EClass
到 A.class
,你可以使用这个:
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);
}
在那之后,您将需要处理动态实例(您的 EObject),除非您使用以下方法将 myinstance
显式转换为 A
:
A instance = (A) myinstance;
// or
A instance = A.class.cast(myinstance);
如果将所有这些都放在一个方法中,它可能看起来像这样:
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
}
请注意,此时,您必须确定您将尝试创建的接口 (A.class
) 确实是 EClass
并且不是抽象的,否则将引发异常.
为了处理这类事情,几个月前我开始编写一种库:https://github.com/aranega/dynemf
它还没有完全记录,但你可以这样做:
EPackageWrapper mymm = ePackage(FooPackage.eINSTANCE);
mymm.create(A.class)
.set("name", "MyAInstance")
.set("bRels", mymm.create(B.class)
.set("name", "MyB1"));
您可以浏览一下代码,或许对您有所帮助。
希望我理解正确你的问题。
给定任何 Class<?> clazz
对象,是否存在 API 来获取其模型实例实现 clazz
的 EClass
? (即 eClass.getInstanceClass().equals(clazz)
为真的 eClass
)
如果我有 eObject
,我可以简单地调用 eObject.eClass()
来获得 EClass
。但就我而言,我没有这样的例子。我只有一个模型实例 class 并且需要关联的 EClass
来调用 EcoreUtil.create(eClass)
。
我找不到任何 API。 EClass
与其实例 class 之间的关系由生成的初始化方法设置,但没有任何反向映射。这样做的原因似乎是没有一对一的关系,因为多个模型元素可以使用同一个实例接口。
如果您确定每个 class 使用不同的接口,则可以迭代所有 EClassifiers
并自己构建映射。
Map<Class<?>, EClass> eClasses = new HashMap<>();
for (final EClassifier eClassifier : FooPackage.eINSTANCE.getEClassifiers()) {
if (eClassifier instanceof EClass) {
if(eClasses.put(eClassifier.getInstanceClass(), (EClass) eClassifier) != null) {
throw new RuntimeException(
"Failed to create distinct instance class to EClass mapping for "
+ Classifier.getInstanceClass());
}
}
}
为了说明答案,我将假设我们有一个名为 Foo
的元模型,就像您之前的答案一样,并且关联的包是 FooPackage
,关联的工厂是 FooFactory
.在这个元模型中,我假设我们有 A
和 B
,它们是 EClass
.
为了得到关联的 EClass
到 A.class
,你可以使用这个:
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);
}
在那之后,您将需要处理动态实例(您的 EObject),除非您使用以下方法将 myinstance
显式转换为 A
:
A instance = (A) myinstance;
// or
A instance = A.class.cast(myinstance);
如果将所有这些都放在一个方法中,它可能看起来像这样:
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
}
请注意,此时,您必须确定您将尝试创建的接口 (A.class
) 确实是 EClass
并且不是抽象的,否则将引发异常.
为了处理这类事情,几个月前我开始编写一种库:https://github.com/aranega/dynemf
它还没有完全记录,但你可以这样做:
EPackageWrapper mymm = ePackage(FooPackage.eINSTANCE);
mymm.create(A.class)
.set("name", "MyAInstance")
.set("bRels", mymm.create(B.class)
.set("name", "MyB1"));
您可以浏览一下代码,或许对您有所帮助。
希望我理解正确你的问题。