package com.scpyun.platform.jilinsscgsdp.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

/**
 * @Author liujunyan
 */
public class BeanUtils extends org.springframework.beans.BeanUtils {

    public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) {
        return copyListProperties(sources, target, null);
    }

    /**
     * 使用场景：Entity、Bo、Vo层数据的复制，因为BeanUtils.copyProperties只能给目标对象的属性赋值，却不能在List集合下循环赋值，因此添加该方法
     * 如：List<AdminEntity> 赋值到 List<AdminVo> ，List<AdminVo>中的 AdminVo 属性都会被赋予到值
     * S: 数据源类 ，T: 目标类::new(eg: AdminVo::new)
     */
    public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, PeachBeanUtilsCallBack<S, T> callBack) {
        List<T> list = new ArrayList<>(sources.size());
        for (S source : sources) {
            T t = target.get();
            copyProperties(source, t);
            if (callBack != null) {
                // 回调
                callBack.callBack(source, t);
            }
            list.add(t);
        }
        return list;
    }

    @FunctionalInterface
    public interface PeachBeanUtilsCallBack<S, T> {

        void callBack(S t, T s);
    }


    /**
     * 合并对象
     *
     * @param source 数据源对象
     * @param target 需要得到的对象
     * @return
     */
    public static Object mergerData(Object source, Object target) {
        Field[] sourceFields = source.getClass().getDeclaredFields();
        Field[] targetFields = target.getClass().getDeclaredFields();
        try {
            for (int i = 0; i < sourceFields.length; i++) {
                Field sourceField = sourceFields[i];
                //这里遍历主要是为了适应双方对象属性顺序不一致的情况
                for (int j = 0; j < targetFields.length; j++) {
                    Field targetField = targetFields[j];
                    if (sourceField.getName().equals(targetField.getName())) {
                        sourceField.setAccessible(true);
                        targetField.setAccessible(true);
                        if (!(sourceField.get(source) == null)) {
                            targetField.set(target, sourceField.get(source));
                        }
                    }
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return target;
    }
}
