使用Xtext进行网格加速

时间:2012-08-15 09:18:17

标签: eclipse eclipse-emf xtext acceleo

我正处于Acceleo Transformation的中间,旨在从输入UML模型生成代码(即Java)。

这个UML模型的一些元素(即活动不透明动作)包含一些符合Xtext语法的文本,我想在Acceleo转换中获得等效的AST Ecore表示。

为此,我开发了一个Java类,其中包含一个方法,该方法将包含DSL摘录的字符串作为输入,并生成符合它的Ecore模型(有关详细信息,请参阅http://www.eclipse.org/forums/index.php/m/901947/#msg_901947)。我在一个单独的Java应用程序中对它进行了测试,看起来它运行正常。

因此我编写了一个简单的Acceleo模块(即getDSLModel)来包装该java类,并使我能够从DSL文本表示中获取Ecore模型。

假设我的DSL(和等效的Ecore)由名为DSLModel的根元素组成,其中包含{0 .. *)个DSLStatement个(这是一个简化)。 在Acceleo中,我从包含正确DSL脚本的字符串调用包装器时,我注意到它正确返回ModelImpl

    ['statement1;statement2'.getDSLModel()/]

所以Java服务和Xtext解析正在运行。

但是,如果我试图获得模型语句,即:

  ['statement1;statement2'.getDSLModel().statements/]

它返回“无效”字符串。所以我不能在for循环中使用它

因此,我尝试从模型实例调用eAllContents()OCL服务,即:。

  ['statement1;statement2'.getDSLModel().eAllContents()/]

它实际上返回了语句列表。我不明白为什么从Xtext解析器返回的Ecore实体的功能无法正常工作。


这是Java服务,它将字符串转换为我的DSL模型(Ecore AST)的实例。我已经使用独立的Java应用程序对其进行了测试,它运行正常!

 public class GetDSLModel {
 public DSLModel getDSLModel(String expression){    
    DSLStandaloneSetupGenerated dslsas = new DSLStandaloneSetupGenerated();
    Injector injector = dslsas.createInjectorAndDoEMFRegistration();
    XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
    resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
    Resource resource = resourceSet.createResource(URI.createURI("dummy:/example.dsl"));
    InputStream in = new ByteArrayInputStream(expression.getBytes());
    try {
        resource.load(in, resourceSet.getLoadOptions());
        DSLModel model = (DSLModel) resource.getContents().get(0);
        return model;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;

}

}

现在我需要在主要的Acceleo(UML2Text)转换中使用AST,因此这里是Acceleo包装器

 [query public getDSLModel(str:String): DSLModel =  (invoke('sfg.baleno.src.mloaders.GetDSLModel','getDSLModel(java.lang.String)',Sequence{str})).oclAsType(DSLModel)/]

这是我得到的,如果运行它

  input: ['statement1;statement2'.getDSLModel()/]
  output: mypackage.dsl.impl.DSLModelImpl@a1c7a

  input: ['statement1;statement2'.getDSLModel().statements/]  (Syntactically VALID)
  output: invalid

  input: ['statement1;statement2'.getDSLModel().eAllContents()/]
  output: mypackage.dsl.impl.DSLStatement@e53202 (......

更新

对于主要的Acceleo模块的Java类,我添加了以下行

 @Override
 public void initialize(EObject element, File folder, java.util.List<? extends Object> arguments) throws IOException {    preInitialize();
    super.initialize(element, folder, arguments);
}
@Override
public void initialize(URI modelURI, File folder, java.util.List<?> arguments) throws IOException {
    preInitialize();
    super.initialize(modelURI, folder, arguments);
}

protected void preInitialize() {
   DSLStandaloneSetup.doSetup();
}

  @Override
 public void registerPackages(ResourceSet resourceSet) {
    super.registerPackages(resourceSet);
   if (!isInWorkspace(org.eclipse.uml2.uml.UMLPackage.class)) {
         resourceSet.getPackageRegistry().put(org.eclipse.uml2.uml.UMLPackage.eINSTANCE.getNsURI(), org.eclipse.uml2.uml.UMLPackage.eINSTANCE);
    }
    if (!isInWorkspace(mypackages.DSLPackage.class)) {
        resourceSet.getPackageRegistry().put(mypackages.DSLPackage.eINSTANCE.getNsURI(), mypackages.DSLPackage.eINSTANCE);
     }
   EcoreUtil.resolveAll(resourceSet);
}

但它的行为仍然相同。

更新

在此链接中,您临时找到包含Acceleo和XText项目的示例EMF工作区的压缩文件,以再现该问题。奇怪的是,如果你将它作为Java应用程序运行它可以工作,但是如果你将它作为Acceleo应用程序运行它不会...

https://docs.google.com/open?id=0B2_ovo8IiZaZaXdNdFdPMTI4Yjg

在左上角,您应找到一个文件菜单,您可以从中下载zip文件。

1 个答案:

答案 0 :(得分:1)

我很遗憾不熟悉Xtext ...但我相信你的问题在于你从java服务中加载你的dsl的方式:你是在正在运行的Eclipse(“加速应用程序”)的上下文中生成的,然而你加载你的模型就好像你是独立的:新的DSLStandaloneSetup,createInjector ......

我相信这种加载模型的方式为您提供了两个Xtext元模型和工厂实例,使得当您尝试获取其值时,OCL无法检索功能“语句”。

我可以想到绕过这个的一种可能方法是更改​​您的服务以将任何类型的EObject作为参数并使用其资源集来加载您的dsl(因此使用您在启动器中初始化的资源集) ,一个Acceleo使用,而不是你自己的):

public DSLModel getDSLModel(String expression, EObject eObj){
    ResourceSet rSet = eObj.eResource().getResourceSet();
    [...]
}

有了这个,你不应该需要从服务中进行第二次Xtext初始化...如果它不起作用,我真的没有一个解决方案来提议除了去Xtext论坛并在那里问如何制作一个可以加载DSL并在独立和插件环境中工作的应用程序。