我的问题分为两部分:
1)如何从scala / java代码创建和/或修改EMF ecore文件(带有.ecore后缀的ecore元模型)?
2)如何从我的scala / java代码创建和/或修改ecore文件的实例(即符合ecore元模型的模型)?
我希望看看是否有一些可能的方法来实现这些,其他方法是使用XML API直接操作相应的XML文件。
非常感谢提供代码spinet或对它的引用。
ps。作为背景思考,我想知道我是否可以使用单个API来执行上述两个任务,因为我们可以将ecore文件看作Ecore的模型/实例.ecore。
答案 0 :(得分:8)
基本概念(资源,资源集,资源工厂和注册表):
在回答这个问题之前,我将解释ecore API中的一些概念。前两个概念是Resource和ResourceSet。资源是持久资源(如ecore文件)的程序级表示,而ResourceSet只是这类资源的集合。每个ecore元模型文档以及模型文档(符合其元模型)都是资源。因此,使用这些文件的第一步是将它们的程序级表示形式提供为resourceSet中的资源。
另外两个概念是Resource Factory和Registry。工厂类用于生成资源,注册表跟踪resourceSets中这些工厂的列表。根据我们的资源存储方式,我们可以使用不同的工厂来操作它们。例如, EcoreResourceFactoryImpl , XMLResourceFactoryImpl 和 XMIResourceFactoryImpl 是工厂实现的一些示例,可分别用于处理 ecore < / em>, xml 和 xmi 文件。如果我们想使用这些工厂来处理resourceSet中的资源,我们首先需要将它们放在resourceSet的注册表列表中。因此,对于我上面提到的每个resourceSet,都有一个注册表列表。
综上所述,让我们看看如何在java代码中加载和修改ecore文件(元模型)和实例文件(模型)。
首先,我们需要创建一个resourceSet来表示我们想要使用的持久资源:
ResourceSet resourceSet = new ResourceSetImpl();
然后在这个resourceSet的注册表中,我们需要注册我们想要使用的工厂:
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", new EcoreResourceFactoryImpl());
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
以上两行代码只需将 EcoreResourceFactoryImpl 和 XMIResourceFactoryImpl 分别注册为ecore和xmi文件工厂(注意 ecore 和 xmi 是那里的文件扩展名。我假设我的元模型文件扩展名是ecore,我的模型文件扩展名是xmi。
注册这些工厂后,我们现在可以要求我们的ResourceSet加载我们的元模式(即ecore)文件,如下所示:
Resource myMetaModel= resourceSet.getResource(URI.createFileURI("./univ.ecore"), true);
univ.ecore是我的ecore文件的名称。
要加载模型文件,我们需要再迈出一步!我们需要先在resourceSet中再注册一件事。这是在我们的资源集的注册表列表中注册我们的ecore元模型的包。为此,我们需要首先获得我们的ecore包的编程级表示,如下所示:
EPackage univEPackage = (EPackage) myMetaModel.getContents().get(0);
然后,在我们的资源集registry list of packages中注册此包,如下所示:
resourceSet.getPackageRegistry().put("http://gholizadeh.org", univEPackage);
我们现在准备加载我们的模型(xmi文件)。我们使用以下代码:
Resource myModel = resourceSet.getResource( URI.createURI( "./univModel.xmi"), true);
现在我们将元模式和模型文件都带到了编程层面,我们可以简单地在代码中操作它们。
更改元模型:
例如,要在ecore文件中创建新类,我们使用EcoreFactory API:我们首先获取此类的实例,如下所示:
EcoreFactory theCoreFactory = EcoreFactory.eINSTANCE;
然后创建一个EClass,如下所示:
EClass adultEClass= theCoreFactory.createEClass();
然后,为了保留这个类,我们需要将它添加到我们加载的ecore包分类器的列表中,如下所示:
univEPackage.getEClassifiers().add(adultEClass);
要进行附加更改,您需要更熟悉ecore API。
更改模型:
要更改模型,我们需要创建EObject类型的对象。与上面的EcoreFactory类似,我们需要一家工厂来做这件事。但是,我们需要一个对象工厂,而不是EcoreFactory。对于每个ecore包,我们可以获得类型为EFactory的特定对象工厂,如下所示:
EFactory univInstance = univEPackage.getEFactoryInstance();
请注意,上面代码中的univEPackage代表我们的ecore包(参见上面的一些段落)。完成此操作后,我们就可以为模型创建对象了。例如
EObject adultObject = univInstance.create(adultEClass);
在我们的模型中创建一个类型为adultEClass的对象。请注意,为了持久化这个新创建的对象,我们需要将它添加到我们的资源内容中(代表我们的模型,即myModel)。由于我们的持久文件是xmi格式并且只有一个根,我们需要将所有对象放在一个列表中并将此列表添加到我们的资源中:
EList<EObject> ModelObjects = new BasicEList<EObject>();
ModelObjects.add(adultObject);
myModel.getContents().addAll(ModelObjects);
存储模型和元模型文件:
最后,在我们修改了元模型和模型元素之后,我们需要将它们再次存储在相应的文件中。这可以通过调用相应资源的save方法来完成:
myModel.save(null);
myMetaodel.save(null);