package org.nutz.lang.born; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.nutz.castor.Castors; import org.nutz.lang.Lang; import org.nutz.lang.MatchType; import org.nutz.lang.Mirror; /** * 关于创建对象的一些帮助方法 * * @author zozoh(zozohtnt@gmail.com) */ public abstract class Borns { /** * 根据参数类型数组获取一个对象的构建信息 * * @param <T> * 对象类型信息 * @param type * 对象类型 * @param argTypes * 构造参数类型数组 * @return 构建信息对象 */ public static <T> BornContext<T> evalByArgTypes(Class<T> type, Class<?>... argTypes) { BornContext<T> re; if (argTypes.length == 0) { re = evalWithoutArgs(type); } else { re = evalWithArgTypes(true, type, argTypes, null); } return re; } /** * 根据参数类型数组获取一个对象的构建信息 * * @param <T> * 对象类型信息 * @param type * 对象类型 * @param args * 构造参数数组 * @return 构建信息对象 * @throws NullPointerException * when args is null */ public static <T> BornContext<T> eval(Class<T> type, Object... args) { BornContext<T> re; if (args.length == 0) { re = evalWithoutArgs(type); } else { re = evalWithArgs(type, args); } return re; } /** * 根据一个调用参数数组,获取一个对象的构建信息 * * @param <T> * 对象类型信息 * @param type * 对象类型 * @param args * 参考构建参数 * @return 构建信息对象 */ private static <T> BornContext<T> evalWithArgs(Class<T> type, Object[] args) { // 准备变参数组 Object dynaArg = Mirror.evalArgToSameTypeRealArray(args); // 准备好参数类型 Class<?>[] argTypes = Mirror.evalToTypes(args); BornContext<T> re = evalWithArgTypes(false, type, argTypes, dynaArg); if (null == re) return null; if (MatchType.LACK == re.getMatchType()) { re.setArgs(Lang.arrayLast(args, re.getLackArg())); } else { re.setArgs(args); } switch (re.getMatchType()) { case LACK: re.setArgs(Lang.arrayLast(args, re.getLackArg())); break; case NEED_CAST: re.setArgs(Lang.array2ObjectArray(args, re.getCastType())); break; default: re.setArgs(args); } return re; } /** * 根据一个调用参数类型数组,获取一个对象的构建信息 * * @param <T> * 对象类型信息 * @param accurate * 是否需要精确匹配 * @param type * 对象类型 * @param argTypes * 参考参数类型数组 * @param dynaAry * 参考参数类型信息是否是一个变参数组 * @return 构建信息对象 */ @SuppressWarnings({"rawtypes", "unchecked"}) private static <T> BornContext<T> evalWithArgTypes(boolean accurate, Class<T> type, Class<?>[] argTypes, Object dynaArg) { // 准备好返回对象 BornContext<T> re = new BornContext<T>(); // 先看看有没对应的构造函数 Mirror<T> mirror = Mirror.me(type); for (Constructor<?> cc : type.getConstructors()) { Class<?>[] pts = cc.getParameterTypes(); MatchType mt = Mirror.matchParamTypes(pts, argTypes); re.setMatchType(mt); // 正好合适 if (MatchType.YES == mt) { return re.setBorning(new ConstructorBorning(cc)); } // 差一个参数,说明这个构造函数有变参数组 else if (MatchType.LACK == mt) { re.setLackArg(Mirror.blankArrayArg(pts)); return re.setBorning(new ConstructorBorning(cc)); } // 看看整个输入的参数是不是变参 else if (null != dynaArg && pts.length == 1 && pts[0] == dynaArg.getClass()) { return re.setBorning(new DynamicConstructorBorning(cc)); } } // 看看有没有对应静态工厂函数 Method[] sms = mirror.getStaticMethods(); for (Method m : sms) { Class<?>[] pts = m.getParameterTypes(); MatchType mt = Mirror.matchParamTypes(pts, argTypes); re.setMatchType(mt); if (MatchType.YES == mt) { return re.setBorning(new MethodBorning<T>(m)); } else if (MatchType.LACK == mt) { re.setLackArg(Mirror.blankArrayArg(pts)); return re.setBorning(new MethodBorning<T>(m)); } else if (null != dynaArg && pts.length == 1) { if (pts[0] == dynaArg.getClass()) { return re.setBorning(new DynaMethodBorning<T>(m)); } } } // 如果不是要精确查找的话 if (!accurate) { // 找到一个长度合适的构造函数,准备转换 try { for (Constructor<?> cc : type.getConstructors()) { Class<?>[] pts = cc.getParameterTypes(); if (canBeCasted(argTypes, pts)) { re.setMatchType(MatchType.NEED_CAST); re.setCastType(pts); return re.setBorning(new ConstructorCastingBorning(cc)); } } } catch (RuntimeException e) {} // 有没有变参的静态构造方法 try { for (Method m : sms) { Class<?>[] pts = m.getParameterTypes(); if (canBeCasted(argTypes, pts)) { re.setMatchType(MatchType.NEED_CAST); re.setCastType(pts); return re.setBorning(new MethodCastingBorning<T>(m)); } } } catch (Exception e) {} } return null; } private static boolean canBeCasted(Class<?>[] argTypes, Class<?>[] pts) { if (pts.length != argTypes.length) return false; for (int i = 0; i < pts.length; i++) { if (!Castors.me().canCast(argTypes[i], pts[i])) return false; } return true; } /** * 为一个给定类,寻找一个不需要参数的构造方法 * * @param <T> * 类 * @param type * 类实例 * @return 构造信息 */ @SuppressWarnings({"rawtypes", "unchecked"}) private static <T> BornContext<T> evalWithoutArgs(Class<T> type) { // 准备好返回对象 BornContext<T> re = new BornContext<T>(); Mirror<T> mirror = Mirror.me(type); boolean isAbstract = Modifier.isAbstract(type.getModifiers()); // 先看看有没有默认构造函数 try { if (!isAbstract) { re.setBorning(new EmptyArgsConstructorBorning<T>(type.getConstructor())); return re.setArgs(new Object[0]); } } // 如果没有默认构造函数 ... catch (Exception e) {} // 看看有没有默认静态工厂函数 Method[] stMethods = mirror.getStaticMethods(); for (Method m : stMethods) { if (m.getReturnType().equals(type) && m.getParameterTypes().length == 0) { return re.setBorning(new EmptyArgsMethodBorning<T>(m)).setArgs(new Object[0]); } } // 看看有没有带一个动态参数的构造函数 if (!isAbstract) { for (Constructor<?> cons : type.getConstructors()) { Class<?>[] pts = cons.getParameterTypes(); if (pts.length == 1 && pts[0].isArray()) { Object[] args = new Object[1]; args[0] = Mirror.blankArrayArg(pts); return re.setBorning(new ConstructorBorning(cons)).setArgs(args); } } } // 看看有没有带一个动态参数的静态工厂函数 for (Method m : stMethods) { Class<?>[] pts = m.getParameterTypes(); if (m.getReturnType() == type && m.getParameterTypes().length == 1 && pts[0].isArray()) { Object[] args = new Object[1]; args[0] = Mirror.blankArrayArg(pts); return re.setBorning(new MethodBorning<T>(m)).setArgs(args); } } return null; } }