package org.nutz.lang.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.MatchType; import org.nutz.lang.Mirror; public abstract class AbstractFastClass implements FastClass { private static final String[] cMethodName = new String[]{"create", "newInstance"}; private static final Class<?>[] toClasses(Object... args) { Class<?>[] classes = new Class[args.length]; for (int i = 0; i < classes.length; i++) classes[i] = args[i].getClass(); return classes; } protected Object _born(int index, Object... args) { throw Lang.noImplement(); } protected Object _invoke(Object obj, int index, Object... args) { throw Lang.noImplement(); } public Object born(Constructor<?> constructor, Object... args) { if (constructor == null) throw new IllegalArgumentException("!!Constructor must not NULL !"); if (Modifier.isPrivate(constructor.getModifiers())) throw new IllegalArgumentException("!!Constructor is private !"); return _born(getConstructorIndex(constructor.getParameterTypes()), args); } public Object born(Object... args) { Class<?>[] classes = toClasses(args); int index = getConstructorIndex(classes); if (index > -1) return _born(getConstructorIndex(classes), args); for (int i = 0; i < cMethodName.length; i++) { try { Method method = getSrcClass().getDeclaredMethod(cMethodName[i], classes); if (Modifier.isPrivate(method.getModifiers())) continue; if (!Modifier.isStatic(method.getModifiers())) continue; if (!getSrcClass().isAssignableFrom(method.getReturnType())) continue; return invoke(null, method, args); } catch (Throwable e) {} } throw new IllegalArgumentException("!!Fail to find Constructor for args"); } private int getConstructorIndex(Class<?>[] cpB) { Constructor<?>[] constructors = getConstructors(); for (int i = 0; i < constructors.length; i++) { Class<?>[] cpA = constructors[i].getParameterTypes(); if (MatchType.YES == Mirror.matchParamTypes(cpA, cpB)) return i; } throw new RuntimeException("!!No such Constructor found!"); } protected abstract Constructor<?>[] getConstructors(); private int getMethodIndex(Method method) { for (int i = 0; i < getMethods().length; i++) { if (getMethods()[i].equals(method)) return i; if (getMethods()[i].getName().equals(method.getName())) if (MatchType.YES == Mirror.matchParamTypes(getMethods()[i].getParameterTypes(), method.getParameterTypes())) return i; } throw new RuntimeException("!!No such Method found!"); } private int getMethodIndex(String name, Class<?>[] cpB) { for (int i = 0; i < getMethods().length; i++) { if (getMethods()[i].getName().equals(name)) if (MatchType.YES == Mirror.matchParamTypes(getMethods()[i].getParameterTypes(), cpB)) return i; } throw new RuntimeException("!!No such Method found!"); } protected abstract Method[] getMethods(); protected abstract Class<?> getSrcClass(); public Object invoke(Object obj, Method method, Object... args) { if (method == null) throw new IllegalArgumentException("!!Method must not NULL !"); if (Modifier.isPrivate(method.getModifiers())) throw new IllegalArgumentException("!!Method is private !"); if (obj == null && (Modifier.isStatic(method.getModifiers())) == false) throw new IllegalArgumentException("!!obj is NULL but Method isn't static !"); int index = getMethodIndex(method); if (index > -1) return _invoke(obj, getMethodIndex(method), args); throw new IllegalArgumentException("!!No such method --> " + method); } public Object invoke(Object obj, String methodName, Object... args) { Class<?>[] classes = toClasses(args); int index = getMethodIndex(methodName, classes); if (index > -1) return _invoke(obj, index, args); throw new IllegalArgumentException("!!Fail to get method ! For " + Json.toJson(classes)); } }