![](/img/trans.png)
[英]How to create Genmodel and model code from ecore programmatically using EMF API?
[英]Create and modify ecore files and their instances from code
我的問題有兩個部分:
1) 如何從我的 scala/java 代碼創建和/或修改然后存儲 EMF 生態文件(帶有 .ecore 后綴的生態元模型)?
2) 如何從我的 scala/java 代碼創建和/或修改 ecore 文件的實例(即符合 ecore 元模型的模型)?
我想看看是否有一些可能的方法來做這些,其他的使用 XML API 直接操作它們相應的 XML 文件。
非常感謝提供代碼spinet 或對它的引用。
附: 作為背景想法,我想知道是否可以使用單個 API 來執行上述兩項任務,因為我們可以將 ecore 文件視為 Ecore.ecore 的模型/實例。
基本概念(資源、資源集、資源工廠和注冊表):
在回答這個問題之前,我先解釋一下ecore API 中的一些概念。 前兩個概念是Resource和ResourceSet 。 Resource 是持久化資源(如 ecore 文件)的程序級表示,而 ResourceSet 只是這些資源的集合。 每個ecore元模型文檔以及模型文檔(符合其元模型)都是一個資源。 因此,處理這些文件的第一步是提供它們作為資源集中的資源的程序級表示。
另外兩個概念是Resource Factory和Registry 。 工廠類用於生成資源,注冊中心在資源集中跟蹤這些工廠的列表。 根據我們的資源存儲方式,我們可以使用不同的工廠來操作它們。 例如, EcoreResourceFactoryImpl 、 XMLResourceFactoryImpl和XMIResourceFactoryImpl是可用於分別處理ecore 、 xml和xmi文件的工廠實現的一些示例。 如果我們想使用這些工廠來處理一個resourceSet中的資源,我們需要先把它們放到resourceSet的注冊列表中。 因此,對於我上面提到的每個資源集,都有一個注冊表列表。
說了這么多,我們來看看一個ecore文件(元模型)和一個實例文件(模型)是如何在java代碼中加載和修改的。
首先,我們需要創建一個資源集來表示我們想要使用的持久資源:
ResourceSet resourceSet = new ResourceSetImpl();
然后在這個資源集的注冊表中,我們需要注冊我們想要使用的工廠:
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 文件的名稱。
為了加載模型文件,我們需要再進一步! 我們需要先在我們的資源集中再注冊一個東西。 即在我們資源集中的包注冊列表中注冊我們ecore元模型的包。 為此,我們需要首先獲得我們的 ecore 包的編程級別表示,如下所示:
EPackage univEPackage = (EPackage) myMetaModel.getContents().get(0);
然后,在我們的資源集的包的注冊表列表中注冊這個包,如下所示:
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 代表我們的核心包(參見上面的一些段落)。 完成此操作后,我們就可以為我們的模型創建對象了。 例如
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);
myMetaModel.save(null);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.