content: package com.alibaba.tamper.core.helper;
  
  import java.beans.BeanInfo;
  import java.beans.IntrospectionException;
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.Array;
  import java.lang.reflect.Constructor;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  
  import net.sf.cglib.core.ReflectUtils;
  
  import com.alibaba.tamper.core.BeanMappingException;
  
  /**
   * 一些反射调用的helper类
   * 
   * @author jianghang 2011-5-26 下午08:35:43
   */
  public class ReflectionHelper {
  
      private static String                   alias_int_name    = "int";
      private static String                   alias_short_name  = "short";
      private static String                   alias_long_name   = "long";
      private static String                   alias_char_name   = "char";
      private static String                   alias_double_name = "double";
      private static String                   alias_float_name  = "float";
      private static String                   alias_byte_name   = "byte";
      private static String                   alias_bool_name   = "boolean";
      private static String                   alias_string_name = "string";
      private static String                   alias_map_name    = "map";
      private static String                   alias_list_name   = "list";
      private static String                   alias_set_name    = "set";
      private final static Map<Class, Object> primitiveValueMap = new ConcurrentHashMap<Class, Object>(16);
      private final static Map<String, Class> aliasClassMap     = new ConcurrentHashMap<String, Class>(16); // class别名,比如primitive类型,string,list,map
  
      static {
          primitiveValueMap.put(Boolean.class, Boolean.FALSE);
          primitiveValueMap.put(Byte.class, Byte.valueOf((byte) 0));
          primitiveValueMap.put(Character.class, Character.valueOf((char) 0));
          primitiveValueMap.put(Short.class, Short.valueOf((short) 0));
          primitiveValueMap.put(Double.class, Double.valueOf(0));
          primitiveValueMap.put(Float.class, Float.valueOf(0));
          primitiveValueMap.put(Integer.class, Integer.valueOf(0));
          primitiveValueMap.put(Long.class, Long.valueOf(0));
          primitiveValueMap.put(boolean.class, Boolean.FALSE);
          primitiveValueMap.put(byte.class, Byte.valueOf((byte) 0));
          primitiveValueMap.put(char.class, Character.valueOf((char) 0));
          primitiveValueMap.put(short.class, Short.valueOf((short) 0));
          primitiveValueMap.put(double.class, Double.valueOf(0));
          primitiveValueMap.put(float.class, Float.valueOf(0));
          primitiveValueMap.put(int.class, Integer.valueOf(0));
          primitiveValueMap.put(long.class, Long.valueOf(0));
  
          aliasClassMap.put(alias_int_name, int.class);
          aliasClassMap.put(alias_short_name, short.class);
          aliasClassMap.put(alias_long_name, long.class);
          aliasClassMap.put(alias_double_name, double.class);
          aliasClassMap.put(alias_char_name, char.class);
          aliasClassMap.put(alias_float_name, float.class);
          aliasClassMap.put(alias_byte_name, byte.class);
          aliasClassMap.put(alias_bool_name, boolean.class);
          aliasClassMap.put(alias_string_name, String.class);
          aliasClassMap.put(alias_list_name, ArrayList.class);
          aliasClassMap.put(alias_map_name, HashMap.class);
          aliasClassMap.put(alias_set_name, HashSet.class);
      }
  
      public static void registerClassAlias(String alias, Class clazz) {
          aliasClassMap.put(alias, clazz);
      }
  
      public static PropertyDescriptor[] getPropertyDescriptors(Class clazz) {
          BeanInfo beanInfo = null;
          PropertyDescriptor[] descriptors = null;
          try {
              beanInfo = Introspector.getBeanInfo(clazz);
          } catch (IntrospectionException e) {
              return (new PropertyDescriptor[0]);
          }
  
          descriptors = beanInfo.getPropertyDescriptors();
          if (descriptors == null) {
              descriptors = new PropertyDescriptor[0];
          }
  
          return descriptors;
      }
  
      /**
       * 特殊处理，允许通过带参数的constructor创建对象
       * 
       * @param type
       * @return
       */
      public static Object newInstance(Class type) {
          Constructor _constructor = null;
          Object[] _constructorArgs = new Object[0];
          try {
              _constructor = type.getConstructor(new Class[] {});// 先尝试默认的空构造函数
          } catch (NoSuchMethodException e) {
              // ignore
          }
  
          if (_constructor == null) {// 没有默认的构造函数，尝试别的带参数的函数
              Constructor[] constructors = type.getConstructors();
              if (constructors.length == 0) {
                  throw new UnsupportedOperationException("Class[" + type.getName() + "] has no public constructors");
              }
              _constructor = constructors[0];// 默认取第一个参数
              Class[] params = _constructor.getParameterTypes();
              _constructorArgs = new Object[params.length];
              for (int i = 0; i < params.length; i++) {
                  _constructorArgs[i] = getDefaultValue(params[i]);
              }
          }
  
          return ReflectUtils.newInstance(_constructor, _constructorArgs);
      }
  
      /**
       * 根据class类型返回默认值值
       * 
       * @param cl
       * @return
       */
      public static Object getDefaultValue(Class cl) {
          if (cl.isArray()) {// 处理数组
              return Array.newInstance(cl.getComponentType(), 0);
          } else if (cl.isPrimitive() || primitiveValueMap.containsKey(cl)) { // 处理原型
              return primitiveValueMap.get(cl);
          } else {
              return newInstance(cl);
              // return null;
          }
      }
  
      /**
       * 支持class alias别名
       * 
       * @param className
       * @return
       */
      public static Class forName(String className) {
          try {
              return Class.forName(className);
          } catch (ClassNotFoundException e) {
              if (aliasClassMap.containsKey(className)) {
                  return aliasClassMap.get(className);
              }
  
              throw new BeanMappingException("forName class[" + className + "] is error!", e);
          }
      }
  
      /**
       * 从指定的ClassLoader中装载
       */
      public static Class forName(String className, ClassLoader loader) {
          try {
              return loader.loadClass(className);
          } catch (ClassNotFoundException e) {
              if (aliasClassMap.containsKey(className)) {
                  return aliasClassMap.get(className);
              }
  
              throw new BeanMappingException("forName class[" + className + "] is error!", e);
          }
      }
  }
  