Package org.nutz.lang.born

Source Code of org.nutz.lang.born.Borns

package org.nutz.lang.born;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

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 构建信息对象
   */
  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> evalWithArgTypesboolean 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);

    // 先看看有没有默认构造函数
    try {
      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() == type && m.getParameterTypes().length == 0) {
          return re.setBorning(new EmptyArgsMethodBorning<T>(m)).setArgs(new Object[0]);
        }
      }
      // 看看有没有带一个动态参数的构造函数
      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;
  }

}
TOP

Related Classes of org.nutz.lang.born.Borns

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.