Eclipseのプラグイン開発のJDTのITypeについて。
|
|
ITypeは、Javaの型(クラス・インターフェース・列挙型・アノテーション)を表すインターフェース。
IJavaProjectのfindTypeメソッドでITypeを取得することが出来る。
import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException;
IJavaProject project = 〜; IType type; try { type = project.findType("com.asakusafw.dmdl.parser.DmdlParser"); } catch (JavaModelException e) { ILog log = Activator.getDefault().getLog(); log.log(e.getStatus()); return; } if (type == null) { return; // 見つからなかった } if (type.isClass()) { // クラス }
findType()は、Javaプロジェクトのビルドパスに含まれているライブラリー(jarファイル等)から探す。
ICompilationUnitからはfindPrimaryTypeメソッドでITypeを取得することが出来る。[2014-06-09]
import org.eclipse.core.resources.IFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore;
IFile file = 〜; IJavaElement element = JavaCore.create(file); if (element != null) { ICompilationUnit unit = (ICompilationUnit) element.getAncestor(IJavaElement.COMPILATION_UNIT); if (unit != null) { IType type = unit.findPrimaryType(); if (type != null) { 〜 } } }
ITypeの属性を取得するには、IType自身のメソッドの他に、Flagsクラスを使う方法がある。[2014-06-09]
import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IType;
IType type = 〜; boolean isAbstract = Flags.isAbstract(type.getFlags());
ITypeがクラスを指しているとして、そのインスタンスを生成したい。
が、単純に生成できる方法は提供されていないようだ。(参考: stackoverflowのInstantiate an Object from an IType)
そこで、無理矢理だが方法を考えてみた。
ITypeからそのクラスが含まれているjarファイルを取得し、クラスローダーを独自に作ればいい。
String className = "com.asakusafw.dmdl.parser.DmdlParser"; IType type = project.findType(className); if (type == null) { return; } IClassFile cf = type.getClassFile(); URL url = cf.getPath().toFile().toURI().toURL(); URL[] urls = { url }; ClassLoader loader = URLClassLoader.newInstance(urls); Class<?> parserClass = loader.loadClass(className); Object parser = parserClass.newInstance();
ちなみに、インスタンスを作りたいクラスが依存しているライブラリーが他にもある場合は、同様の手順でURLを取得してまとめてひとつのクラスローダーを生成しないと、インスタンス生成で例外が発生する。
ここで例に挙げているAsakusa Framework0.4のDmdlParserはslf4jを使っているので、「org.slf4j.LoggerFactoryが見つからない」という例外が発生した(苦笑)
なお、この方法だと、生成したインスタンスの操作も全てリフレクションで行う必要があり、かなり面倒orz
DmdlParserがEclipseプラグインとして提供されていれば、プラグインの依存関係に入れるだけで使えるんだけどなぁ^^;