package net.eulerframework.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class JavaObjectUtils {
    
    /**
     * 将对象中为<code>""</code>的属性置为<code>null</code>
     * @param obj 待处理的对象
     */
    public static void clearEmptyProperty(Object obj) {
        if (obj == null)
            return;
        try {
            for (Class<? extends Object> clazz = obj.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields)
                    if ((field.getType() == String.class) && (!(Modifier.isStatic(field.getModifiers())))) {
                        boolean accessible = field.isAccessible();
                        field.setAccessible(true);
                        String value = (String) field.get(obj);
                        if (value != null && "".equals(value.trim())) {
                            field.set(obj, null);
                        }
                        field.setAccessible(accessible);
                    }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取对象的属性
     * @param clazz 待获取的对象
     * @param includeParentClass 是否包含父类属性
     * @return 对象的属性数组
     */
    public static Field[] getBeanFields(Class<?> clazz, boolean includeParentClass) {
        Field[] fields = clazz.getDeclaredFields();
        if (includeParentClass) {
            Class<?> parentClazz = clazz.getSuperclass();
            if (parentClazz != Object.class) {
                Field[] parentClazzFields = getBeanFields(parentClazz, true);
                Field[] result = ArrayUtils.concatAll(fields, parentClazzFields);
                return result;
            }
        }
        return fields;
    }

    /**
     * 获取父类范型类型
     * @param clazz 当前类
     * @param index 第几个范型参数
     * @return 范型参数的<code>Class</code>
     */
    public static Class<?> findSuperClassGenricType(Class<?> clazz, int index){
        if(clazz == null)
            return null;
        
        Type type = clazz.getGenericSuperclass();
        
        if (type instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) type;            
            Type[] argTypes = pType.getActualTypeArguments();
            
            if(index >= argTypes.length || index < 0){
                throw new IndexOutOfBoundsException("Genric args types find error，Index out of bounds: total="+argTypes.length+", index="+index);
            }
            
            Type argType = argTypes[index];
            
            if (argType instanceof Class) {
                return ((Class<?>) argType);
            }
            
            return null;
        }
    
        return findSuperClassGenricType(clazz.getSuperclass(), index);        
    }
}

@@ -175,16 +175,38 @@
 ct.Type;
+%0Aimport java.util.Map;
 %0A%0Apublic
@@ -608,32 +608,33 @@
 s = 
-clazz.getDeclaredFields(
+getBeanFields(clazz, true
 );%0A 
@@ -2992,10 +2992,1367 @@
  %0A    %7D%0A
+    %0A    /**%0A     * %E5%B0%86Map%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%AF%B9%E8%B1%A1, %E7%9B%AE%E5%89%8D%E5%8F%AA%E6%94%AF%E6%8C%81String%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%B1%9E%E6%80%A7%0A     * @param map%0A     * @param objectClass%0A     * @return%0A     * @throws InstantiationException%0A     * @throws IllegalAccessException%0A     */%0A    public static %3CE%3E E readMapAsObject(Map%3CString, Object%3E map, Class%3CE%3E objectClass) throws InstantiationException, IllegalAccessException %7B%0A        E obj = objectClass.newInstance();%0A        Field%5B%5D fields = getBeanFields(objectClass, true);%0A        %0A        for (Field field : fields) %7B%0A            if(Modifier.isStatic(field.getModifiers())) %7B%0A                continue;%0A            %7D%0A            %0A            if ((field.getType() == String.class)) %7B%0A                setFieldValue(obj, field, map.get(field.getName()));%0A            %7D else if(field.getType().isEnum()) %7B%0A                Object value = map.get(field.getName());%0A                if(value != null) %7B%0A                    setFieldValue(obj, field, Enum.valueOf((Class%3C? extends Enum%3E) field.getType(), (String) value));%0A                %7D%0A            %7D%0A        %7D%0A        %0A        return obj;%0A    %7D%0A    %0A    private static void setFieldValue(Object obj, Field field, Object value) throws IllegalArgumentException, IllegalAccessException %7B%0A        boolean accessible = field.isAccessible();%0A        field.setAccessible(true);%0A        field.set(obj, value);%0A        field.setAccessible(accessible);%0A    %7D%0A
 %7D%0A

read map as object