昨天在开发一个给Java Class添加static final long serialVersionUID属性的Eclipse插件时需要用到获取选中的Java类型(IType)对应的Class,由于是第一次写插件,花了不少时间来看帮助和相关资料才解决这个问题,最后总结了一下,写了一个ClassHelper类,方便以后再写其他插件时可以使用。
ClassHelper.java
package ksource.eclipse.util;
import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import java.util.Map;
import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.launching.JavaRuntime;
/** * Class Helper to load class of java project. * @author <a href=mailto:[email protected]>elvis</a> */ public final class ClassHelper {
private static final String PROTOCAL_PREFIX = "file:///";
/** * get the <code>ClassLoader</code> of java project specified. * * @param project <code>IJavaProject</code> * @return <code>ClassLoader</code> of java project * @throws CoreException * @throws MalformedURLException */ public static ClassLoader getProjectClassLoader(IJavaProject project) throws CoreException,MalformedURLException {
//compute the project classpaths //REVIEW: Are the classpaths returned by computeDefaultRuntimeClassPath enough to load class? String[] classPaths = JavaRuntime.computeDefaultRuntimeClassPath(project);
URL[] urls = new URL[classPaths.length]; for (int i = 0; i < classPaths.length; i++) { urls[i] = new URL(PROTOCAL_PREFIX + computeForURLClassLoader(classPaths[i])); } return new URLClassLoader(urls); }
/** * load <code>Class</code> in java project * * @param project <code>IJavaProject</code> * @param className name of class to load * @return <code>Class</code> * @throws ClassNotFoundException * @throws CoreException * @throws MalformedURLException */ public static Class loadClass(IJavaProject project, String className) throws CoreException, ClassNotFoundException,MalformedURLException { ClassLoader loader = getProjectClassLoader(project); Class clazz = loader.loadClass(className); loader = null; return clazz; }
/** * transform the <code>IType</code> to <code>Class</code> * * @param type <code>IType</code> * @return <code>Class</code> * @throws ClassNotFoundException * @throws MalformedURLException */ public static Class typeToClass(IType type) throws CoreException, ClassNotFoundException,MalformedURLException { try { if (null != type && (type.isClass() || type.isInterface())) { String className = type.getFullyQualifiedName('$'); return loadClass(type.getJavaProject(), className); } } catch (JavaModelException e) { e.printStackTrace(); } return null; }
/** * because of URLClassLoader assumes any URL not ends with '/' to refer to a * jar file. so we need to append '/' to classpath if it is a folder but not * ends with '/'. * * @param classpath * @return */ private static String computeForURLClassLoader(String classpath) { if (!classpath.endsWith("/")) { File file = new File(classpath); if (file.exists() && file.isDirectory()) { classpath = classpath.concat("/"); } } return classpath; } }

|