2

入力 UML モデルからコード (つまり Java) を生成することを目的とした Acceleo 変換の最中です。

この UML モデルの一部の要素 (つまり、Activities Opaque アクション) には、Xtext 文法に準拠したテキストが含まれており、Acceleo 変換で同等の AST Ecore 表現を取得したいと考えています。

この目的のために、DSL の抜粋を含む文字列を入力として受け取り、それに準拠した Ecore モデルを生成するメソッドを備えた Java クラスを開発しました ( http://www.eclipse.org/forums/index.php/を参照)。詳しくはm/901947/#msg_901947をご覧ください)。別の Java アプリケーションでテストしたところ、正しく動作しているようです。

したがって、単純な Acceleo モジュール (つまり getDSLModel) を作成し、その Java クラスをラップして、DSL テキスト表現から Ecore モデルを取得できるようにしました。

私の DSL (および同等の Ecore)DSLModelが、(0..*) 個のDSLStatements を含むという名前のルート要素で構成されているとします (これは単純化したものです)。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);
}

それでも同じように動作します。

アップデート

このリンクでは、Acceleo と問題を再現する XText プロジェクトを含むサンプル EMF ワークスペースの zip ファイルが一時的に見つかります。奇妙なことに、Java アプリケーションとして実行すると動作しますが、Acceleo アプリケーションとして実行すると動作しません...

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

左上隅に、zip ファイルをダウンロードできる [ファイル] メニューがあります。

4

1 に答える 1

1

残念ながら、私はXtextにあまり詳しくありません...しかし、あなたの問題は、Javaサービス内からDSLをロードする方法にあると思います:実行中のEclipse(「acceleoアプリケーション」)のコンテキストで生成していますが、ロードしますスタンドアロンの場合と同じようにモデル:新しいDSLStandaloneSetup、createInjector ...

モデルをロードするこの方法では、Xtextメタモデルとファクトリの2つのインスタンスが提供され、値を取得しようとしたときにOCLが機能の「ステートメント」を取得できなくなると思います。

これを回避するために考えられる1つの方法は、サービスを変更して、任意の種類のEObjectをパラメーターとして受け取り、そのリソースセットを使用してdslをロードすることです(したがって、ランチャーで初期化したリソースセットを使用します。 Acceleoはあなた自身の代わりに使用します):

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

これで、サービスから2回目のXtext初期化を行う必要はありません...それがうまくいかない場合は、Xtextフォーラムにアクセスして、作成方法を尋ねる以外に、提案する解決策はありません。 DSLをロードし、スタンドアロン環境とプラグイン環境の両方で動作できるアプリケーション。

于 2012-08-21T07:33:04.403 に答える