使用自定义 ecore 元模型的 Acceleo 转换
Acceleo transformation using a custom ecore metamodel
首先,我是 eclipse 的建模功能的新手,所以这个问题可能是微不足道的,但我已经搜索了好几天都没有找到答案。
我已经使用 ecore 建模项目创建了一个 ecore 元模型文件。 URI 是这样的:/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore
我还生成了(通过 ATL 转换)一个 xmi 模型文件。第一个元素是这样的:
<?xml version="1.0" encoding="ISO-8859-1"?>
<RESTfulServicePSM
xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns="/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore"
name="WSAT">
在 ATL 项目中,一切都按预期工作。
现在我需要使用 Acceleo 创建 M2T 转换。所以对于初学者来说,我创建了两个模块,一个 main :
[comment encoding = UTF-8 /]
[module PsmToCode('/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore')]
[import org::eclipse::acceleo::psm2code::files::ResourceModelClasses/]
[template public PsmToCode(aRESTfulServicePSM : RESTfulServicePSM)]
[comment @main/]
[for ( aCSharpResourceModel : CSharpResourceModel | aRESTfulServicePSM.hasCSharpRModel)]
[aCSharpResourceModel.generateResourceModelClasses()/]
[/for]
[/template]
还有一个:
[comment encoding = UTF-8 /]
[module ResourceModelClasses('/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore')]
[template public generateResourceModelClasses(aCSharpResourceModel : CSharpResourceModel)]
[file (aCSharpResourceModel.parentName.toUpperFirst().concat('.cs'), false, 'UTF-8')]
[/file]
[/template]
当我 运行 这个时,我得到一个 Package with uri '/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore' not found. (file:/H:/Users/doumas/workspace/PIM2PSM/WSATPSM.xmi, 6, 15)
异常。我做错了什么?
提前致谢。
您的元模型可能有 .ecore
,但您没有生成元模型代码(使用 .genmodel
)。当您尝试使用 EMF 工具(Acceleo/QVT...等)打开 .xmi
文件时,会出现您遇到的错误。所以,这里有很多要点 ;).
您可以处理元模型的静态或动态实例。
静态实例
静态实例是在您生成元模型代码(使用 .genmodel
)、将项目注册为插件并创建符合已部署元模型的模型时生成的。在这种情况下,您的元模型被部署为 Eclipse 插件,并且当该插件被 Eclipse 加载时,您的元模型在全局注册表中注册。在您的开发模式例程中,定义元模型并围绕它开发内容的最简单方法是处理两个 eclipse 实例。第一个(我将其称为“原始”实例)是您的元模型项目所在的实例。第二个是通过 run new eclipse configuration
菜单从原始实例启动的(我将其称为“新”实例)。所以,这是例程:
- 您创建元模型
- 您生成
.genmodel
linked 到您的元模型
- 您生成元模型代码
- 您从原始实例启动“新”eclipse 实例
- 您通过
file->new->other->Example Model EMF Creation Wizard->your_stuff
向导创建您的模型
现在,您的模型已创建并且您的元模型已在全局注册表中注册,因此 Acceleo 文件可以很好地编译并且您的模型将被任何 EMF 兼容应用程序 openeable/readeable 无需额外工作。这个方法比较长,但是也是最简单的。
如果您只想处理一个 Eclipse 实例并且生成了元模型代码,您也可以执行此操作:
- Link 你的 acceleo 项目到你的元模型项目
- 修改Acceleo生成的java文件,在
registerPackages
方法中添加:
resourceSet.getPackageRegistry().put(SomethingPackage.eINSTANCE.getNsURI(), SomethingPackage.eINSTANCE);
这将注册您的元模型并且 Acceleo 转换应该 运行 没有任何问题。但是,如果您 link 您的 Acceleo 项目到您的元模型项目,我不确定是否需要此手动步骤。我认为如果元模型项目在同一个工作区中,Acceleo 可以自己处理元模型(但以防万一,您可以手动处理)。
动态实例
在您描述的情况下,您正在处理动态实例。这意味着没有生成元模型代码。 ATL 可以处理动态实例,这就是您能够生成 .xmi
的原因。顺便说一下,您可以通过打开您的元模型创建一个 .xmi
,select 您的根 EClass 并单击 right_click->Create dynamic instance...
。
如果你想处理这种类型的实例,你必须为 Acceleo 手动注册你的元模型。为此,您必须修改 Acceleo 生成的 java 文件并将其添加到 registerPackages 方法中:
File file = new File("path/to/your/metamodel.ecore");
EObject obj = ModelUtils.load(file, resourceSet);
resourceSet.getPackageRegistry().put("metamodel_ns_uri", obj);
(ModelUtils
来自 org.eclipse.acceleo.common.utils
)
使用它,您可以使用动态实例从 Acceleo 生成代码。
此外,关于 Acceleo,如果您的 RESTfulServicePSM
实例不会生成代码,您可以直接将 @main
注释直接放在 generateResourceModelClasses
模板上。 Acceleo 引擎将自行迭代每个 CSharpResourceModel
个实例。哦,你可以在许多模板上放置许多 @main
注释,它们将被评估 ;)。
编辑>
我刚刚看到你的问题已经解决了,我应该看看。很抱歉 post.
简而言之,您需要 'Generate Model code' 使用 .genmodel。
首先,我是 eclipse 的建模功能的新手,所以这个问题可能是微不足道的,但我已经搜索了好几天都没有找到答案。
我已经使用 ecore 建模项目创建了一个 ecore 元模型文件。 URI 是这样的:/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore
我还生成了(通过 ATL 转换)一个 xmi 模型文件。第一个元素是这样的:
<?xml version="1.0" encoding="ISO-8859-1"?>
<RESTfulServicePSM
xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns="/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore"
name="WSAT">
在 ATL 项目中,一切都按预期工作。
现在我需要使用 Acceleo 创建 M2T 转换。所以对于初学者来说,我创建了两个模块,一个 main :
[comment encoding = UTF-8 /]
[module PsmToCode('/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore')]
[import org::eclipse::acceleo::psm2code::files::ResourceModelClasses/]
[template public PsmToCode(aRESTfulServicePSM : RESTfulServicePSM)]
[comment @main/]
[for ( aCSharpResourceModel : CSharpResourceModel | aRESTfulServicePSM.hasCSharpRModel)]
[aCSharpResourceModel.generateResourceModelClasses()/]
[/for]
[/template]
还有一个:
[comment encoding = UTF-8 /]
[module ResourceModelClasses('/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore')]
[template public generateResourceModelClasses(aCSharpResourceModel : CSharpResourceModel)]
[file (aCSharpResourceModel.parentName.toUpperFirst().concat('.cs'), false, 'UTF-8')]
[/file]
[/template]
当我 运行 这个时,我得到一个 Package with uri '/com.auth.dotnetPSM.PSMmodel/model/PSMMetamodel.ecore' not found. (file:/H:/Users/doumas/workspace/PIM2PSM/WSATPSM.xmi, 6, 15)
异常。我做错了什么?
提前致谢。
您的元模型可能有 .ecore
,但您没有生成元模型代码(使用 .genmodel
)。当您尝试使用 EMF 工具(Acceleo/QVT...等)打开 .xmi
文件时,会出现您遇到的错误。所以,这里有很多要点 ;).
您可以处理元模型的静态或动态实例。
静态实例
静态实例是在您生成元模型代码(使用 .genmodel
)、将项目注册为插件并创建符合已部署元模型的模型时生成的。在这种情况下,您的元模型被部署为 Eclipse 插件,并且当该插件被 Eclipse 加载时,您的元模型在全局注册表中注册。在您的开发模式例程中,定义元模型并围绕它开发内容的最简单方法是处理两个 eclipse 实例。第一个(我将其称为“原始”实例)是您的元模型项目所在的实例。第二个是通过 run new eclipse configuration
菜单从原始实例启动的(我将其称为“新”实例)。所以,这是例程:
- 您创建元模型
- 您生成
.genmodel
linked 到您的元模型 - 您生成元模型代码
- 您从原始实例启动“新”eclipse 实例
- 您通过
file->new->other->Example Model EMF Creation Wizard->your_stuff
向导创建您的模型
现在,您的模型已创建并且您的元模型已在全局注册表中注册,因此 Acceleo 文件可以很好地编译并且您的模型将被任何 EMF 兼容应用程序 openeable/readeable 无需额外工作。这个方法比较长,但是也是最简单的。
如果您只想处理一个 Eclipse 实例并且生成了元模型代码,您也可以执行此操作:
- Link 你的 acceleo 项目到你的元模型项目
- 修改Acceleo生成的java文件,在
registerPackages
方法中添加:resourceSet.getPackageRegistry().put(SomethingPackage.eINSTANCE.getNsURI(), SomethingPackage.eINSTANCE);
这将注册您的元模型并且 Acceleo 转换应该 运行 没有任何问题。但是,如果您 link 您的 Acceleo 项目到您的元模型项目,我不确定是否需要此手动步骤。我认为如果元模型项目在同一个工作区中,Acceleo 可以自己处理元模型(但以防万一,您可以手动处理)。
动态实例
在您描述的情况下,您正在处理动态实例。这意味着没有生成元模型代码。 ATL 可以处理动态实例,这就是您能够生成 .xmi
的原因。顺便说一下,您可以通过打开您的元模型创建一个 .xmi
,select 您的根 EClass 并单击 right_click->Create dynamic instance...
。
如果你想处理这种类型的实例,你必须为 Acceleo 手动注册你的元模型。为此,您必须修改 Acceleo 生成的 java 文件并将其添加到 registerPackages 方法中:
File file = new File("path/to/your/metamodel.ecore");
EObject obj = ModelUtils.load(file, resourceSet);
resourceSet.getPackageRegistry().put("metamodel_ns_uri", obj);
(ModelUtils
来自 org.eclipse.acceleo.common.utils
)
使用它,您可以使用动态实例从 Acceleo 生成代码。
此外,关于 Acceleo,如果您的 RESTfulServicePSM
实例不会生成代码,您可以直接将 @main
注释直接放在 generateResourceModelClasses
模板上。 Acceleo 引擎将自行迭代每个 CSharpResourceModel
个实例。哦,你可以在许多模板上放置许多 @main
注释,它们将被评估 ;)。
编辑> 我刚刚看到你的问题已经解决了,我应该看看。很抱歉 post.
简而言之,您需要 'Generate Model code' 使用 .genmodel。