Package kilim.mirrors

Source Code of kilim.mirrors.RuntimeMethodMirror

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;
        }
    }

}
TOP

Related Classes of kilim.mirrors.RuntimeMethodMirror

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.