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

Xtext NatureAddingEditorCallback

XtextのNatureAddingEditorCallbackクラス(IXtextEditorCallbackインターフェース)のメモ。


概要

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

このダイアログはNatureAddingEditorCallbackクラスで表示しているので、 ダイアログを出さないようにする為にはNatureAddingEditorCallbackクラスを独自クラスに差し替えればよい。

ただし、NatureAddingEditorCallbackは(Eclipseプラグイン機構の仕組みにより)外部に公開されていないクラスなので、直接継承しようとすると警告が出る。
したがって、(他の処理も特に無いので)NatureAddingEditorCallbackの親クラスを継承して独自クラスを作ればよい。
Xtext2.4ではNatureAddingEditorCallbackはAbstractDirtyStateAwareEditorCallbackを継承しているので、独自クラスもAbstractDirtyStateAwareEditorCallbackを継承すれば(このクラスは公開されているクラスなので)警告も出ない。
と思っていた。

しかし、Xtext2.7でAbstractDirtyStateAwareEditorCallbackが非推奨となり、NatureAddingEditorCallbackもIXtextEditorCallback.NullImplを継承するよう修正された。
AbstractDirtyStateAwareEditorCallbackを継承した独自クラスを使っていると、Xtext2.7環境では、エディターで文字を入力する度に 『Resource was edited concurrently.』「The resource is concurrently edited in another editor. Do you want to continue?」というダイアログが出て、非常に鬱陶しい。

Resource was edited concurrently

「Yes」を押せば一時的に出なくなるが、ファイルを保存してから修正しようとするとまた出てくる(苦笑)

Xtext2.7では、NatureAddingEditorCallbackを差し替えるには(AbstractDirtyStateAwareEditorCallbackでなく)IXtextEditorCallback.NullImplを継承するようにするべき。

とは言え、過去のバージョンでも使えるようにするなら、警告が出るのはあきらめて、NatureAddingEditorCallbackを直接継承しておくのが良さそうだ。
ネイチャーの自動登録


Xtext2.4:NatureAddingEditorCallbackの差し替え

Xtext2.4で(NatureAddingEditorCallbackを差し替えて)自動的にネイチャーを登録する例。

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

import java.util.Arrays;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.xtext.ui.XtextProjectHelper;
import org.eclipse.xtext.ui.editor.AbstractDirtyStateAwareEditorCallback;
import org.eclipse.xtext.ui.editor.XtextEditor;
public class MyEditorCallback extends AbstractDirtyStateAwareEditorCallback {

	@Override
	public void afterCreatePartControl(XtextEditor editor) {
		super.afterCreatePartControl(editor);

		IResource resource = editor.getResource();
		if (resource == null) {
			return;
		}
		IProject project = resource.getProject();
		if (!XtextProjectHelper.hasNature(project) && project.isAccessible() && !project.isHidden()) {
			addNature(project);
		}
	}
	private void addNature(IProject project) {
		try {
			IProjectDescription description = project.getDescription();
			String[] natures = description.getNatureIds();
			String[] newNatures = Arrays.copyOf(natures, natures.length + 1);
			newNatures[natures.length] = XtextProjectHelper.NATURE_ID;
			description.setNatureIds(newNatures);
			project.setDescription(description, null);
		} catch (CoreException e) {
			MyActivator.getInstance().getLog().log(e.getStatus());
		}
	}
}

作成した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;
	}
}

Xtext2.7:NatureAddingEditorCallbackの差し替え

Xtext2.7で(NatureAddingEditorCallbackを差し替えて)自動的にネイチャーを登録する例。
Xtext2.4版との違いは、親クラスだけ)

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

import java.util.Arrays;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.xtext.ui.XtextProjectHelper;
import org.eclipse.xtext.ui.editor.IXtextEditorCallback;
import org.eclipse.xtext.ui.editor.XtextEditor;
public class MyEditorCallback extends IXtextEditorCallback.NullImpl {

	@Override
	public void afterCreatePartControl(XtextEditor editor) {
		super.afterCreatePartControl(editor);

		IResource resource = editor.getResource();
		if (resource == null) {
			return;
		}
		IProject project = resource.getProject();
		if (!XtextProjectHelper.hasNature(project) && project.isAccessible() && !project.isHidden()) {
			addNature(project);
		}
	}
	private void addNature(IProject project) {
		try {
			IProjectDescription description = project.getDescription();
			String[] natures = description.getNatureIds();
			String[] newNatures = Arrays.copyOf(natures, natures.length + 1);
			newNatures[natures.length] = XtextProjectHelper.NATURE_ID;
			description.setNatureIds(newNatures);
			project.setDescription(description, null);
		} catch (CoreException e) {
			MyActivator.getInstance().getLog().log(e.getStatus());
		}
	}
}

作成した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へ戻る / 技術メモへ戻る
メールの送信先:ひしだま