我正在进行一项旨在从输入 UML 模型生成代码(即 Java)的 Acceleo 转换。
这个 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
s(这是一种简化)。在 Acceleo 中,我从包含正确 DSL 脚本的字符串调用包装器时,我注意到它正确返回了ModelImpl
.
['statement1;statement2'.getDSLModel()/]
所以 Java 服务和 Xtext 解析正在工作。
但是,如果我尝试获取模型语句,即:
['statement1;statement2'.getDSLModel().statements/]
它返回一个“无效”字符串。所以我不能在 for 循环中使用它
因此,我尝试从模型实例调用 eAllContents() OCL 服务,即:
['statement1;statement2'.getDSLModel().eAllContents()/]
它实际上返回语句列表。我不明白为什么从 Xtext 解析器返回的 Ecore 实体的功能不能正常工作。
这是将字符串转换为我的 DSL 模型(Ecore AST)实例的 Java 服务。我已经用一个独立的 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);
}
但它的行为仍然相同。
更新
在此链接中,您可以临时找到一个示例 EMF 工作区的压缩文件,其中包含一个 Acceleo 和一个重现该问题的 XText 项目。奇怪的是,如果你将它作为 Java 应用程序运行,它可以工作,但如果你将它作为 Acceleo 应用程序运行,它就不会......
https://docs.google.com/open?id=0B2_ovo8IiZaZaXdNdFdPMTI4Yjg
在左上角,您应该找到一个文件菜单,您可以从中下载 zip 文件。