S-JIS[2013-10-23/2014-10-18] 変更履歴

Xtextネイチャー

Xtextのネイチャーのメモ。


概要

Xtextで生成されたエディターを起動すると、初回に「Do you want to add the Xtext nature to the project 'プロジェクト名'?」というダイアログが表示される。

ここでYesを選択しないと、Xtextの一部の機能(「Open Model Element」ダイアログとか)が使えないし、別のファイルのエディターを開いたときに再び同じダイアログが表示される。

このダイアログは、エディターを使おうとしているファイルのプロジェクトに「Xtextネイチャー」を追加するかどうかを確認するもの。
ネイチャーはEclipseの仕組みのひとつであり、例えばJavaの開発を行う場合はJDTのJavaNatureが使われている。
Xtextを使う場合は、ユーザーに対してXtextネイチャーを使うかどうかを明示的に確認する、という方針らしい。


プロジェクトにXtextネイチャーを追加すると、.projectファイルにXtextネイチャーの指定が加わる。

.project:

<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>プロジェクト名</name>
〜
	<natures>
		<nature>org.eclipse.jdt.core.javanature</nature>
		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
	</natures>
</projectDescription>

pom.xmlでネイチャーを指定する方法

Mavenを使ってプロジェクトを作っている場合、「mvn eclipse:eclipse」コマンドを実行すると、.projectファイルが作り直される。
その為、以前にXtextネイチャーを登録していてもネイチャーの情報が消えてしまい、再度Xtextネイチャーを登録するかどうか確認するダイアログが表示されることになる。

pom.xmlのmaven-eclipse-pluginにネイチャーを追加しておけば 生成される.projectファイル内にそのネイチャーが追加されるので、確認ダイアログが出なくなる。

pom.xml:

	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-eclipse-plugin</artifactId>
		<version>${plugin.eclipse.version}</version>
		<configuration>
			<additionalProjectnatures>
				<projectnature>org.eclipse.xtext.ui.shared.xtextNature</projectnature>
			</additionalProjectnatures>
			<downloadSources>true</downloadSources>
			<downloadJavadocs>false</downloadJavadocs>
〜
		</configuration>
	</plugin>

build.gradleでネイチャーを指定する方法

Gradleを使ってプロジェクトを作っている場合、build.gradleにEclipseプラグインを導入して「gradle cleanEclipse eclipse」コマンドを実行すると、.projectファイルが作り直される。[2014-04-25]
その為、以前にXtextネイチャーを登録していてもネイチャーの情報が消えてしまい、再度Xtextネイチャーを登録するかどうか確認するダイアログが表示されることになる。

build.gradleのeclipse.projectにネイチャーを追加しておけば 生成される.projectファイル内にそのネイチャーが追加されるので、確認ダイアログが出なくなる。

build.gradle:

apply plugin: 'eclipse'

eclipse {
    project {
        natures 'org.eclipse.xtext.ui.shared.xtextNature'
    }
}

自動的にネイチャーを登録する方法

Xtextでエディターを作っても、そのエディターを使うだけのユーザーにはXtextとか関係ないので、Xtextネイチャーを追加するダイアログは不可解だろう。
このダイアログはNatureAddingEditorCallbackというクラスで出している。
したがって、このダイアログを出さないようにするには、NatureAddingEditorCallbackに代わるクラスを用意してやればよい。

uiプロジェクト/src/〜/MyEditorCallback.java:

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.xtext.builder.nature.NatureAddingEditorCallback;
import org.eclipse.xtext.builder.nature.ToggleXtextNatureAction;
import org.eclipse.xtext.ui.editor.XtextEditor;

import com.google.inject.Inject;
@SuppressWarnings("restriction")
public class MyEditorCallback extends NatureAddingEditorCallback {
	@Inject
	private ToggleXtextNatureAction toggleNature;
	@Override
	public void afterCreatePartControl(XtextEditor editor) {
		IResource resource = editor.getResource();
		if (resource != null) {
			IProject project = resource.getProject();
			if (!hasNature(project) && project.isAccessible() && !project.isHidden()) {
				addNature(project);
			}
		}

		super.afterCreatePartControl(editor);
	}
	private boolean hasNature(IProject project) {
		return toggleNature.hasNature(project);
	}

	private void addNature(IProject project) {
		toggleNature.toggleNature(project);
	}
}

NatureAddingEditorCallbackは(Eclipseプラグインの機構によって)外部に公開されていないので、restrictionの警告が出る。[2014-10-18]
Xtext2.4ではNatureAddingEditorCallbackの親クラスであるAbstractDirtyStateAwareEditorCallbackを継承する方法でもよかったが、Xtext2.7で非推奨になって挙動がおかしくなったので、AbstractDirtyStateAwareEditorCallbackは使わない方が良い)


作成したCallbackクラスをUiModuleで指定する。

uiプロジェクト/src/〜/MyUiModule.java:

public class MyUiModule extends com.example.ui.AbstractMyUiModule {
〜
	@Override
	public Class<? extends org.eclipse.xtext.ui.editor.IXtextEditorCallback> bindIXtextEditorCallback() {
		return MyEditorCallback.class;
	}
}

Xtext目次へ戻る / Eclipseへ戻る / 技術メモへ戻る
メールの送信先:ひしだま