package com.platform.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.fasterxml.jackson.databind.PropertyNamingStrategy.UpperCamelCaseStrategy;

public class BeanCopy {
	
	/** 复制属性(子类父类等继承关系不可用)
	 * @param source 源对象
	 * @param dst 目标对象
	 * @param params 不复制的属性
	 * @throws Exception 
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 */
	public static void copyBean(Object source, Object dst, String... params) throws Exception{
		if (dst.getClass().getSuperclass() == source.getClass()) {
			fatherCopyChild(source, dst, params);
		}
		List<String> filter = new ArrayList<String>();
		filter.addAll(Arrays.asList(params));
		Field[] sourceField = source.getClass().getDeclaredFields();
		List<String> sourceFieldName = new ArrayList<String>();
		for (Field fie : sourceField) {
			sourceFieldName.add(fie.getName());
		}
		Field[] dstField = dst.getClass().getDeclaredFields();
		for (Field field : dstField) {
			String name = field.getName();
			if (filter.contains(name)) {
				continue;
			}
			if (sourceFieldName.contains(name)) {
				field.setAccessible(true);
				Object value;
//					Method m = source.getClass().getMethod("get"+upperHeadChar(name));
//					value = m.invoke(source);
					value = source.getClass().getDeclaredField(name).get(source);
					if (null != value) {
						field.set(dst, value);
					}
			}
		}
		
	}
	
	private static void fatherCopyChild(Object father, Object dst, String... params) throws Exception{
		List<String> filter = new ArrayList<String>();
		filter.addAll(Arrays.asList(params));
		if (dst.getClass().getSuperclass() == father.getClass()) {
			Class faClass = father.getClass();
			Field[] ff = faClass.getDeclaredFields();
			for (int i = 0; i < ff.length; i++) {
				Field f = ff[i];
				String name = f.getName();
				if (filter.contains(name)) {
					continue;
				}
				f.setAccessible(true);
				Class type = f.getType();
				Method m = faClass.getMethod("get"+upperHeadChar(f.getName()));
				Object obj = m.invoke(father);
				f.set(dst, obj);
			}
		}
	}
	
	private static String upperHeadChar(String in) {
		String head = in.substring(0,1);
		return head.toUpperCase()+in.substring(1, in.length());
	}

}