EMF は Eclipse プラットフォームに不可欠な部分であると同時に、Eclipse Visual Editor、SDO、XSD、そして UML といった関連技術およびフレームワーク (その多くは、Rational® Application Developer や WebSphere® Business Modeler などの IBM® プラットフォームに統合されています) の基礎でもあります。現在、EMF は列挙型、アノテーション、Generics をはじめとする Java 技術の機能を包含するまでに進化しました。EMF に馴染みのない方は、「参考文献」に記載されている入門者用の記事を参照してください。
EMF に関するほとんどのマニュアルやチュートリアルでは、振る舞いをモデル化するためにではなく、データとインターフェース (EMF リリース・ドキュメントでの Library と Books など) をモデル化するために EMF を使用しています。もちろんデータ・オブジェクトを対象に生成されたデフォルト・メソッド実装もありますが、これらの実装が扱っているのはモデル要素間の関係です。その上、Eclipse Foundation の記事「Modeling Rule-Based Systems with EMF」(「参考文献」を参照) は例外としても、「メタ・メタモデル」としての EMF の使用例はほとんど文書化されておらず、Ecore メタモデルの拡張方法を説明する例に至っては 1 つもありません。
また、EMF JET テンプレートを使用および拡張するプロセスも十分には文書化されていません。さらに、最近になって JET エディター・プロジェクトは別の Eclipse プロジェクト (M2T) に移行されました。そこで、この記事ではこうした内容について説明し、読者の皆さんが動的テンプレートを EMF との関連で一層活用できるようにしたいと思います。
Ecore メタモデルは、モデル駆動型アーキテクチャー (MDA) を設計する際の強力なツールで、ソフトウェア開発の出発点として使用することができます。一般に Ecore メタモデルで定義するのは、アプリケーションの領域でのオブジェクト (EClass 型)、オブジェクトの属性、そしてオブジェクト間の関係です。また、これらのオブジェクトに属する特定の操作も EOperation モデル要素を使って定義します。EMF はデフォルトで、これらの操作の「スケルトン」、つまりメソッド・シグニチャーを生成しますが、操作を実装するには Ecore メタモデルにまで戻る必要があり、同じようなロジックのコードを何度も作成することも珍しくありません。
一方、ある種の自由な実装の振る舞いをモデルに直に指定するという場合を考えてみてください。それには、テキスト・ベースのアノテーション (EAnnotation 型) をモデル・オブジェクトに追加し、コードの生成中にこれらのアノテーションをテンプレートで解釈するという方法があります。その好例は、Eclipse Foundation の記事「Implementing Model Integrity in EMF with MDT OCL」(「参考文献」を参照) に記載されています。しかし、その記事に記載されているようなモデル要素の妥当性の検証は、この記事で目的とするところではなく、この記事で目的とするのは、あらゆる具象モデルでメタモデル要素を再利用するために、実装自体をモデル化することです。この目的のためには、Ecore メタモデルを拡張する必要があります。
この記事で取り上げるのは、Ecore を拡張したモデルで、プログラムによる非常に単純化されたモデルです。このモデルは完全な、あるいは首尾一貫したメタモデルでもフレームワークでもなく、厳密には EMF によるコード実装のメタモデリングの可能性を示すことを目的としたプロトタイプ的な一連の要素でしかありません。図 1 に、この記事で使用する EcoreX というサンプル拡張メタモデルのスナップショットを記載します。この図に続いて、それぞれの要素を簡単に説明します。
図 1. EcoreX モデル
EPackageを拡張するEPackageX- この要素は、Ecore 要素である
EPackageの単純な「マーカー」拡張で、追加の属性はありません。この要素が必要となる理由は、デフォルトではEPackage要素に対応した EMF エディター・プラグインでEClassのサブクラスを子要素として追加することができないためです (この後のEClassXを参照)。EPackageを拡張するモデル要素を提供すると、EPackageXにEClassX子要素を追加することのできるコードが自動的に生成されることになります。
EClassを拡張するEClassX- 同じくこの要素も Ecore 要素である
EClassの単純な「マーカー」拡張で、追加の属性はありません。この要素が必要となるのは、上記の要素と同じく、EClassのエディター・プラグインではこの記事が目的とするEOperationのサブクラスをデフォルトでは追加することができないためです。
EOperationを拡張するEOperationImpl- これは基本エンティティーであり、具体的なメタ機能を Ecore モデルに追加するためのエントリー・ポイントとなります。この要素は、Ecore の基本
EOperation要素には存在しない属性で参照されます。以下に説明するすべての要素はこのEOperationImplに属し、プログラムによる実装を構成するために使用されます。例えば、EOperationImplには変数とステートメントがあり、参照または値を返すことが可能です。
ETypedElementを拡張するLocalVariableLocalVariableはローカル・スコープを持つ変数です。変数には名前と Java の型 (String、Integer、Objectなど) があります。これらの属性は変数のスーパー・スーパークラスであるEParameterにすでに存在するため、LocalVariableに必要な追加属性はありません。
EClassを拡張するStatement- この単純化されたサンプル・ロジック・モデルでは、
EOperationImplに含まれる多数のstatementは、一定の順序で評価されます。Statement は抽象スーパークラスです。
Statementを拡張するLiteralAssignment- 変数を参照する
LiteralAssignmentには、String属性があります。ユーザーはこの属性に、解析されて変数に割り当てられる値を入力することができます (例えば、「hello」、「4.5」をそれぞれString、floatに割り当てることができます)。
Statementを拡張するAccessAccessは、Java フィールドまたは操作を参照する動作表します。
Accessを拡張するFieldReferenceAssignment- フィールドにアクセスして値を割り当てます (例えば、
var1 = var2.name)。
Accessを拡張するInvoke- 操作 (Java メソッド) を呼び出します。呼び出し (
Invoke) の結果は、変数に割り当てることができます (例えば、myVar = obj.toString())。
図 2 に、UML 風の表現で EcoreX メタモデルを図解します。
図 2. EcoreX モデル図
この記事のステップは、大まかに以下の 2 つに分けられます。
- メタモデルの構築
- 具象モデルの構築
上記で説明したメタモデルは、作成することも、インポートすることもできます。いずれの場合にしても、まずは既存の Java プロジェクトから手順を開始しなければなりません。既存の Java プロジェクトがなければ、新しく作成してください。この記事では、EMFX という名前の Java プロジェクトを使用します。プロジェクトには model という名前のフォルダーが必要です。EcoreX.ecore モデル (「参考文献」を参照) を model ディレクトリーにコピーして「Editor Metamodel プラグインをビルドして起動する」のセクションまでスキップするか、または以下のステップに従ってメタモデルを一から作成しなおしてください。
プロジェクトを右クリックし、コンテキスト・メニューから New > Other > Example EMF Model Creation Wizards > Ecore Model (Eclipse V3.5 以降 (Galileo、Helios) では、New > Other > Eclipse Modeling Framework > Ecore Model) を選択します。フォルダーには model フォルダーを選択し、名前には EcoreX.ecore と入力してください。
デフォルトのモデル・パッケージの名前は ecorex です。モデル・ウィンドウで右クリックして Load Resource > Browse Registered Packages の順に選択します。名前空間が http://www.eclipse.org/emf/2002/Ecore となっている Ecore モデルを選択します。
Ecore メタモデルのインポートが完了したら早速、モデルの拡張に取り掛かれます。まず、ecorex.ecore モデルを再作成するために、パッケージ要素 ecorex を右クリックして New Child > EClass を選択してください。この要素は EPackageX という名前にします (上記のモデル要素の説明を参照してください)。次に必要な作業は、基本要素 EPackage をこの新しい EpackageX 要素の ESuper Type として追加することです。
同じ手順に従って、EClass を今度は ESuperType として指定して新規要素 EClassX を作成します。引き続き必要に応じて Ecore オブジェクトをサブクラス化し、EcoreX モデルに他の EClass を定義します。どの属性でどの EClass を作成するかについて確認するには、図 1 と EcoreX.ecore ファイルを参照してください。
ビルド・ステップでは、genmodel メタモデルを作成し、モデルとエディター・プロジェクトをビルドします。まず、EcoreX モデルを右クリックして New > Other > Eclipse Modeling Framework > EMF Model (Eclipse V3.5 以降 (Galileo、Helios) では、New > Other > Eclipse Modeling Framework > EMF Generator Model) の順に選択してください。モデル名は自分で指定するのでも、デフォルト名の EcoreX.genmodel をそのまま使用するのでも構いません。genmodel の基本モデルには、EcoreX モデルが事前に選択されているはずです。Load をクリックして EcoreX.ecore メタモデルの妥当性を検証します。
図 3. 新規 EMF モデル
生成するパッケージと他のジェネレーター・モデルから参照させるパッケージを指定するように求められたら、Root packages では EcoreX パッケージ、Referenced generator models では Ecore を選択します。
この時点で、ウィザードはメタモデルの genmodel を作成します。これで、genmodel の最上位レベルの要素を強調表示してからコンテキスト・メニューで Generate All を選択することによって、関連するコードを自動生成できるようになります。生成されるのは、genmodel に構成された振る舞いに応じた 4 つの Eclipse プロジェクトです。この記事では .test プロジェクトについては取り上げないので、このプラグインに関しては生成しなくても構いません。
ここからは、起動ステップに移ります。ほとんどの Eclipse チュートリアルでは、開発したプラグインを別の Eclipse プロセスで起動するように指示していますが、このセクションではそれとは異なる方法を取ります。ここでは、プラグインを現行の Eclipse およびワークスペース内で有効にします。こうすることによって、次のセクションで、事前に構築されたメタモデルと具象モデル開発を統合しやすくなるからです。以下のステップに従って、プラグインを有効にしてください。
- EMFX plugin.xml をダブルクリックしてプラグイン構成エディターを開きます。
- Exporting タブで Export Wizard をクリックします。
- 基本モデリング・プラグインと 2 つのエディター・プラグインを選択します。
- Destination タブで Eclipse のインストール・ディレクトリーを選択します。
図 4. Export ウィザード
Finish をクリックすると、自動的に生成済みプラグインの JAR がビルドされて plugins ディレクトリーにコピーされます。この時点で、Eclipse を再起動して新規プラグインを有効にしてください。プラグインが有効になったら、具象モデル (ここでの名前は Test2) を保持するための新規プロジェクトを作成するとエディター・プラグインが起動されるようになります。
この新規プロジェクト内で New > Other > Example EMF Model Creation Wizards > Ecorex Model にナビゲートし、モデル名を指定します。EPackageX 要素を選択すると、空の具象モデルが作成されます。
このセクションでは、具象 Java クラス (EClassX のインスタンス) をモデル化し、このクラスが持つ 2 つの具象メソッドの実装をモデル化します。最初のサンプル・メソッドは String パラメーター・メッセージを取り、このメッセージをタイムスタンプ付きで出力します (こうすると、例えばメッセージをデバッグする際に役立ちます)。目的とする出力結果は以下のとおりです。
リスト 1.
printTimestampMessage
void printTimestampMessage(String message) {
System.out.print(message);
System.out.print("; Timestamp= ");
System.out.println(System.currentTimeMillis());
}
|
2 つ目のサンプル・メソッドは日付に基づく 3 つのパラメーターを取り、その日付の曜日を表す 1 つの数値を返します。
リスト 2.
getDayOfWeek
int getDayOfWeek(int year, int month, int date) {
int result;
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, date);
result = calendar.get(Calendar.DAY_OF_WEEK);
return result;
}
|
最初のステップは、前のセクションの最後のステップで作成した新規 EPackageX 要素で 3 つの必須属性を入力することです。モデリング・ウィンドウの下に Properties タブが表示されていない場合は、コンテキスト・メニューから Show Properties View を選択してください。このサンプルでのパッケージ名は、mypackage とします。
図 5. EPackageX プロパティー
次に、新規 EClassX を mypackage に追加します。それには、mypackage が強調表示された状態でコンテキスト・メニューを使用します。name 属性を入力してクラスに名前 (例えば、MyClass) を指定し、この新規クラスに 2 つの EOperationImpl 要素を追加して上記の printTimeStampMessage と getDayofWeek というメソッド名を指定します。続いて、操作ごとに Ecore パラメーターを追加します。
図 6.
EOperationImpl getDayOfWeek()
図 7.
getDayOfWeek() プロパティー
上記の printTimestampMessage() 操作では EString 型のパラメーターを 1 つ取り、getDayOfWeek() 操作では EInt 型のパラメーターを 3 つ取ります。さらに getDayOfWeek 操作は、EType プロパティー属性で構成された EInt を返します (図 7 を参照)。
これまでは継承された Ecore 要素と属性のみを扱っていましたが、ここからは拡張したメタモデル要素を使って Java 実装をビルドします。
LocalVariable- 図 8 を見るとわかるように、
printTimestampMessage()に必要な 2 つのLocalVariable要素の型は、EStringとELongです。
図 8.
printTimestampMessage()
図 9.
LiteralAssignment
図 9 の Value 属性のストリングは LiteralAssignment にインライン化されています。別のメタモデルでは、リテラル値 (定数) がそれぞれ個別の要素としてモデル化される場合も当然あります。
次に LiteralAssignment 型の要素を挿入します。この要素によって、LocalVariable を選択してそれに値を割り当てることが可能になります。この例では String 変数を選択し、上記のプロトタイプ・メソッドからのテキスト値を提供します (テキストを囲む引用符を忘れずに含めてください)。
-
DataType - 上記の図をもう一度見て、
SystemTypeというEcore DataTypeがあることに注目してください。これは java.lang.System のラッパーです。これをmypackageパッケージに含める必要があるのは、その後に続くInvoke要素がこのラッパーを参照するためです。
Statement- この操作に追加する最初の
Statementは、上記で定義したSystemTypeでの静的メソッド、currentTimeMillis()の呼び出し (Invoke) です。
図 10.
currentTimeMillis() プロパティーの呼び出し
このメタモデルでは (次のセクションでコード・テンプレートを提供した上で)、上記の Invoke は timestamp = java.lang.System.currentTimeMillis(); という Java ステートメントに変換されることになります。
次に追加する Invoke は前のものとは微妙に違います。まず第一に、Assignment がありません。第二に、message パラメーターを Args というプロパティーの引数として参照します。
図 11.
out.print プロパティーの呼び出し
Access Name プロパティーの値が out.print となっていることにも注目してください。実は、ここでは Java System から out フィールドを逆参照してから print メソッドを呼び出しています。FieldReferenceAssignment を PrintStream 型の LocalVariable と併せて使用する代わりに、今のところはこのショートカットを使用します。
この操作に追加する 3 つ目かつ最後の Invoke は、LocalVariable timestamp を唯一の引数として使用する println() です。これで、printTimestampMessage() 操作の具象モデルが完成します。
次に、2 つ目の EOperationImpl getDayOfWeek() の完全なモデルを見てみましょう。
図 12.
getDayOfWeek()
DataTypes- このモデルの一番下には、この操作に必要な追加 DataType として作成した
CalendarTypeがあります。
LocalVariable- この操作モデルに含まれる 3 つの
LocalVariableのうち、特に重要なのはresultです。操作の最後のステートメントの後に返される値は、このローカル変数が保持するためです。EOperationImplプロパティーの 1 つとしてReturn Refというプロパティーがあります。実装では、このプロパティーとしてプルダウン・メニューを使ってLocalVariableのresultを選択します。
Statement- 図 12 を見るとわかるように、3 つの
LocalVariableの後には 3 つのStatementが続いています。最初のInvokeはCalendarType要素のgetInstance()を使用し、それによって値をcalendar変数に割り当てます。これは図 10 での実行内容と似ています。
その次にあるのは calendar 変数の set() メソッドの Invoke で、EOperationImpl パラメーターに対応する year、month、date という 3 つの Arg を渡します。
図 13. パラメーターを使用した
set()
図 14.
FieldReferenceAssignment
メタモデルでは、この要素は DAY = Calendar.DAY_OF_WEEK; のような Java コードになります。
図 15 では、EOperationImpl の最後の Invoke で DAY 変数が使用されています。get() の戻り値が、result 変数 (この実装の Return Ref) に割り当てられます。
図 15.
Return Ref
これまでのところで、拡張メタモデルを設計し、それを使って My.ecorex という具象モデルを記述しました。今度はいよいよ、JET を使ってコード実装を生成する番です。JET テンプレート構文の特徴を調べるためには、JET エディター・プラグインをインストールする必要があります (「参考文献」および「Jet エディターの制約事項」を参照)。
デフォルトでは、EMF はモデルのコードを生成する際に動的テンプレートを使用しません。EMF が使用するのは事前ビルドされた Java クラスです。JET テンプレートのカスタマイズに取り掛かるには、プラグイン JAR の org.eclipse.emf.codegen.ecore_2.3.0.XYZ.jar (ここで、XYZ は Eclipse plugins フォルダーに含まれる EMF ビルドのタイムスタンプ) からコピーしなければならないファイルがいくつかあります。この記事で使用するのは org.eclipse.emf.codegen.ecore_2.3.0.v200706262000.jar です。ファイルをコピーするには、ZIP ユーティリティーで JAR ファイルを開き、以下の手順に従ってください。
- この JAR の templates ディレクトリーを具象モデル用の Java プロジェクトに解凍します。
- templates/model に Class という名前のディレクトリーを作成します。
- model フォルダーに、implementedGenOperation.TODO.override.javajetinc という名前の空のファイルを新規に作成するか、このファイルを「参考文献」からコピーします。
その名前からわかるように、ステップ 3 の新規ファイルは JET テンプレートです。これからこのテンプレートに、モデル・オブジェクト EOperationImpl のコード生成ロジックを配置します。このファイルはデフォルトでは存在しません。EMF は各 EOperation に対して単に空のメソッド・シグニチャーを提供するだけだからです。動的テンプレート機能を有効にすると、この新規ファイルは EOperationImpl の定義に従って自動的に Java メソッドの本文として組み込まれます。
implementedGenOperation.TODO.override.javajetinc の完全なコードは以下のとおりです。
リスト 3.
implementedGenOperation
// created by implementedGenOperation.TODO.override.javajetinc
<%
if ( ! (genOperation.getEcoreOperation() instanceof EOperationImpl) ) { %>
// TODO: implement this method
// Ensure that you remove @generated or mark it @generated NOT
throw
new UnsupportedOperationException();
<% } else { %>
// ** EOperationX implementation **
<% EOperationImpl opx = (EOperationImpl)genOperation.getEcoreOperation();
Statement stm = null;
Iterator iterator = null;
EList<LocalVariable> pList = opx.getLocalVariables();
LocalVariable lvar = null;
String iname = null;
StringBuffer paramsString = null;
StringBuffer varString = null;
for (int i = 0;i < pList.size(); i++) {
lvar = pList.get(i);
iname = lvar.getEType().getInstanceClassName();%>
<%=iname%>
<%=lvar.getName()%><%
if (iname.startsWith("java")) { %> = null
<% } %>;
<% }
iterator = opx.getStatements().iterator();
while (iterator.hasNext()) {
paramsString = new StringBuffer();
varString = new StringBuffer();
iname = null;
stm = (Statement)iterator.next();
if (stm instanceof LiteralAssignment) {%>
<%= stm.getAssignment().getName()%> = <%=\
((LiteralAssignment)stm).getValue()%>;
<%} else
//
if (stm instanceof FieldReferenceAssignment) {
Access ax = (Access)stm;
if (stm.getAssignment() != null) {
varString.append(stm.getAssignment().getName());
varString.append(" = ");
}
if ( ax.getStaticType() != null) {
// STATIC
iname = ax.getStaticType().getInstanceClassName();
} else {
// NON STATIC
iname = ax.getTarget().getName();
} %>
<%=varString.toString()%><%=iname%>.<%=ax.getAccessName()%>;
<% } else
if (stm instanceof Invoke) {
// INVOKE
Invoke iv = ((Invoke)stm);
if (stm.getAssignment() != null) {
varString.append(stm.getAssignment().getName());
varString.append(" = ");
}
for (int p = 0; p < iv.getArgs().size(); p++) {\
paramsString.append(iv.getArgs().get(p).getName());
if ( p + 1 < iv.getArgs().size() ) {
paramsString.append(" , ");
}
}
if (iv.getStaticType() != null) {
// STATIC
iname = iv.getStaticType().getInstanceClassName();
} else {
// NON STATIC
iname = iv.getTarget().getName();
} %>
<%=varString.toString()%><%=iname%>.<%=iv.getAccessName()\
%>(<%=paramsString.toString()%>);
<% }
} // STATEMENTS
if (opx.getReturnRef() != null) { %>
return
<%=opx.getReturnRef().getName()%>;
<% }
} // EOPERATIONIMPL %>
|
JET の詳細については、この記事では説明しませんが、JET テンプレートがこのプロセスに重要であることは明らかなので、擬似コードという点からこのテンプレートの中身を調べることにします。最初の変数、genOperation は、テンプレートが処理される前に Ecore/JET によってあらかじめ初期化されることを念頭に置いておいてください。
リスト 4.
Ecore/JET によって事前に初期化される genOperationIs this GenOperation is an EOperationImpl? If false, emit default UnsupportedOperationException STOP; Else, cast it to EOperationImpl; continue; Find and declare all elements of type LocalVariable, initializing Java Objects to null; Iterate through all Statements; Emit Java code according to the subtype; Does the implementation return something? If yes, emit the return statement; |
There are a few actions to perform before building the concrete model. First, at the top of templates/model/Class.javajet, we must add to the list of imports (the first two marked in bold):
<%@ jet package="org.eclipse.emf.codegen.ecore.templates.model" imports="ecorex.* org.eclipse.emf.common.util.* \ java.util.* org.eclipse.emf.codegen.ecore.genmodel.*"… |
具象モデルを構築する前に、いくつか行っておかなければならない作業があります。まず、templates/model/Class.javajet の先頭にインポートするファイルのリストを追加してください (最初の 2 つを太字で示しています)。
上記の EcoreX パッケージはもちろん、拡張したメタモデルです。次に、具象モデル (My.ecorex) の EMF (GenModel) を作成して構成します。それには、モデルを右クリックして New > Other > Eclipse Modeling Framework > EMF Model (Eclipse V3.5 以降 (Galileo、Helios) では、New > Other > Eclipse Modeling Framework > EMF Generator Model) の順に選択します。EMF モデルが作成されたら、Templates & Merge プロパティー・グループにある 3 つのプロパティーを以下のように構成してください。
図 16. GenModel - Templates & Merge
- Dynamic Templates は true に設定します。
- Template Directory を指定します。
- Template Plugin Variables に EMFX (拡張メタモデル・プラグイン ID) を追加します。
これで、具象モデルを構築する準備ができました。GenModel を右クリックして Generate Model Code を選択してください。すべてが上手くいくと、具象 Test プロジェクト (この例では Test2) のソース・フォルダー (src) に、生成された Java ソース・パッケージとクラスが表示されます。そのなかに含まれる mypackage.impl.MyClassImpl.java ファイルを開くと、2 つのメソッドが生成されているはずです。
リスト 5. MyClassImpl.java
public
void printTimestampMessage(String message) {
// created by implementedGenOperation.TODO.override.javajetinc
// ** EOperationX implementation **
java.lang.String timestampStr = null;
long timestamp;
timestampStr = "; Timestamp = ";
timestamp = java.lang.System.currentTimeMillis();
java.lang.System.out.print(message);
java.lang.System.out.print(timestampStr);
java.lang.System.out.println(timestamp);
}
public
int getDayOfWeek(int year, int month, int date) {
// created by implementedGenOperation.TODO.override.javajetinc
// ** EOperationX implementation **
int result;
int DAY;
java.util.Calendar calendar = null;
calendar = java.util.Calendar.getInstance();
calendar.set(year , month , date);
DAY = java.util.Calendar.DAY_OF_WEEK;
result = calendar.get(DAY);
return result;
}
|
このクラスをテストするには、main メソッドを追加してください。
JET テンプレートの構文を色分けして強調表示するには、Eclipse JET エディターがインストールされている必要があります (JET エディター・プラグインは最近、EMF から M2T に移行しました)。
ただし、この記事を執筆している時点では、最新バージョンの JET エディターは、ネストされた JET インクルード (.javajetinc ファイルなど) での Java コンテンツ・アシストやオンザフライでのコンパイルを正しく処理しません。さらに、インポートを指定できるのは親ファイル (上記の Class.javajet など) のみで、インクルード・ファイルで指定するとビルドが成功しません。
追加の構成を行うことによって (プロジェクトのコンテキスト・メニューを使用)、EMF 動的テンプレート・プロジェクト (この例では Test2) を JET プロジェクトに変換することは可能です。しかし実際には、上記の制約事項と併せ、EMF と M2T/JET が統合されていないことから、このような変換は現時点では非現実なものとなっています。
したがって、インクルードされたテンプレート・ファイルでエラーをキャッチして修正するのは困難な場合があります。JET テンプレートは最終コードが発行される前に、まず中間 Java ファイル (デフォルトでは JETEmitter という隠し Java プロジェクトに配置) にコンパイルされるため、Eclipse の Package Explorer ビューでのフィルター設定をしないことでコンパイル・エラーを確認することができます。エラーがテンプレート・ファイル内での純粋なフォーマットのエラーであれば、ビルド中に Eclipse のポップアップ・ウィンドウが表示されるはずです。JET の今後のリリースでは、より進化した機能を期待できると思います。
この記事の例では、EMF Validation Framework も OCL 機能も使用していません。そのため、モデル内に矛盾があるとモデルの構築は失敗します。例えば、EOperationImpl は特定の戻り型を宣言しているのに、Return Ref プロパティーが別の型を参照していたり、ヌルであったりするような場合、このようなエラーはモデルの構築中にはキャッチされないため、生成されたコードはコンパイルされません。進化したメタモデルでは、OCL (「参考文献」を参照) を使用して整合性および制約を強化することになるはずです。
この記事では、Ecore メタモデルを拡張して統合的な Java メソッド内での単純なプログラムによる振る舞いを概念化する方法について検討してきました。まずは Ecore 自体をインポートするという方法で、いくつもの Ecore モデル要素 (特に EOperation) を拡張し、それからメタモデルを構築しました。次にエディターを使用して、EOperationImpl という形でモデル化した 2 つの Java メソッドが含まれる具象テスト・モデルを設計しました。そして最後に、EOperationImpl のコードを生成するための JET テンプレートを構成してビルドしました。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Sample templates | os-eclipse-emfmetamodel.zip | 2KB | HTTP |
学ぶために
- Eclipse Foundation の記事「Using EMF」で、Eclipse Modelling Framework について紹介しています。
- Eclipse Foundation の記事「Modeling
Rule-Based Systems with EMF」では、ルール・ベース・システムのモデリングを対象とした ECore のメタモデルを定義しています。
- Eclipse Foundation の記事「Implementing
Model Integrity in EMF with MDT OCL」では、後からカスタム・コードを生成する必要のない Ecore 仕様によるモデルの生成方法を紹介しています。
- Eclipse Modeling Framework (EMF) には、あらゆる EMF 関連の資料とダウンロードが揃っています。
- Eclipse Foundation の Model To Text (M2T) は、JET を含め、モデルからテキスト成果物を生成することに重点を置いたプロジェクトです。
- Eclipse Modeling Framework Technology (EMFT) プロジェクトは、EMF 関連の技術を対象とした Eclipse のインキュベーション・プロジェクトです。
- EMF を使い始めるには developerWorks の連載記事、「Eclipse Modeling Framework でモデリング」を読んでください。第 1 回ではモデルからコードを生成する方法、第 2 回では JET (Java Emitter Templates) について、そして第 3 回では JET テンプレートの出力をカスタマイズする際に利用できる JMerge について説明しています。
- developerWorks の記事「動的 EMF を使ってメタモデルを構築する」を読んで、Java 実装クラスを生成することなく、オンデマンドで動的な Ecore ベースのモデルを作成する方法を学んでください。
- 「Eclipse オススメ情報リスト」を読んでください。
- developerWorks ですべての Eclipse 関連記事を調べてください。
- Eclipse の初心者は、developerWorks の記事「Eclipse Platform 入門」を読んでください。Eclipse の起源とアーキテクチャー、そしてプラグインで Eclipse を拡張する方法を学べます。
- IBM developerWorks の Eclipse project resources を調べて、Eclipse のスキルを磨いてください。
- ソフトウェア開発者を対象とした興味深いインタービューや討論については、developerWorks ポッドキャストをチェックしてください。
- developerWorks の Technical events and webcasts で最新情報を入手してください。
- 無料の developerWorks On demand demos で、IBM およびオープンン・ソースの技術と製品機能を調べて試してみてください。
- 世界中で近日中に予定されている IBM オープンソース開発者を対象とした会議、見本市、ウェブ放送やその他のイベントをチェックしてください。
- オープンソース技術を使用して開発し、IBM の製品と併用するときに役立つ広範囲のハウツー情報、ツール、およびプロジェクト・アップデートについては、developerWorks Open source ゾーンを参照してください。
製品や技術を入手するために
- Model to Text (M2T) をダウンロードしてください。Eclipse Foundation のこのプロジェクトでは、モデルからテキスト成果物を生成することを焦点としています。
- IBM alphaWorks で Eclipse 技術の最新ダウンロードを調べてください。
- Eclipse Foundation から Eclipse Platform およびその他のプロジェクトをダウンロードしてください。
- IBM 製品の評価版をダウンロードして、DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を使ってみてください。
- IBM ソフトウェアの試用版を使用して、次のオープンソース開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。
議論するために
- Eclipse に関する質問を投じる最初の場所として、Eclipse Platform newsgroups があります (このリンクをクリックすると、デフォルト Usenet ニュース・リーダー・アプリケーションが起動され、eclipse.platform が開きます)。
- Eclipse newsgroups には Eclipse を利用し、拡張することに関心を持つ人達のために、さまざまなリソースが用意されています。
- developerWorks blogs から developerWorks コミュニティーに加わってください。