All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.freegeese.maven.plugin.autocode.BeanPropertyUtils Maven / Gradle / Ivy

There is a newer version: 1.1
Show newest version
package com.github.freegeese.maven.plugin.autocode;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Bean属性操作工具
 */
public class BeanPropertyUtils {

    private static Map> fieldCache = new HashMap<>();

    private static SimpleDateFormat sdf = new SimpleDateFormat();

    /**
     * 合并 target 对象非空字段值 到 source 对象
     *
     * @param source
     * @param target
     * @param moreTargets
     */
    public static void merge(Object source, Object target, Object... moreTargets) {
        if (null == target) {
            return;
        }
        merge(source, target);
        if (null != moreTargets) {
            for (Object moreTarget : moreTargets) {
                merge(source, moreTarget);
            }
        }
    }

    private static void merge(Object source, Object target) {
        Class cls = source.getClass();
        List fields = getDeclaredFields(cls, true);
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object targetFieldValue = field.get(target);
                if (null != targetFieldValue) {
                    setFieldValue(source, field, targetFieldValue);
                }
            } catch (IllegalAccessException | NoSuchFieldException e) {
                e.printStackTrace();
            } finally {
                field.setAccessible(false);
            }
        }
    }

    /**
     * Map转换为Bean
     *
     * @param map
     * @param bean
     * @return
     */
    public static Object mapToBean(Map map, Object bean) {
        List fields = getDeclaredFields(bean.getClass(), true);
        Map fieldNameMap = new HashMap<>();
        for (Field field : fields) {
            fieldNameMap.put(field.getName(), field);
        }
        Set keys = map.keySet();
        for (Object key : keys) {
            if (fieldNameMap.containsKey(key)) {
                Field field = fieldNameMap.get(key);
                field.setAccessible(true);
                try {
                    setFieldValue(bean, field, map.get(key));
                } catch (IllegalAccessException | NoSuchFieldException e) {
                    e.printStackTrace();
                } finally {
                    field.setAccessible(false);
                }
            }
        }
        return bean;
    }

    /**
     * 设置字段的值
     *
     * @param target 目标对象
     * @param field  字段
     * @param value  字段值
     * @return 目标对象
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private static Object setFieldValue(Object target, Field field, Object value) throws NoSuchFieldException, IllegalAccessException {
        notNull(target);
        notNull(field);

        if (value == null) {
            return target;
        }
        // 字段类型
        field.setAccessible(true);
        Class fieldType = field.getType();

        Class valueClass = value.getClass();
        // 值不是String类型,直接设置
        if (String.class != valueClass) {
            // TODO: 2016/11/7 为了兼容枚举类型的copy
            // 枚举
            if (valueClass.isEnum()) {
                return setFieldValue(target, field, value.toString());
            }
            // 枚举数组
            if (valueClass.isArray() && valueClass.getComponentType().isEnum()) {
                StringBuffer enumValues = new StringBuffer(Array.get(value, 0).toString());
                int length = Array.getLength(value);
                for (int i = 1; i < length; i++) {
                    enumValues.append(",").append(Array.get(value, i).toString());
                }
                return setFieldValue(target, field, enumValues.toString());
            }
            field.set(target, value);
            return target;
        }

        // 值是String类型,可能存在多种情况
        String valueString = value.toString().trim();

        // 字段为String类型
        if (String.class == fieldType) {
            field.set(target, valueString);
            return target;
        }

        // 字段为基本类型
        if (int.class == fieldType || Integer.class == fieldType) {
            field.set(target, Integer.valueOf(valueString));
            return target;
        }
        if (long.class == fieldType || Long.class == fieldType) {
            field.set(target, Long.valueOf(valueString));
            return target;
        }
        if (double.class == fieldType || Double.class == fieldType) {
            field.set(target, Double.valueOf(valueString));
            return target;
        }
        if (float.class == fieldType || Float.class == fieldType) {
            field.set(target, Float.valueOf(valueString));
            return target;
        }
        if (short.class == fieldType || Short.class == fieldType) {
            field.set(target, Short.valueOf(valueString));
            return target;
        }
        if (byte.class == fieldType || Byte.class == fieldType) {
            field.set(target, Short.valueOf(valueString));
            return target;
        }
        if (Boolean.class == fieldType || boolean.class == fieldType) {
            field.set(target, Boolean.valueOf(valueString));
            return target;
        }

        // 字段为大数字类型
        if (BigDecimal.class == fieldType) {
            BigDecimal.valueOf(Double.valueOf(valueString));
            return target;
        }
        if (BigInteger.class == fieldType) {
            BigInteger.valueOf(Long.valueOf(valueString));
            return target;
        }

        // 字段为日期类型
        if (Date.class == fieldType) {
            String dateString = valueString.replaceAll("[\\s\\-\\/\\:\\.]*", "");

            switch (dateString.length()) {
                case 4:
                    sdf.applyPattern("yyyy");
                    break;
                case 6:
                    sdf.applyPattern("yyyyMM");
                    break;
                case 8:
                    sdf.applyPattern("yyyyMMdd");
                    break;
                case 10:
                    sdf.applyPattern("yyyyMMddHH");
                    break;
                case 12:
                    sdf.applyPattern("yyyyMMddHHmm");
                    break;
                case 14:
                    sdf.applyPattern("yyyyMMddHHmmss");
                    break;
                case 17:
                    sdf.applyPattern("yyyyMMddHHmmssSSS");
                    break;
                default:
                    throw new IllegalArgumentException("不支持的日期格式:" + valueString);
            }
            try {
                field.set(target, sdf.parse(dateString));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return target;
        }

        // 字段为枚举类型
        if (fieldType.isEnum()) {
            field.set(target, Enum.valueOf(fieldType, valueString));
            return target;
        }

        if (fieldType.isArray()) {
            String[] elements = valueString.split(",");
            if (elements.length > 0) {
                // 元素类型
                Class componentType = fieldType.getComponentType();

                // 字符串类型
                if (String.class == componentType) {
                    field.set(target, elements);
                    return target;
                }


                Object arr = Array.newInstance(componentType, elements.length);
                int index = 0;
                // 枚举类型
                if (componentType.isEnum()) {
                    for (String element : elements) {
                        Array.set(arr, index++, Enum.valueOf(componentType, element.trim()));
                    }
                    field.set(target, arr);
                    return target;
                }

                // TODO 其他类型处理
            }

        }

        throw new IllegalArgumentException("不支持的字段类型处理:" + fieldType);
    }

    /**
     * 复制属性到一个Map
     *
     * @param bean 来源对象
     * @return 目标Map
     */
    public static Map beanToMap(Object bean) {
        return beanToMap(bean, (List) null);
    }

    /**
     * 复制属性到一个Map
     *
     * @param bean     来源对象
     * @param includes 需要复制的属性
     * @return 目标Map
     */
    public static Map beanToMap(Object bean, List includes) {
        return (Map) copy(bean, new HashMap(), includes, null);
    }

    /**
     * 复制属性到一个Map
     *
     * @param bean     来源对象
     * @param excludes 不需要复制的属性
     * @return 目标Map
     */
    public static Map beanToMap(Object bean, String... excludes) {
        return (Map) copy(bean, new HashMap(), null, Arrays.asList(excludes));
    }

    /**
     * 复制属性到一个Map
     *
     * @param beans 来源对象
     * @return 目标Map
     */
    public static List beanToMap(List beans) {
        return beanToMap(beans, (List) null);
    }

    /**
     * 复制属性到一个Map
     *
     * @param beans    来源对象
     * @param includes 需要复制的属性
     * @return 目标Map集合
     */
    public static List beanToMap(List beans, List includes) {
        List toList = new ArrayList<>();
        for (Object o : beans) {
            toList.add(beanToMap(o, includes));
        }
        return toList;
    }

    /**
     * 复制属性到一个Map
     *
     * @param beans    来源对象
     * @param excludes 需要排除的属性
     * @return 目标Map集合
     */
    public static List beanToMap(List beans, String... excludes) {
        List toList = new ArrayList<>();
        for (Object o : beans) {
            toList.add(beanToMap(o, excludes));
        }
        return toList;
    }

    /**
     * 对象属性复制
     *
     * @param from 来源对象
     * @param to   目标对象
     */
    public static Object copy(Object from, Object to) {
        return copy(from, to, null, null);
    }

    /**
     * 对象属性复制
     *
     * @param from     来源对象
     * @param to       目标对象
     * @param includes 指定需要复制的属性
     */
    public static Object copy(Object from, Object to, List includes) {
        return copy(from, to, includes, null);
    }

    /**
     * 对象属性复制
     *
     * @param from     来源对象
     * @param to       目标对象
     * @param excludes 排除不需要复制的属性
     */
    public static Object copy(Object from, Object to, String... excludes) {
        return copy(from, to, null, Arrays.asList(excludes));
    }

    /**
     * 对象属性复制
     *
     * @param from 来源对象
     * @param to   目标类
     * @param   目标对象类型
     * @return 目标对象
     */
    public static  T copy(Object from, Class to) {
        return copy(from, to, (List) null);
    }

    /**
     * 对象属性复制
     *
     * @param from     来源对象
     * @param to       目标类
     * @param excludes 指定不需要复制的属性
     * @param       目标对象类型
     * @return 目标对象
     */
    public static  T copy(Object from, Class to, String... excludes) {
        T t = null;
        try {
            t = to.newInstance();
            copy(from, t, null, Arrays.asList(excludes));
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return t;
    }

    /**
     * 对象属性复制
     *
     * @param from     来源对象
     * @param to       目标类
     * @param includes 指定需要复制的属性
     * @param       目标对象类型
     * @return 目标对象
     */
    public static  T copy(Object from, Class to, List includes) {
        T t = null;
        try {
            t = to.newInstance();
            copy(from, t, includes, null);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return t;
    }

    /**
     * 对象属性复制
     *
     * @param from 来源对象集合
     * @param to   目标类
     * @param   目标对象类型
     * @return 目标对象集合
     */
    public static  List copy(List from, Class to) {
        return copy(from, to, (List) null);
    }

    /**
     * 对象属性复制
     *
     * @param from     来源对象集合
     * @param to       目标类
     * @param excludes 制定不需要复制的属性
     * @param       目标对象类型
     * @return 目标对象集合
     */
    public static  List copy(List from, Class to, String... excludes) {
        List toList = new ArrayList<>();
        for (Object o : from) {
            toList.add(copy(o, to, excludes));
        }
        return toList;
    }

    /**
     * 对象属性复制
     *
     * @param from     来源对象
     * @param to       目标对象
     * @param includes 指定需要复制的属性
     * @param       目标对象类型
     * @return 目标对象集合
     */
    public static  List copy(List from, Class to, List includes) {
        List toList = new ArrayList<>();
        for (Object o : from) {
            toList.add(copy(o, to, includes));
        }
        return toList;
    }

    /**
     * 属性复制
     *
     * @param from     来源对象
     * @param to       目标对象
     * @param includes 指定需要复制的属性(includes 优先于 excludes)
     * @param excludes 指定不需要复制的属性
     */
    private static Object copy(Object from, Object to, List includes, List excludes) {
        notNull(from);
        notNull(to);

        // 检查是否有需要导入或排除的属性
        boolean hasIncludes = (null != includes && !includes.isEmpty());
        boolean hasExcludes = false;
        if (!hasIncludes) {
            hasExcludes = (null != excludes && !excludes.isEmpty());
        }

        // 来源字段
        Class fromClass = from.getClass();
        List fromFields = getDeclaredFields(fromClass, true);

        // 目标字段
        Class toClass = to.getClass();
        boolean isMap = Map.class.isAssignableFrom(toClass);
        Map toFieldMap = null;
        if (!isMap) {
            toFieldMap = new HashMap();
            List toFields = getDeclaredFields(toClass, true);
            for (Field toField : toFields) {
                toFieldMap.put(toField.getName(), toField);
            }
        }

        // 来源字段名称
        String fromFieldName;
        for (Field fromField : fromFields) {
            fromFieldName = fromField.getName();
            try {
                fromField.setAccessible(true);
                // 目标对象是Map类型
                if (isMap) {
                    ((Map) to).put(fromFieldName, fromField.get(from));
                    continue;
                }
                // 目标对象是Bean类型
                if (toFieldMap.containsKey(fromFieldName)) {
                    // 有需要导入的
                    if (hasIncludes && !includes.contains(fromFieldName)) {
                        continue;
                    }
                    // 有需要排除的
                    if (hasExcludes && excludes.contains(fromFieldName)) {
                        continue;
                    }
                    // 设置目标对象字段的值
                    Field toField = toFieldMap.get(fromFieldName);
                    setFieldValue(to, toField, fromField.get(from));
                    // toField.set(to, fromField.get(from));
                }
            } catch (IllegalAccessException | NoSuchFieldException e) {
                System.err.println("属性访问异常:" + e.getMessage());
                e.printStackTrace();
            } finally {
                fromField.setAccessible(false);
            }
        }

        return to;
    }

    /**
     * 获取已经声明的字段
     *
     * @param aClass 目标类型
     * @param deep   是否深度获取(向上查找父类的字段)
     * @return 获取的字段集合
     */
    private static List getDeclaredFields(Class aClass, boolean deep) {
        // 从缓存中获取
        if (fieldCache.containsKey(aClass)) {
            return fieldCache.get(aClass);
        }
        List fieldsStore = new ArrayList<>();
        getFields(fieldsStore, aClass, true, deep);
        // TODO: 2016/11/7 静态字段过滤
        Iterator fieldIterator = fieldsStore.iterator();
        while (fieldIterator.hasNext()) {
            if (Modifier.isStatic(fieldIterator.next().getModifiers())) {
                fieldIterator.remove();
            }
        }
        // 添加到缓存
        fieldCache.put(aClass, fieldsStore);
        return fieldsStore;
    }

    /**
     * 获取字段
     *
     * @param findedFields 存放获取到字段的容器
     * @param aClass       目标类
     * @param declared     字段是否声明
     * @param deep         是否深度查找
     */
    private static void getFields(List findedFields, Class aClass, boolean declared, boolean deep) {
        if (Object.class != aClass) {
            Field[] fields = declared ? aClass.getDeclaredFields() : aClass.getFields();
            findedFields.addAll(Arrays.asList(fields));
            if (deep) {
                getFields(findedFields, aClass.getSuperclass(), declared, deep);
            }
        }
    }

    private static void notNull(Object object) {
        notNull(object, "[Assertion failed] - this argument is required; it must not be null");
    }

    private static void notNull(Object object, String message) {
        if (object == null) {
            throw new IllegalArgumentException(message);
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy