2012-08-15 26 views
2

我正處於旨在從輸入UML模型生成代碼(即Java)的Acceleo Transformation中。使用Xtext對網格進行加速

這個UML模型的一些元素(即Activities Opaque actions)包含一些符合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/] 

它返回一個「無效」字符串。所以我不能在使用它的循環

因此,我試着撥打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: [email protected] 

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

    input: ['statement1;statement2'.getDSLModel().eAllContents()/] 
    output: [email protected] (...... 

UPDATE

對於主要Acceleo m的Java類odule我加入以下行

@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); 
} 

,但它仍然表現相同。

UPDATE

在這個環節你臨時發現含有Acceleo和XTEXT項目再現問題的示例EMF工作空間的壓縮文件。奇怪的是,如果你運行它作爲一個Java應用程序,它的工作原理,但如果你運行它作爲一個Acceleo應用它不...

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

在左上角,你應該找到一個文件菜單您可以從中下載該zip文件。

+0

您是否正確註冊了DSL的元模型?你在模塊的定義中使用它嗎? – sbegaudeau 2012-08-16 09:02:00

+0

我想我是,我已經更新了這個問題。包裝java服務的Acceleo模塊只使用DSLEcore,而主Acceleo模塊同時使用UML和DSLEcore – Sindico 2012-08-16 09:45:27

+0

可能問題在於我利用兩種不同的資源集:一種在Java服務中檢索Xtext文件,然後在Acceleo中運行?有沒有辦法從Java服務中檢索Acceleo當前資源集? – Sindico 2012-08-17 13:11:50

回答

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的應用程序,並且可以在獨立環境和插件環境中工作。

相關問題