001package runwar.util;
002
003import java.lang.reflect.InvocationTargetException;
004import java.lang.reflect.Method;
005import java.util.Arrays;
006
007public class Reflection {
008
009    public static Class<?> load(ClassLoader classLoader, String name) {
010        try {
011            return classLoader.loadClass(name);
012        } catch (Exception ex) {
013            handleReflectionException(ex);
014        }
015        throw new IllegalStateException("Should never get here");
016    }
017
018    public static Method method(Class<?> clazz, String name) {
019        return method(clazz, name, new Class[0]);
020    }
021
022    public static Method method(Class<?> clazz, String name, Class<?>... paramTypes) {
023        Class<?> searchType = clazz;
024        while (!Object.class.equals(searchType) && searchType != null) {
025            Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());
026            for (int i = 0; i < methods.length; i++) {
027                Method method = methods[i];
028                if (name.equals(method.getName()) && Arrays.equals(paramTypes, method.getParameterTypes())) {
029                    return method;
030                }
031            }
032            searchType = searchType.getSuperclass();
033        }
034        return null;
035    }
036
037    public static Object invoke(Method method, Object target, Object... args) {
038        try {
039            return method.invoke(target, args);
040        } catch (Exception ex) {
041            handleReflectionException(ex);
042        }
043        throw new IllegalStateException("Should never get here");
044    }
045
046    public static void handleReflectionException(Exception ex) {
047        if (ex instanceof NoSuchMethodException) {
048            throw new IllegalStateException("Method not found: " + ex.getMessage());
049        }
050        if (ex instanceof IllegalAccessException) {
051            throw new IllegalStateException("Could not access method: " + ex.getMessage());
052        }
053        if (ex instanceof InvocationTargetException) {
054            handleInvocationTargetException((InvocationTargetException) ex);
055        }
056        if (ex instanceof RuntimeException) {
057            throw (RuntimeException) ex;
058        }
059        handleUnexpectedException(ex);
060    }
061
062    public static void rethrowRuntimeException(Throwable ex) {
063        if (ex instanceof RuntimeException) {
064            throw (RuntimeException) ex;
065        }
066        if (ex instanceof Error) {
067            throw (Error) ex;
068        }
069        handleUnexpectedException(ex);
070    }
071
072    public static void handleInvocationTargetException(InvocationTargetException ex) {
073        rethrowRuntimeException(ex.getTargetException());
074    }
075
076    private static void handleUnexpectedException(Throwable ex) {
077        IllegalStateException isex = new IllegalStateException("Unexpected exception thrown");
078        isex.initCause(ex);
079        throw isex;
080    }
081
082}