DocumentRootをDiagram Root Elementにする

EMFでは、Ecoreエディタを使って直接EMFモデルを作成するだけでなく、XMLスキーマを読み込んでEMFモデルを自動生成することができます。XMLスキーマからEMFモデルを生成する場合、DocumentRootという特別なクラスも生成されます。このクラスは、整形式XMLに必ず存在するルート要素を属性として持ちます。

もちろん、XMLスキーマから生成したEMFモデルのインスタンスをグラフィカルに編集可能なエディタをGMFで生成することができます。通常、上記DocumentRootクラスではなく、ルートクラスをDiagram Root Elementとしてグラフィカルエディタを生成します。

実は、DocumentRootクラスをDiagram Root Elementとしてグラフィカルエディタを生成可能です。GMF/Tutorial - Eclipsepediaの例で使用されているマインドマップモデルのXMLスキーマ"mindmap.xsd"を用いて説明します。

まず、mindmap.xsdからEcoreモデル"mindmap.ecore"を生成します。次に、mindmap.ecoreファイルからGraphical Definitionファイルを作成します。その際、新規作成ウィザードにおいて、(通常はルートクラスであるMapクラスを選択するところを)「Diagram Element」としてDocumentRootを選択します。

ここでは簡単のために、MapクラスとTopicクラスのみをノードとしてキャンバス上に配置できるようにします。そして注意していただきたいのは、今回、DocumentRootクラスがDiagram Root Elementとなるため、Topicクラスのノードをキャンバス上に配置直後には、GMF runtimeがそのノードに対応するインスタンスの親(Map)を一意に特定できません。したがって、上記ノードを配置した後にその親としてMapクラスのインスタンスを指定できるよう、Mapクラスの属性「rootTopics」をリンクフィギュアとして指定します。

同じく、mindmap.ecoreファイルからTooling Definitionファイルを作成する際、新規作成ウィザードにおいて、「Diagram Element」としてDocumentRootを選択します。

また、Tooling Definitionとして、MapクラスとTopicクラスに対応するノードのみを作成するように定義し、上記のようにMapクラスの属性「rootTopics」に対応するリンクを作成するように定義します。

同じく、mindmap.ecoreファイルからMapping Definitionファイルを作成する際、新規作成ウィザードの「Select Domain Model」ページにおいて、「Class」としてDocumentRootを選択します。

そして、以下のようにMapping Definitionを定義します。ここでの注意点は、Topicクラスに対応するTop Node Referenceの属性「Containment Feature」を未定義にしておくことです。これにより、Topicクラスのノードをキャンバスに配置後に、親を上記リンクで指定できるようになります。

最後に、上記Mapping Definitionファイルから.gmfgenファイルを生成し、グラフィカルエディタコードを生成します。このとき、一カ所だけコンパイルエラーが発生するはずです。発生箇所はorg.example.mindmap.diagram.part.MindmapDiagramEditorUtil.java内のcreateDocumentRoot()メソッド内です。本メソッドを以下のように修正します。

/**
 * @generated NOT
 */
private static DocumentRoot createDocumentRoot(DocumentRoot model) {
	org.example.mindmap.Map map = MindmapFactory.eINSTANCE.createMap();
	// DocumentRootクラスにルート要素をセットする
	model.setMap(map);
	return model;
}

これでコンパイルエラーが取れるはずで、グラフィカルエディタを起動してみると、ルート要素が一つだけすでにキャンバス上に現れた状態で起動されるはずです。

あとは、Topicノードをキャンバス上に配置した後、MapRootTopicsリンクでMapノードをTopicノードを接続してやると、Mapを親とするTopic要素として編集されます。