简体   繁体   English

从代码创建和修改 ecore 文件及其实例

[英]Create and modify ecore files and their instances from code

My question has two parts:我的问题有两个部分:

1) How can I create and/or modify and then store EMF ecore files (ecore metamodels with .ecore suffixes) from my scala/java code? 1) 如何从我的 scala/java 代码创建和/或修改然后存储 EMF 生态文件(带有 .ecore 后缀的生态元模型)?

2) How can I create and/or modify an instance of an ecore file (ie a model conforming to an ecore metamodel) from my scala/java code? 2) 如何从我的 scala/java 代码创建和/或修改 ecore 文件的实例(即符合 ecore 元模型的模型)?

I am looking to see if there are some possible ways of doing these, other that manipulating directly their corresponding XML files using XML API's.我想看看是否有一些可能的方法来做这些,其他的使用 XML API 直接操作它们相应的 XML 文件。

Providing a code spinet or a reference to it is very much appreciated.非常感谢提供代码spinet 或对它的引用。

ps.附: As a background thought, I am wondering if I can use a single API for performing both of the above tasks, as we can look to an ecore file as a model/instance of Ecore.ecore.作为背景想法,我想知道是否可以使用单个 API 来执行上述两项任务,因为我们可以将 ecore 文件视为 Ecore.ecore 的模型/实例。

Basic Concepts (Resource, ResourceSet, Resource Factory and Registry):基本概念(资源、资源集、资源工厂和注册表):

Before answering this question I will explain some concepts in ecore API.在回答这个问题之前,我先解释一下ecore API 中的一些概念。 The First two concepts are Resource and ResourceSet .前两个概念是ResourceResourceSet Resource is a program level representation of a persistent resource (like an ecore file), and ResourceSet is simply a set of these kind of resources. Resource 是持久化资源(如 ecore 文件)的程序级表示,而 ResourceSet 只是这些资源的集合。 Each ecore metamodel document as well as a model document (which conforms to its metamodel) is a resource.每个ecore元模型文档以及模型文档(符合其元模型)都是一个资源。 Therefore the first step to work with these files is to provide a program level representation of them as resources in a resourceSet.因此,处理这些文件的第一步是提供它们作为资源集中的资源的程序级表示。

Another two concepts are Resource Factory and Registry .另外两个概念是Resource FactoryRegistry Factory classes are used to generate resources, and registries are keeping track of list of these factories in resourceSets.工厂类用于生成资源,注册中心在资源集中跟踪这些工厂的列表。 Depending on how our resource are stored, we can use different factories to manipulate them.根据我们的资源存储方式,我们可以使用不同的工厂来操作它们。 For example, EcoreResourceFactoryImpl , XMLResourceFactoryImpl , and XMIResourceFactoryImpl are some examples of factory implementations that can be used to handle, respectively, ecore , xml , and xmi files.例如, EcoreResourceFactoryImplXMLResourceFactoryImplXMIResourceFactoryImpl是可用于分别处理ecorexmlxmi文件的工厂实现的一些示例。 If we want to use these factories to handle resources in a resourceSet we need to put them in the registry list of resourceSet first.如果我们想使用这些工厂来处理一个resourceSet中的资源,我们需要先把它们放到resourceSet的注册列表中。 So, for each resourceSet that I mentioned above, there is a registry list.因此,对于我上面提到的每个资源集,都有一个注册表列表。

With all the above being said, let's see how loading and modifying an ecore file (metamodel) and an instance file (model) happens in a java code.说了这么多,我们来看看一个ecore文件(元模型)和一个实例文件(模型)是如何在java代码中加载和修改的。

First, We need to create a resourceSet to represent our persistent resources we would like to work with:首先,我们需要创建一个资源集来表示我们想要使用的持久资源:

ResourceSet resourceSet = new ResourceSetImpl(); 

Then in the registry of this resourceSet, we need to register the Factories we want to work with:然后在这个资源集的注册表中,我们需要注册我们想要使用的工厂:

resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", new EcoreResourceFactoryImpl());
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new  XMIResourceFactoryImpl());

Above two lines of code simply register EcoreResourceFactoryImpl and XMIResourceFactoryImpl as, respectively, ecore and xmi file factories (note that ecore and xmi are file extensions there).以上两行代码简单地将EcoreResourceFactoryImplXMIResourceFactoryImpl分别注册为 ecore 和 xmi 文件工厂(注意ecorexmi是那里的文件扩展名)。 I assumed that my metamodel file extension is ecore and my model file extension is xmi.我假设我的元模型文件扩展名是 ecore,我的模型文件扩展名是 xmi。

After registering these Factories, we can now ask our ResourceSet to load our metamodel (ie, ecore) file as below:注册这些工厂后,我们现在可以要求我们的 ResourceSet 加载我们的元模型(即 ecore)文件,如下所示:

Resource myMetaModel= resourceSet.getResource(URI.createFileURI("./univ.ecore"), true);

univ.ecore is the name of my ecore file. univ.ecore 是我的 ecore 文件的名称。

For loading a model file we need to take one further step!为了加载模型文件,我们需要再进一步! We need to first register one more thing in our resourceSet.我们需要先在我们的资源集中再注册一个东西。 That is to register the package of our ecore metamodel in the registry list of packages in our resource set.即在我们资源集中的包注册列表中注册我们ecore元模型的包。 For doing this we need to first get a programming level representation of our ecore package as bellow:为此,我们需要首先获得我们的 ecore 包的编程级别表示,如下所示:

EPackage univEPackage = (EPackage) myMetaModel.getContents().get(0);

And then, register this package in the registry list of packages of our resource set as below:然后,在我们的资源集的包注册表列表中注册这个包,如下所示:

resourceSet.getPackageRegistry().put("http://gholizadeh.org", univEPackage);

We are now ready to load our model (xmi file).我们现在准备加载我们的模型(xmi 文件)。 We use the following code for this:为此,我们使用以下代码:

Resource myModel = resourceSet.getResource( URI.createURI( "./univModel.xmi"), true);

Now we have brought both of our metamodel and model files to the programming level, and we can simply manipulate them in code.现在我们已经将元模型和模型文件带到了编程级别,我们可以简单地在代码中操作它们。

Change the Metamodel:更改元模型:

For example, for creating a new Class in an ecore file, we use EcoreFactory API: we first obtain an instance of this class as below:例如,为了在 ecore 文件中创建一个新类,我们使用EcoreFactory API:我们首先获取此类的实例,如下所示:

EcoreFactory theCoreFactory = EcoreFactory.eINSTANCE;

and then create an EClass as the following:然后创建一个 EClass 如下:

EClass adultEClass= theCoreFactory.createEClass();

Then for keeping this Class, we need to add it to the list of our loaded ecore package classifiers as bellow:然后为了保留这个类,我们需要将它添加到我们加载的 ecore 包分类器列表中,如下所示:

univEPackage.getEClassifiers().add(adultEClass);

For doing aditional changes you need to get more familiar with ecore API .要进行其他更改,您需要更加熟悉ecore API

Change the Model:更改模型:

for changing a model, we need to create objects of type EObject.为了改变模型,我们需要创建 EObject 类型的对象。 Similar to EcoreFactory in the above, we need a factory to do this.与上面的 EcoreFactory 类似,我们需要一个工厂来做到这一点。 But instead of EcoreFactory, we need an object factory.但是我们需要一个对象工厂而不是 EcoreFactory。 For each ecore package there is an specific object factory of type EFactory that we can get as the following:对于每个 ecore 包,都有一个EFactory类型的特定对象工厂,我们可以获得如下:

EFactory univInstance = univEPackage.getEFactoryInstance();

Note that univEPackage in above code, represents our ecore package (see some paragraphs above).请注意,上面代码中的 univEPackage 代表我们的核心包(参见上面的一些段落)。 After doing this, we are ready to create objects for our model.完成此操作后,我们就可以为我们的模型创建对象了。 For example例如

EObject adultObject = univInstance.create(adultEClass);

create an object of type adultEClass, in our model.在我们的模型中创建一个 AdultEClass 类型的对象。 Note that for persisting this newly created object we need to add it to the content of our resource (that represent our model, ie, myModel).请注意,为了持久化这个新创建的对象,我们需要将它添加到我们的资源(代表我们的模型,即 myModel)的内容中。 Since our persistent file is in xmi format and it has only one root we need to put all of our objects in a list and add this list to our resource:由于我们的持久文件是 xmi 格式并且它只有一个根,我们需要将我们所有的对象放在一个列表中并将这个列表添加到我们的资源中:

EList<EObject> ModelObjects = new BasicEList<EObject>(); 
ModelObjects.add(adultObject);

myModel.getContents().addAll(ModelObjects);

Storing Model and Metamodel files:存储模型和元模型文件:

Finally, after we modified our metamodel and model elements we need to store them again in their corresponding files.最后,在我们修改了元模型和模型元素之后,我们需要将它们再次存储在相应的文件中。 This is simply done by calling save method of their corresponding Resources:这只需通过调用其相应资源的 save 方法即可完成:

myModel.save(null);

myMetaModel.save(null);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM