package com.zzwtec.third.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 由于ice数据实体没有get/set方法 需要实现属性拷贝，需要重新封装方法
 * 
 * @author yangtonggan
 * @date 2016-3-11
 *
 */
public class BeanUtil {
	private static final Logger logger = LoggerFactory.getLogger(BeanUtil.class);

	/**
	 * 复制数组到List中
	 * 
	 * @param t1
	 * @param orig
	 * @return
	 */
	public static <T1, T2> List<T1> array2List(Class<T1> t1, T2[] orig) {
		List<T2> list = Arrays.asList(orig);
		return copyList(t1, list);
	}

	/**
	 * 复制List中数据到另一个List中
	 * 
	 * @param t1
	 * @param orig  
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T1, T2> List<T1> copyList(Class<T1> t1, List<T2> orig) {
		if(t1 == null) {
			throw new RuntimeException("param t1 is null");
		}
		if(orig == null) {
			throw new RuntimeException("param orig is null");
		}
		List<T1> list = new ArrayList<T1>();
		try {
			for (T2 m : orig) {
				Object dest = t1.newInstance();
				copyProperties(dest, m);
				list.add((T1) dest);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return list;

	}

	@SuppressWarnings("unchecked")
	public static <T1, T2> Collection<T1> copyCollection(Class<T1> t1, Collection<T2> orig) {
		if(t1 == null) {
			throw new RuntimeException("param t1 is null");
		}
		if(orig == null) {
			throw new RuntimeException("param orig is null");
		}
		Collection<T1> list = new ArrayList<T1>();
		try {
			for (T2 m : orig) {
				Object dest = t1.newInstance();
				copyProperties(dest, m);
				list.add((T1) dest);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return list;
	}

	/**
	 * javaBean属性值拷贝
	 * 空串和null值不进行拷贝
	 * @param dest
	 * @param orig
	 */
	public static void copyProperties(Object dest, Object orig) {
		try {
			if(dest == null) {
				throw new RuntimeException("目标对象为null，调用前需要检查参数");
			}
			if(orig == null) {
				throw new RuntimeException("源对象为null，调用前需要检查参数");
			}
			Class<?> c = orig.getClass();
			Field field[] = c.getDeclaredFields();
			Class<?> c1 = dest.getClass();
			
			for (Field f : field) {
				boolean flag = f.isAccessible();				
				String name = f.getName();
				f.setAccessible(true);
				Object value = f.get(orig);

				f.setAccessible(flag);
				
				try {					
					Field f1 = c1.getDeclaredField(name);
					if(f1 != null){
						boolean flag1 = f1.isAccessible();
						f1.setAccessible(true);
						f1.set(dest, value);
						f1.setAccessible(flag1);
					}
					

				} catch (Exception e) {
					logger.error("有异常",e);
					continue;
				}

			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
	public static void copyProperties(Object dest, Object orig, String... ignoreProperties) {
		if(dest == null) {
			throw new RuntimeException("目标对象为null，调用前需要检查参数");
		}
		if(orig == null) {
			throw new RuntimeException("源对象为null，调用前需要检查参数");
		}
		BeanUtils.copyProperties(orig, dest, ignoreProperties);
	}
	public static <T> T copyProperties(Class<T> targetClass, Object source) {
        T target = BeanUtils.instantiate(targetClass);
        BeanUtils.copyProperties(source, target);
        return target;
	}

	public static <T> T copyProperties(Class<T> targetClass, Object source, String... ignoreProperties) {
		T target = BeanUtils.instantiate(targetClass);
		BeanUtils.copyProperties(source, target, ignoreProperties);
		return target;
	}

    public static <T> T copyPropertiesWithNull(Class<T> targetClass, Object source) {
        if (targetClass == null || source == null) {
            return null;
        }
        T target = BeanUtils.instantiate(targetClass);
        BeanUtils.copyProperties(source, target);
        return target;
    }
}
