/src/kilim/mirrors/RuntimeClassMirrors.java
http://github.com/kilim/kilim · Java · 194 lines · 147 code · 34 blank · 13 comment · 17 complexity · 0a7fa6ecdd70ac40f11ea15ea4709a0d MD5 · raw file
- package kilim.mirrors;
- import java.lang.reflect.Method;
- import java.util.Collections;
- import java.util.Map;
- import java.util.WeakHashMap;
- import kilim.KilimClassLoader;
- import org.objectweb.asm.Type;
- /**
- * This class provides the Mirrors facade over a set of Class objects
- * @see Mirrors
- */
- public class RuntimeClassMirrors implements Mirrors {
- // Weakly cache the mirror objects.
- Map<String, RuntimeClassMirror> cachedClasses = Collections
- .synchronizedMap(new WeakHashMap<String, RuntimeClassMirror>());
- public final KilimClassLoader classLoader;
- public RuntimeClassMirrors() {
- this(Thread.currentThread().getContextClassLoader());
- }
- public RuntimeClassMirrors(ClassLoader cl) {
- if (!(cl instanceof KilimClassLoader)) {
- cl = new KilimClassLoader(cl);
- }
- this.classLoader = (KilimClassLoader) cl;
- }
- @Override
- public ClassMirror classForName(String className) throws ClassMirrorNotFoundException {
- try {
- RuntimeClassMirror ret = cachedClasses.get(className);
- if (ret == null) {
- ret = make(classLoader.loadClass(className));
- }
- return ret;
- } catch (ClassNotFoundException e) {
- throw new ClassMirrorNotFoundException(className, e);
- }
- }
- @Override
- public ClassMirror mirror(Class<?> clazz) {
- if (clazz == null)
- return null;
- return make(clazz);
- }
- @Override
- public ClassMirror mirror(String className, byte[] bytecode) {
- try {
- return classForName(className);
- } catch (ClassMirrorNotFoundException ignore) {}
- return null;
- }
- /**
- * Like classForName, but only if the class is already loaded. This does not force loading of a
- * class.
- *
- * @param className
- * @return null if className not loaded, else a RuntimeClassMirror to represent the loaded
- * class.
- */
- public ClassMirror loadedClassForName(String className) {
- Class<?> c = classLoader.getLoadedClass(className);
- return (c == null) ? null : make(c);
- }
- public Class<?> getLoadedClass(String className) {
- return classLoader.getLoadedClass(className);
- }
- public boolean isLoaded(String className) {
- return classLoader.isLoaded(className);
- }
- private RuntimeClassMirror make(Class<?> c) {
- if (c == null) {
- throw new NullPointerException();
- }
- RuntimeClassMirror ret = new RuntimeClassMirror(c);
- cachedClasses.put(c.getName(), ret);
- return ret;
- }
- }
- class RuntimeMethodMirror implements MethodMirror {
- private final Method method;
- public RuntimeMethodMirror(Method method) {
- this.method = method;
- }
- public String getName() {
- return method.getName();
- }
- public String[] getExceptionTypes() {
- String[] ret = new String[method.getExceptionTypes().length];
- int i = 0;
- for (Class<?> excl : method.getExceptionTypes()) {
- ret[i++] = excl.getName();
- }
- return ret;
- }
- public String getMethodDescriptor() {
- return Type.getMethodDescriptor(method);
- }
- public boolean isBridge() {
- return method.isBridge();
- }
- }
- class RuntimeClassMirror implements ClassMirror {
- private final Class<?> clazz;
- private MethodMirror[] methods;
-
- public RuntimeClassMirror(Class<?> clazz) {
- this.clazz = clazz;
- }
- @Override
- public String getName() {
- return clazz.getName();
- }
- @Override
- public boolean isInterface() {
- return clazz.isInterface();
- }
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ClassMirror) {
- return ((ClassMirror) obj).getName().equals(this.getName());
- }
- return false;
- }
- @Override
- public int hashCode() {
- return clazz.hashCode();
- }
- @Override
- public MethodMirror[] getDeclaredMethods() {
- if (methods == null) {
- Method[] declaredMethods = clazz.getDeclaredMethods();
- methods = new MethodMirror[declaredMethods.length];
- for (int i = 0; i < declaredMethods.length; i++) {
- methods[i] = new RuntimeMethodMirror(declaredMethods[i]);
- }
- }
- return methods;
- }
- @Override
- public String[] getInterfaces() {
- Class<?>[] ifs = clazz.getInterfaces();
- String[] result = new String[ifs.length];
- for (int i = 0; i < result.length; i++) {
- result[i] = ifs[i].getName();
- }
- return result;
- }
- @Override
- public String getSuperclass() {
- Class<?> supcl = clazz.getSuperclass();
- return supcl != null ? supcl.getName() : null;
- }
- @Override
- public boolean isAssignableFrom(ClassMirror c) {
- if (c instanceof RuntimeClassMirror) {
- RuntimeClassMirror cc = (RuntimeClassMirror) c;
- return clazz.isAssignableFrom(cc.clazz);
- } else {
- return false;
- }
- }
- }