package com.qmth.qrzk.repository.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/******
 * Bean辅助类
 * 
 * @author YeFeng
 * @version 1.0
 * @date 2014年3月21日
 */
public class BeanHelper {

	public static <T> T copyEntity(Class<T> clazz, Object object) {
		T entity = null;
		try {
			entity = clazz.newInstance();
		} catch (Exception e) {
		}
		if (entity == null)
			return null;
		if (object == null)
			return entity;
		for (Field field : object.getClass().getDeclaredFields()) {
			Field cField = null;
			try {
				cField = clazz.getDeclaredField(field.getName());
			} catch (Exception e) {
			}
			if (cField == null)
				continue;
			field.setAccessible(true);
			cField.setAccessible(true);
			try {
				cField.set(entity, field.get(object));
			} catch (Exception e) {

			}
		}
		return entity;
	}

	public static void setFieldByMethod(Object entity, String fieldName, Object value) {
		Field field = null;
		try {
			field = entity.getClass().getDeclaredField(fieldName);
		} catch (Exception e) {

		}
		if (field == null || (field.getModifiers() != 2 && field.getModifiers() != 4)) {
			// 判断父类,如果是object
			if (entity.getClass().getSimpleName().equalsIgnoreCase("Object"))
				return;
			try {
				field = entity.getClass().getSuperclass().getDeclaredField(fieldName);
			} catch (Exception e) {

			}
			if (field == null || (field.getModifiers() != 2 && field.getModifiers() != 4))
				return;
		}
		Method method = null;
		try {
			method = entity.getClass().getMethod("set" + General.upperFirstChar(fieldName), (Class<?>) field.getGenericType());
		} catch (Exception e) {
		}
		if (method == null){
			setFiledValue(entity, field, value);
		}else{
			try {
				method.invoke(entity, value);
			} catch (Exception e) {
				// 调用方法出现错误是，直接试着属性
				setFiledValue(entity, field, value);
			}
		}
	}

	/*****
	 * 设置clazz类型的静态变量
	 */
	public static void setStaticField(Class<?> clazz, Map<String, ?> paramMap) {
		// 递归对父类进行赋值
		Class<?> superClass = clazz.getSuperclass();
		if (!superClass.getSimpleName().equalsIgnoreCase("Object")) {
			setStaticField(superClass, paramMap);
		}

		// 设置自身的类型
		for (Field field : clazz.getDeclaredFields()) {
			// public static getModifiers =9
			// private static getModifiers =10
			if ((field.getModifiers() == 9 || field.getModifiers() == 10) && paramMap.containsKey(field.getName())) {
				// 设置为可修改属性
				setFiledValue(null, field, paramMap.get(field.getName()));
			}
		}

	}

	/******
	 * 通过反射设置属性值，需要对属性进行判断
	 */
	public static void setFiledValue(Object object, Field field, Object value) {
		// 禁止设置null值
		if (value == null)
			return;
		String fieldType = field.getGenericType().toString().toLowerCase();
		// System.out.println("[" + field.getName() + "]" + fieldType);
		if (fieldType.indexOf(".") > -1)
			fieldType = fieldType.substring(fieldType.lastIndexOf(".") + 1);
		field.setAccessible(true);

		String vValue = value.toString();
		// 如果类型相同，纸质设置
		if (fieldType.equals(value.getClass().getSimpleName().toLowerCase())) {
			try {
				field.set(object, value);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (fieldType.equals("int") || fieldType.equals("integer")) {
			// int类型
			try {
				field.set(object, Integer.parseInt(vValue));
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (fieldType.equals("float")) {
			// Float类型
			try {
				field.set(object, Float.parseFloat(vValue));
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (fieldType.equals("double")) {
			// Double类型
			try {
				field.set(object, Double.parseDouble(vValue));
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (fieldType.equals("bigdecimal")) {
			// BigDecimal类型
			try {
				field.set(object, BigDecimal.valueOf(Double.parseDouble(vValue)));
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (fieldType.equals("boolean")) {
			// boolean类型
			if (value.toString().equalsIgnoreCase("false"))
				try {
					field.set(object, false);
				} catch (Exception e) {
					e.printStackTrace();
				}
			else if (value.toString().equalsIgnoreCase("true"))
				try {
					field.set(object, true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			else {
				// 入股哦是其他字符，大于0的数字为true，其他全部设置为false
				int sValue = 0;
				try {
					sValue = Integer.parseInt(value.toString());
				} catch (Exception e) {
				}
				try {
					if (sValue > 0)
						field.set(object, true);
					else
						field.set(object, false);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		} else if (fieldType.equals("date")) {
			// 日期格式
			if (vValue.indexOf("-") == -1) {
				// 没有分隔符
				if (vValue.length() == 8) {
					// yyyyMMdd格式
					try {
						field.set(object, DateHelper.shortSimpleDateFormatWithoutSplit.parse(vValue));
					} catch (Exception e) {
					}
				} else if (vValue.length() == 14) {
					// yyyyMMddHHmmss格式
					try {
						field.set(object, DateHelper.longSimpleDateFormatWithoutSplit.parse(vValue));
					} catch (Exception e) {
					}
				}
			} else {
				// 有分隔符
				// System.out.println(vValue.length());
				if (vValue.length() == 8) {
					// yyyyMMdd格式
					try {
						field.set(object, DateHelper.shortSimpleDateFormat.parse(vValue));
					} catch (Exception e) {
					}
				} else if (vValue.length() == 19) {
					// yyyyMMddHHmmss格式
					try {
						field.set(object, DateHelper.longSimpleDateFormat.parse(vValue));
					} catch (Exception e) {
					}
				}
			}

		}
	}

	/********
	 * 把Entity属性值方放置到一个Map中
	 * 
	 * @param entity
	 *            :实体对象
	 * @return
	 */
	public static Map<String, Object> getMapFromEntity(Object entity) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (entity == null)
			return map;
		// 递归获取父类
		Class<?> clazz = entity.getClass();
		while (!clazz.getSimpleName().equalsIgnoreCase("Object")) {
			for (Field f : clazz.getDeclaredFields()) {

				// 只处理private　修饰符
				if (f.getModifiers() != 2)
					continue;
				f.setAccessible(true);
				try {
					Object o = f.get(entity);
					if (o == null)
						continue;
					map.put(f.getName(), o);
				} catch (Exception e) {
					// throw new FieldException(f, "");
				}
			}
			clazz = clazz.getSuperclass();
		}

		return map;
	}

}
