入力 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..*) 個の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);
}
それでも同じように動作します。
アップデート
このリンクでは、Acceleo と問題を再現する XText プロジェクトを含むサンプル EMF ワークスペースの zip ファイルが一時的に見つかります。奇妙なことに、Java アプリケーションとして実行すると動作しますが、Acceleo アプリケーションとして実行すると動作しません...
https://docs.google.com/open?id=0B2_ovo8IiZaZaXdNdFdPMTI4Yjg
左上隅に、zip ファイルをダウンロードできる [ファイル] メニューがあります。