【问题标题】:ATL transformation - empty outputATL 转换 - 空输出
【发布时间】:2014-04-03 15:07:54
【问题描述】:

我正在尝试将 XText 与 EMF 的 ATL 模型结合起来进行模型转换。 我正在阅读我的 DSL,将其转储到 EMF 的 XMI 资源中并放入 ATL api:ATL 不会给我任何错误并且可以正常运行:

Number of instructions executed: 38

无论我做什么,我的 OutModel (palData) 都保持为空 (null)。如果我从这里获取所有文件(hdl.ecore、pal.ecore、hdl.xmi)并将它们放入示例 ATL 项目中,我会得到正确的输出。

那么有什么神奇的参数需要我添加到 EMFVM 启动器上吗?

我的触发 ATL 的代码:

// create stuff
EMFModelFactory emfFactory = new EMFModelFactory();
XMIResourceFactoryImpl xmiFactory = new XMIResourceFactoryImpl();

EMFExtractor extractor = new EMFExtractor();
EMFInjector emfInjector = new EMFInjector();
ResourceSet resourceSet = new ResourceSetImpl();

// load model
EMFReferenceModel hdlMetaModel = (EMFReferenceModel) emfFactory.newReferenceModel();
emfInjector.inject(hdlMetaModel, resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/generated/Hdl.ecore"), true));
EMFModel hdlData = (EMFModel) emfFactory.newModel(hdlMetaModel);

EMFReferenceModel palMetaModel = (EMFReferenceModel) emfFactory.newReferenceModel();
emfInjector.inject(palMetaModel, resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/Pal.ecore"), true));
EMFModel palData = (EMFModel) emfFactory.newModel(palMetaModel);
palData.setIsTarget(true);

// load xtext content, convert to xmi
Resource xmiResource = xmiFactory.createResource(URI.createURI("org.xtext.hal/model/generated/Hdl.xmi"));
xmiResource.getContents().addAll(hdlModel.getContents());
emfInjector.inject(hdlData, xmiResource);

// ATL transformation
InputStream asm = new FileInputStream("org.xtext.hal/model/Pal.asm");
EMFVMLauncher launcher = new EMFVMLauncher();

HashMap<String,Object> options = new HashMap<String,Object>();
options.put("showSummary", "true");
options.put("step", "true");

launcher.initialize(Collections.<String, Object> emptyMap());
launcher.addInModel(hdlData, "IN", "hdl");
launcher.addOutModel(palData, "OUT", "pal");
launcher.launch(ILauncher.DEBUG_MODE, new NullProgressMonitor(), options, asm);

// get output
Resource t_palData = palData.getResource();
t_palData.setURI(URI.createURI("palData.xmi")); // Exception in thread "main" java.lang.NullPointerException
t_palData.save(null);

我在这里 ATL:

-- @path hdl=/org.xtext.hal/model/generated/Hdl.ecore
-- @path pal=/org.xtext.hal/model/Pal.ecore

module HDL2PAL;
create OUT : pal from IN : hdl;

rule Foobar
{
  from
    s : hdl!Model
  to
    t : pal!AddressSpace (
      name <- s.name
    )
}

HDL.ecore(输入元模型):

<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="hdl" nsURI="http://www.xtext.org/hal/Hdl" nsPrefix="hdl">
  <eClassifiers xsi:type="ecore:EClass" name="Model">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
</ecore:EPackage>

PAL.ecore(输出元模型):

<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="pal" nsURI="http://www.xtext.org/hal/Pal" nsPrefix="pal">
  <eClassifiers xsi:type="ecore:EClass" name="AddressSpace">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
</ecore:EPackage>

输入的模型数据:

<?xml version="1.0" encoding="ASCII"?>
<hdl:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:hdl="http://www.xtext.org/hal/Hdl" name="bar"/>

ATL 示例项目的输出:

<?xml version="1.0" encoding="ISO-8859-1"?>
<pal:AddressSpace xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:pal="http://www.xtext.org/hal/Pal" name="bar"/>

ATL assambler 的输出:

main:0  getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:1  push OclParametrizedType
  stack: HDL2PAL : ASMModule, 'OclParametrizedType'
  locals: self=HDL2PAL : ASMModule
main:2  push #native
  stack: HDL2PAL : ASMModule, 'OclParametrizedType', '#native'
  locals: self=HDL2PAL : ASMModule
main:3  new
  stack: HDL2PAL : ASMModule, <unnamed>(null)
  locals: self=HDL2PAL : ASMModule
main:4  dup
  stack: HDL2PAL : ASMModule, <unnamed>(null), <unnamed>(null)
  locals: self=HDL2PAL : ASMModule
main:5  push Collection
  stack: HDL2PAL : ASMModule, <unnamed>(null), <unnamed>(null), 'Collection'
  locals: self=HDL2PAL : ASMModule
main:6  pcall J.setName(S):V
  locals: self=HDL2PAL : ASMModule  Calling <unnamed>(null).setName('Collection')
  stack: HDL2PAL : ASMModule, Collection(null)
  locals: self=HDL2PAL : ASMModule
main:7  dup
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null)
  locals: self=HDL2PAL : ASMModule
main:8  push OclSimpleType
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), 'OclSimpleType'
  locals: self=HDL2PAL : ASMModule
main:9  push #native
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), 'OclSimpleType', '#native'
  locals: self=HDL2PAL : ASMModule
main:10 new
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), <unnamed>
  locals: self=HDL2PAL : ASMModule
main:11 dup
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), <unnamed>, <unnamed>
  locals: self=HDL2PAL : ASMModule
main:12 push OclAny
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), <unnamed>, <unnamed>, 'OclAny'
  locals: self=HDL2PAL : ASMModule
main:13 pcall J.setName(S):V
  locals: self=HDL2PAL : ASMModule  Calling <unnamed>.setName('OclAny')
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), OclAny
  locals: self=HDL2PAL : ASMModule
main:14 pcall J.setElementType(J):V
  locals: self=HDL2PAL : ASMModule  Calling Collection(null).setElementType(OclAny)
  stack: HDL2PAL : ASMModule, Collection(OclAny)
  locals: self=HDL2PAL : ASMModule
main:15 set col
  stack: 
  locals: self=HDL2PAL : ASMModule
main:16 getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:17 push TransientLinkSet
  stack: HDL2PAL : ASMModule, 'TransientLinkSet'
  locals: self=HDL2PAL : ASMModule
main:18 push #native
  stack: HDL2PAL : ASMModule, 'TransientLinkSet', '#native'
  locals: self=HDL2PAL : ASMModule
main:19 new
  stack: HDL2PAL : ASMModule, TransientLinkSet {}
  locals: self=HDL2PAL : ASMModule
main:20 set links
  stack: 
  locals: self=HDL2PAL : ASMModule
main:21 getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:22 pcall A.__matcher__():V
  locals: self=HDL2PAL : ASMModule  Calling HDL2PAL : ASMModule.__matcher__()


__matcher__:0   getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
__matcher__:1   pcall A.__matchFoobar():V
  locals: self=HDL2PAL : ASMModule  Calling HDL2PAL : ASMModule.__matchFoobar()
__matchFoobar:0 push Model
  stack: 'Model'
  locals: self=HDL2PAL : ASMModule
__matchFoobar:1 push hdl
  stack: 'Model', 'hdl'
  locals: self=HDL2PAL : ASMModule
__matchFoobar:2 findme
  stack: hdl!Model
  locals: self=HDL2PAL : ASMModule
__matchFoobar:3 push IN
  stack: hdl!Model, 'IN'
  locals: self=HDL2PAL : ASMModule
__matchFoobar:4 call MMOF!Classifier;.allInstancesFrom(S):QJ
  locals: self=HDL2PAL : ASMModule  Calling hdl!Model.allInstancesFrom('IN')
  stack: OrderedSet {}
  locals: self=HDL2PAL : ASMModule
__matchFoobar:5 iterate
  stack: 
  locals: 
  stack: 
  locals: 
  stack: 
  locals: self=HDL2PAL : ASMModule


main:23 getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:24 pcall A.__exec__():V
  locals: self=HDL2PAL : ASMModule  Calling HDL2PAL : ASMModule.__exec__()
__exec__:0  getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
__exec__:1  get links
  stack: TransientLinkSet {}
  locals: self=HDL2PAL : ASMModule
__exec__:2  push Foobar
  stack: TransientLinkSet {}, 'Foobar'
  locals: self=HDL2PAL : ASMModule
__exec__:3  call NTransientLinkSet;.getLinksByRule(S):QNTransientLink;
  locals: self=HDL2PAL : ASMModule  Calling TransientLinkSet {}.getLinksByRule('Foobar')
  stack: []
  locals: self=HDL2PAL : ASMModule
__exec__:4  iterate
  stack: 
  locals: 
  stack: 
  locals: 

【问题讨论】:

    标签: java xtext emf eclipse-atl


    【解决方案1】:

    您正在从文件加载 HDL 元模型加载您的模型:

    EMFReferenceModel hdlMetaModel = (EMFReferenceModel) emfFactory.newReferenceModel(); emfInjector.inject(hdlMetaModel, resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/generated/Hdl.ecore"), true));

    现有的“hdlModel”将包含链接到其他 EClass 实例的 EObject,而不是那些由您加载到“hdlMetaModel”中的实例。因此,如果 ATL 试图确定“hdl!Model”的所有实例,它不会找到任何东西:真正的实例指的是“hdl!Model”的另一个版本。解决方案是获取 xText 加载的 HDL 元模型的预加载版本。

    附:大多数关于 ATL 的支持讨论都在 the ATL forum 进行。您可能想在那里继续讨论。

    【讨论】:

    • 谢谢。这可能是一个提示。但是我怎样才能选择正确的实例?我尝试从原始 resourceSetProvider 获取(模型和元模型): emfInjector.inject(hdlMetaModel, resourceSetProvider.get().getResource(URI.createURI("org.xtext.hal/model/generated/Hdl.ecore"),真的));资源资源 = resourceSetProvider.get().getResource(URI.createURI("hdlData.hdl"), true);但没有运气。
    • 嘿 dwagelaar 你介意看看stackoverflow.com/questions/37196593/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 2014-05-19
    • 2015-03-18
    • 2017-02-06
    • 2011-09-07
    • 2019-10-02
    相关资源
    最近更新 更多