package cn.com.ty.lift.common.utils;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author huangyuan
 * @date 2019-12-01
 * @description 实体对象工具类
 */
public class PojoUtils {

    private static final String GET_METHOD_PREFIX = "get";//get方法名前缀
    private static final String SET_METHOD_PREFIX = "set";//set方法名前缀

    public static void pojoCopy(Object dest, Object orig){
        try {
            //info:进行beans拷贝，解决时间出现了空值而无法进行复制
            ConvertUtils.register(new DateConverter(null), Date.class);
            ConvertUtils.register(new DateConverter(null), BigDecimal.class);
            BeanUtils.copyProperties(dest, orig);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取属性get方法
     *@author huangy
     *@param attrName
     *@return String
     *@throws
     */
    public static String attrGetMethodName(String attrName) {
        return attrMethodName(GET_METHOD_PREFIX, attrName);
    }

    /**
     * 获取属性set方法
     *@author huangy
     *@param attrName
     *@return String
     *@throws
     */
    public static String attrSetMethodName(String attrName) {
        return attrMethodName(SET_METHOD_PREFIX, attrName);
    }

    /**
     * 获取属性对应方法 get，set
     *@author huangy
     *@date 2018年12月28日
     *@param methodNamePrefix
     *@param attrName
     *@return String
     *@throws
     */
    private static String attrMethodName(String methodNamePrefix,String attrName) {
        return methodNamePrefix + attrName.substring(0, 1).toUpperCase() + attrName.substring(1);
    }

    /**
     * 将B中有值的属性赋值给A
     *@author huangyuan
     *@param pojoA
     *@param pojoB void
     *@throws
     */
    public static void copy(Object pojoA, Object pojoB) {
        //获取A的所以字段
        Field[] fields = pojoB.getClass().getDeclaredFields();
        if(fields != null && fields.length > 0) {
            for(Field field: fields) {
                //获取属性名
                String fieldName = field.getName();
                //获取B对象属性的值
                Object value = getPojoFieldValue(pojoB, fieldName);
                if(value != null && value != "") {
                    //将对象B的值赋给对象A
                    setPojoFieldValue(pojoA, fieldName, value);
                }
            }
        }
    }

    /**
     * 给实体指定私有字段设置值
     *@author huangyuan
     *@param pojo
     *@param fieldName
     *@param fieldValue void
     *@throws
     */
    public static void setPojoFieldValue(Object pojo, String fieldName, Object fieldValue) {
        try {
            //首先判断字段是否存在
            if(judgePirvateFieldExist(pojo, fieldName)) {
                Field field = pojo.getClass().getDeclaredField(fieldName);
                Method setField = pojo.getClass().getMethod(attrSetMethodName(fieldName), field.getType());
                setField.invoke(pojo, fieldValue);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取实体指定私有字段的值
     *@author huangyuan
     *@param pojo
     *@param fieldName
     *@return Object
     *@throws
     */
    public static Object getPojoFieldValue(Object pojo, String fieldName) {

        Object fieldValue = null;
        try {
            //首先判断字段是否存在
            if(judgePirvateFieldExist(pojo, fieldName)) {
                Method getField = pojo.getClass().getMethod(attrGetMethodName(fieldName));
                fieldValue = getField.invoke(pojo, null);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
        return fieldValue;
    }

    /**
     * 判断指定私有字段是否存在
     *@author huangyuan
     *@param pojo
     *@param fieldName
     *@return boolean
     *@throws
     */
    public static boolean judgePirvateFieldExist(Object pojo, String fieldName) {
        Field[] fields = pojo.getClass().getDeclaredFields();
        if(fields != null && fields.length > 0) {
            for(Field field: fields) {
                if(field.getName().equals(fieldName)){
                    return true;
                }
            }
        }
        return false;
    }
}
