package cn.qinys.platform.base.utils;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * code is far away from bug with the animal protecting
 *
 * @author v-lishiquan.gx@chinatelecom.cn
 * @description
 * @date Create in 2018/6/21 10:39
 */
public class BeanExUtils extends BeanUtils {

    private BeanExUtils() {
    }

    private static String[] getNullPropertyNames(Object source, boolean flag) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (Objects.isNull(srcValue)) {
                emptyNames.add(pd.getName());
            }
            if (flag && srcValue instanceof String) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 复制的时候忽略null而不忽略String的""
     *
     * @param src    源对象
     * @param target 目标对象
     */
    public static void copyPropertiesIgnoreNull(Object src, Object target) {
        copyProperties(src, target, getNullPropertyNames(src, false));
    }

    /**
     * 复制的时候忽略null和String的"",空串
     * 参考apache的StringUtils.isBlank()
     *
     * @param src    源对象
     * @param target 目标对象
     */
    public static void copyPropertiesIgnoreBlank(Object src, Object target) {
        copyProperties(src, target, getNullPropertyNames(src, true));
    }

    public static <T, K> T convert(K obj, Class<T> cls) {
        try {
            if (obj == null) {
                return cls.newInstance();
            }
            T t = cls.newInstance();
            copyPropertiesIgnoreNull(obj, t);
            return t;
        } catch (Exception ex) {
            throw new ClassCastException("转换类型错误");
        }
    }

}
