package com.house365.web.util;

import java.util.List;

import org.springframework.beans.BeanUtils;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

/**
 * 复制POJO对象属性值的工具类
 * @author zhaodeshan
 * @version [版本号, 2015年2月3日]
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public final class PropertyCopy {
    /**
     * 复制源对象的属性值设置到目标对象中
     * @author zhaodeshan
     * @version [版本号, 2015年2月3日]
     * @param source 被复制属性值的源对象
     * @param target 获取复制属性值的目标对象
     * @since [产品/模块版本](可选)
     */
    public static void copyProperties(Object source,Object target){
        /*BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        copier.copy(source, target, null);*/
        BeanUtils.copyProperties(source, target);
    }
    
    /**
     * 获取一个复制源对象属性值的新对象
     * @author zhaodeshan
     * @version [版本号, 2015年2月3日]
     * @param source 被复制属性值的源对象
     * @param claxx 新对象的类型
     * @return T 得到源对象属性值的新对象
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @since [产品/模块版本](可选)
     */
    public static <T> T createBeanWithProperties(Object source,Class<T> claxx) throws InstantiationException, IllegalAccessException{
        T result = claxx.newInstance();
        copyProperties(source, result);
        return result;
    }
    
    /**
     * 从已有的List中复制每个列表项的属性值构造一个新的List
     * @author zhaodeshan
     * @version [版本号, 2015年2月4日]
     * @param fromList 源List
     * @param claxx 新的List列表项的类型
     * @return List<T> 新的List
     * @since [产品/模块版本](可选)
     */
    public static <T, E> List<T> copyList(List<E> fromList,final Class<T> claxx) {
        return Lists.transform(fromList, new Function<E, T>() {
            public T apply(E from) {
                try {
                    return createBeanWithProperties(from, claxx);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
    }
}
