Java
Eclipse
Eclipseプラグイン
Eclipseプラグイン開発

[Eclipseプラグイン開発] IEditorInputからIFileを取得する

More than 3 years have passed since last update.


目的


  • Eclipse のエディタで開いているファイル( IFile )を取得する方法をメモ

  • 覚え書き的 tips


結論



  • IAdaptable で取得できる


方法

例えば、アクティブエディタで開いている IFile を取得したいとすると、以下のように書いてしまうと思います。

// nullチェックは省略

IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IEditorPart editor = window.getActivePage().getActiveEditor();
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof IFileEditorInput) {
IFileEditorInput fileEditorInput = (IFileEditorInput) editorInput; // ★
IFile file = fileEditorInput.getFile();
// file 取得
}

この場合 IFileEditorInput を決めうちしていることが問題になります。また、 IFileEditorInput を使うには依存プラグインとして org.eclipse.ui.ide が必要になります。

これは少しだけ簡単に以下のように取得できます。

// nullチェックは省略

IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
IEditorPart editor = window.getActivePage().getActiveEditor();
IEditorInput editorInput = editor.getEditorInput();
IFile file = editorInput.getAdapter(IFile.class); // ★
// file 取得(nullの可能性あり)

こうすれば IFileEditorInput の決めうちも不要ですし、依存プラグインとして org.eclipse.ui.ide も不要になります。

Optional を使えばこんな感じ(Workbenchが null のことは無いはずだけど)。

IEditorPart editor = Optional.ofNullable(PlatformUI.getWorkbench())

.map(IWorkbench::getActiveWorkbenchWindow)
.map(IWorkbenchWindow::getActivePage)
.map(IWorkbenchPage::getActiveEditor)
.map(IEditorPart::getEditorInput)
.map(a -> a.getAdapter(IFile.class)) // ★
.orElse(null);


確認

決めうちしていた IFileEditorInput ですが、実装クラスは org.eclipse.ui.part.FileEditorInput かそのサブクラスになります。

FileEditorInputPlatformObject を拡張しています。

これは IAdaptable な汎用オブジェクトみたいなものですね。

このあたりの詳細は、「Eclipse/プラグイン開発のTIPS集/org.eclipse.core.runtime.IAdaptable」が大変参考になるかと思います。

実際のアダプターは org.eclipse.ui.internal.ide.model.FileInputAdapterFactory が生成しているようです。

ソースを見ると IFileIResource を指定されるとファイルを返すようですね。

また、このアダプターファクトリーは org.eclipse.ui.ideplugin.xml に定義されているようです。

<!-- 省略 -->

<extension
id="org.eclipse.ui.ide.resourceMappingAdapters"
point="org.eclipse.core.runtime.adapters">
<!-- 省略 -->
<factory
adaptableType="org.eclipse.ui.IFileEditorInput"
class="org.eclipse.ui.internal.ide.model.FileInputAdapterFactory">
<adapter
type="org.eclipse.core.resources.IFile">
</adapter>
<adapter
type="org.eclipse.core.resources.IResource">
</adapter>
</factory>
<!-- 省略 -->