如何使用 Java 代码生成 EMF 模型
How to generate EMF models with Java code
我想用 Java 代码生成 EMF 模型。例如,我想创建一个新的 Ecore 建模项目,并构建一个如许多教程中所示的简单模型(即像 vogella tutorial). But I don't want to do that by hand, using the GUI. I want to learn how to create a model with Java code, using the EMF-Ecore-API。
我试图找到关于这个主题的教程。但令我失望的是,我找不到太多关于这个话题的信息。我唯一能找到的是一些 code snippets to load and modify existing models by code。但与创建新模型无关。只是浏览 API 对我没有帮助。
是否有关于此主题的资源?如果没有,我如何通过 java 代码创建 EMF 模型?
IBM 有一个关于动态 EMF 的主题。
但如果您熟悉 emf 中的创建工作方式,则它非常简单。每个 EPackage 都有自己的 EFactory
和 EPackage
实例,它们处理创建(工厂)或存储有关元模型本身(epackage)的信息。
Ecore 有自己的 EPackage
和 EFactory
,所以绝对可以像这样即时创建新的元模型:
/*Use the Ecore factory*/
EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE;
/*Create your EPackage*/
EPackage myPackage = ecoreFactory.createEPackage();
/*set EPackage properties*/
myPackage.setName("myTest");
myPackage.setNsPrefix("myTest");
myPackage.setNsURI("http://com.myTest");
/*Create your first EClass*/
EClass myFirstEClass = ecoreFactory.createEClass();
myFirstEClass.setName("myClass");
/*Add to your EPackage's EClassifiers*/
/*EClasses and EDatatypes implement both EClassifiers*/
myPackage.getEClassifiers().add(myFirstEClass);
/*Create your first EAtttribute*/
EAttribute myFirstEAtt = ecoreFactory.createEAttribute();
myFirstEAtt.setName("name");
/*Use the EcorePackage Datatypes -> here EString*/
myFirstEAtt.setEType(EcorePackage.eINSTANCE.getEString());
/*use EStructuralFeatures to add your EAtt*/
/*EReferences and EAttributes are both EStructuralfeatures*/
myFirstEClass.getEStructuralFeatures().add(myFirstEAtt);
更新:
/*Create your second EClass*/
EClass mySecondEClass = ecoreFactory.createEClass();
mySecondEClass.setName("mySecondClass");
myPackage.getEClassifiers().add(mySecondEClass);
/*now, the firstClass should hold instances of secondClass*/
/*1. create EReference (Ereferences unlike EAttributes define relationships between EClasses)*/
EReference secondClassesRef = ecoreFactory.createEReference();
secondClassesRef.setName("secondClasses");
/*set containment true -> every EObject must have a Container*/
secondClassesRef.setContainment(true);
/*set Type to your EClass*/
secondClassesRef.setEType(mySecondEClass);
/*set upperbound -> now the reference is an EList*/
secondClassesRef.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
/*finally add ERef to EClass*/
myFirstEClass.getEStructuralFeatures().add(secondClassesRef);
/*and for example supertypes*/
myFirstEClass.getESuperTypes().add(mySecondEClass);
现在您有了自己的 EPackage
和一个新的 EClass
,它的 EAttribute
名称类型为 EString
现在也可以将新的 EPackage 保存到 .ecore
文件,如下所示:
/*
* Save your EPackage to file ecore file:
*/
/*Initialize your EPackage*/
myPackage.eClass();
Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
Map<String, Object> m = reg.getExtensionToFactoryMap();
/*add default .ecore extension for ecore file*/
m.put(EcorePackage.eNAME, new XMIResourceFactoryImpl());
// Obtain a new resource set
ResourceSet resSet = new ResourceSetImpl();
// create a resource
Resource resource = null;
try {
resource = resSet.createResource(URI.createFileURI("/Your/Path/To/Directory/myTest.ecore"));
} catch (Exception e) {
e.printStackTrace();
}
/*add your EPackage as root, everything is hierarchical included in this first node*/
resource.getContents().add(myPackage);
// now save the content.
try {
resource.save(Collections.EMPTY_MAP);
} catch (IOException e) {
e.printStackTrace();
}
反之亦然,如果您想加载现有的 ecore EPackage:
/*
* load existing EPackage
*/
EcorePackage.eINSTANCE.eClass();
/*Initialize your EPackage*/
final Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
final Map<String, Object> m = reg.getExtensionToFactoryMap();
m.put(EcorePackage.eNAME, new XMIResourceFactoryImpl());
final ResourceSet resSet = new ResourceSetImpl();
Resource resource = null;
try {
resource = resSet.getResource(URI.createFileURI("/Your/Path/To/Directory/myTest.ecore"), true);
} catch (Exception e) {
e.printStackTrace();
}
/*load root and cast to EPackage*/
final EPackage root = (EPackage) resource.getContents().get(0);
更新:
Ecore 当然有自己的元模型。在 Docs 中,您可以找到对 ecore 架构的精彩概述。
因此,如果您想使用动态 EMF,则需要了解这一点。正如我向您展示的,动态创建一个 EPackage
非常简单,但是您需要知道如何设置 ecore 模型的基本属性(EClass、EAttributes、EReferences、EType、containment、supertypes ...) .一旦你理解了架构,那就很容易了。查看页面底部的 UML 图。
我还更新了上面的代码,向您展示如何初始化 EClasses 之间的关系
我想用 Java 代码生成 EMF 模型。例如,我想创建一个新的 Ecore 建模项目,并构建一个如许多教程中所示的简单模型(即像 vogella tutorial). But I don't want to do that by hand, using the GUI. I want to learn how to create a model with Java code, using the EMF-Ecore-API。
我试图找到关于这个主题的教程。但令我失望的是,我找不到太多关于这个话题的信息。我唯一能找到的是一些 code snippets to load and modify existing models by code。但与创建新模型无关。只是浏览 API 对我没有帮助。
是否有关于此主题的资源?如果没有,我如何通过 java 代码创建 EMF 模型?
IBM 有一个关于动态 EMF 的主题。
但如果您熟悉 emf 中的创建工作方式,则它非常简单。每个 EPackage 都有自己的 EFactory
和 EPackage
实例,它们处理创建(工厂)或存储有关元模型本身(epackage)的信息。
Ecore 有自己的 EPackage
和 EFactory
,所以绝对可以像这样即时创建新的元模型:
/*Use the Ecore factory*/
EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE;
/*Create your EPackage*/
EPackage myPackage = ecoreFactory.createEPackage();
/*set EPackage properties*/
myPackage.setName("myTest");
myPackage.setNsPrefix("myTest");
myPackage.setNsURI("http://com.myTest");
/*Create your first EClass*/
EClass myFirstEClass = ecoreFactory.createEClass();
myFirstEClass.setName("myClass");
/*Add to your EPackage's EClassifiers*/
/*EClasses and EDatatypes implement both EClassifiers*/
myPackage.getEClassifiers().add(myFirstEClass);
/*Create your first EAtttribute*/
EAttribute myFirstEAtt = ecoreFactory.createEAttribute();
myFirstEAtt.setName("name");
/*Use the EcorePackage Datatypes -> here EString*/
myFirstEAtt.setEType(EcorePackage.eINSTANCE.getEString());
/*use EStructuralFeatures to add your EAtt*/
/*EReferences and EAttributes are both EStructuralfeatures*/
myFirstEClass.getEStructuralFeatures().add(myFirstEAtt);
更新:
/*Create your second EClass*/
EClass mySecondEClass = ecoreFactory.createEClass();
mySecondEClass.setName("mySecondClass");
myPackage.getEClassifiers().add(mySecondEClass);
/*now, the firstClass should hold instances of secondClass*/
/*1. create EReference (Ereferences unlike EAttributes define relationships between EClasses)*/
EReference secondClassesRef = ecoreFactory.createEReference();
secondClassesRef.setName("secondClasses");
/*set containment true -> every EObject must have a Container*/
secondClassesRef.setContainment(true);
/*set Type to your EClass*/
secondClassesRef.setEType(mySecondEClass);
/*set upperbound -> now the reference is an EList*/
secondClassesRef.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
/*finally add ERef to EClass*/
myFirstEClass.getEStructuralFeatures().add(secondClassesRef);
/*and for example supertypes*/
myFirstEClass.getESuperTypes().add(mySecondEClass);
现在您有了自己的 EPackage
和一个新的 EClass
,它的 EAttribute
名称类型为 EString
现在也可以将新的 EPackage 保存到 .ecore
文件,如下所示:
/*
* Save your EPackage to file ecore file:
*/
/*Initialize your EPackage*/
myPackage.eClass();
Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
Map<String, Object> m = reg.getExtensionToFactoryMap();
/*add default .ecore extension for ecore file*/
m.put(EcorePackage.eNAME, new XMIResourceFactoryImpl());
// Obtain a new resource set
ResourceSet resSet = new ResourceSetImpl();
// create a resource
Resource resource = null;
try {
resource = resSet.createResource(URI.createFileURI("/Your/Path/To/Directory/myTest.ecore"));
} catch (Exception e) {
e.printStackTrace();
}
/*add your EPackage as root, everything is hierarchical included in this first node*/
resource.getContents().add(myPackage);
// now save the content.
try {
resource.save(Collections.EMPTY_MAP);
} catch (IOException e) {
e.printStackTrace();
}
反之亦然,如果您想加载现有的 ecore EPackage:
/*
* load existing EPackage
*/
EcorePackage.eINSTANCE.eClass();
/*Initialize your EPackage*/
final Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
final Map<String, Object> m = reg.getExtensionToFactoryMap();
m.put(EcorePackage.eNAME, new XMIResourceFactoryImpl());
final ResourceSet resSet = new ResourceSetImpl();
Resource resource = null;
try {
resource = resSet.getResource(URI.createFileURI("/Your/Path/To/Directory/myTest.ecore"), true);
} catch (Exception e) {
e.printStackTrace();
}
/*load root and cast to EPackage*/
final EPackage root = (EPackage) resource.getContents().get(0);
更新: Ecore 当然有自己的元模型。在 Docs 中,您可以找到对 ecore 架构的精彩概述。
因此,如果您想使用动态 EMF,则需要了解这一点。正如我向您展示的,动态创建一个 EPackage
非常简单,但是您需要知道如何设置 ecore 模型的基本属性(EClass、EAttributes、EReferences、EType、containment、supertypes ...) .一旦你理解了架构,那就很容易了。查看页面底部的 UML 图。
我还更新了上面的代码,向您展示如何初始化 EClasses 之间的关系