package com.ym.mec.util.collection;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

public class MapUtil {

	private static final Object[] EMPTY_ARRAY = {};

	/**
	* 将一个bean转换成map
	* @param map
	* @param bean
	* @return
	*/
	public static Map<String, Object> populateMap(Map<String, Object> map, Object bean) {
		return populateMap(map, bean, null);
	}

	/**
	 * 假设prefix=detail.，bean带有一个属性name，则map中将有一个项：
	 * key=detail.name，value为bean的name属性值。
	 */
	public static Map<String, Object> populateMap(Map<String, Object> map, Object bean, String prefix) {
		boolean withoutPrefix = StringUtils.isBlank(prefix);

		try {
			Method[] methods = bean.getClass().getMethods();
			for (int i = 0; i < methods.length; i++) {
				String methodName = methods[i].getName();
				Class<?>[] pts = methods[i].getParameterTypes();
				Class<?> rt = methods[i].getReturnType();

				if (methodName.startsWith("get") && pts.length == 0 && !Void.class.equals(rt)) {
					String propName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
					if ("class".equals(propName)) {
						continue;
					}

					String key = withoutPrefix ? propName : prefix + propName;

					Object value = methods[i].invoke(bean, EMPTY_ARRAY);
					if (value != null) {
						map.put(key, value);
					}
				}
			}

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

	/**
	 * map to javabean
	 * @param clazz
	 * @param map
	 * @return
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws IntrospectionException 
	 * @throws InstantiationException 
	 */
	@SuppressWarnings("rawtypes")
	public static <T> T mapToJavaBean(Class<T> clazz, Map map) throws IllegalAccessException, IllegalArgumentException, IntrospectionException,
			InstantiationException {
		T obj = null;
		BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
		obj = clazz.newInstance();
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
			if (map.containsKey(propertyName)) {
				Object value = map.get(propertyName);
				if ("".equals(value)) {
					value = null;
				}
				Object[] args = new Object[1];
				args[0] = value;
				try {
					descriptor.getWriteMethod().invoke(obj, args);
				} catch (InvocationTargetException e) {
					System.out.println("params poxy failed");
				}
			}
		}
		return (T) obj;
	}
}