目的
- 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
かそのサブクラスになります。
FileEditorInput
は PlatformObject
を拡張しています。
これは IAdaptable
な汎用オブジェクトみたいなものですね。
このあたりの詳細は、「Eclipse/プラグイン開発のTIPS集/org.eclipse.core.runtime.IAdaptable」が大変参考になるかと思います。
実際のアダプターは org.eclipse.ui.internal.ide.model.FileInputAdapterFactory
が生成しているようです。
ソースを見ると IFile
と IResource
を指定されるとファイルを返すようですね。
また、このアダプターファクトリーは org.eclipse.ui.ide
の plugin.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>
<!-- 省略 -->