package com.steering.pss.plnsaleord.processOrder.base;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.regex.Matcher;

import net.sf.json.JSON;
import net.sf.json.JSONObject;
import net.sf.json.util.PropertyFilter;

public class EntityTool {
	
	/**
	 * @param src
	 *            源字符串
	 * @return 字符串，将src的第一个字母转换为大写，src为空时返回null
	 */
	public static String change(String src) {
		if (src != null) {
			StringBuffer sb = new StringBuffer(src);
			sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
			return sb.toString();
		} else {
			return null;
		}
	}
	/**
	 * 将对象属性NULL转化为空字符串
	 * 
	 * @param obj
	 */
	public static void nullConverNullString(Object obj) {
		if (obj != null) {

			Class<? extends Object> classz = obj.getClass();
			// 获取所有该对象的属性值
			Field fields[] = classz.getDeclaredFields();
			// 遍历属性值，取得所有属性为 null 值的
			for (Field field : fields) {
				try {
					Type t = field.getGenericType();
					if (!t.toString().equals("boolean")) {
						Method m = classz.getMethod("get"
								+ change(field.getName()));
						Object name = m.invoke(obj);// 调用该字段的get方法
						if (name == null) {

							Method mtd = classz.getMethod(
									"set" + change(field.getName()),
									new Class[] { String.class });// 取得所需类的方法对象
							mtd.invoke(obj, new Object[] { "" });// 执行相应赋值方法
						}
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
     * 生成SQL where条件字符串 "and condition in('args[1],args[2],...')"  AND  IN 
     * @param column 条件列
     * @param args 条件参数
     * @return String sql条件字符串
     */
    public static String toSqlConditionString(String column, String[] args) {
        StringBuffer str = new StringBuffer();
        if (args != null && args.length > 0) {
            str.append(" AND ");
            str.append(column.toUpperCase());
            str.append(" IN (");
            for (String arg : args) {
                if (arg != null) {
                    str.append("'");
                    str.append(arg);
                    str.append("', ");
                }
            }
            str.deleteCharAt(str.lastIndexOf(","));
            str.append(")");
        }
        return str.toString();
    }
    
    /**
     * 用实体类的值替换Sql中定义的 #字段名# 参数。
     * @param sql sql语句
     * @param obj 实体类对象
     * @return 替换后的sql语句。
     */
    public static String fillSqlByEntity(String sql, Object obj) {
    	String sql2 = sql;
		Class<?> cls = obj.getClass();
		Field[] fields = cls.getDeclaredFields();
		for (Field field : fields) {
			if (field.getGenericType().toString()
					.equals("class java.lang.String")) {
				try {
					String fieldName = getMethodName(field.getName());
					Method m = (Method) obj.getClass().getMethod(
							"get" + fieldName);
					String val = (String) m.invoke(obj);//
					val = val == null ? "" : val;
					String sqlFieldName = "#" + getSqlFieldName(fieldName)
							+ "#";
					val = val.replaceAll("'", "''");
					sql2 = sql2.replaceAll(sqlFieldName, Matcher.quoteReplacement(val));
				} catch (Exception e) {
					continue;
				}
			}
		}

		return sql2;
    }

    // 比如： StdCode转换为 STD_CODE
    private static String getSqlFieldName(String fieldName) {
        StringBuilder sb = new StringBuilder(fieldName);
        for (int i = 1; i < sb.length(); i++) {
            char ch = sb.charAt(i);
            if (Character.isUpperCase(ch)) {
                sb.insert(i, '_');
                i++;
            }
        }

        return sb.toString().toUpperCase();
    }
    
    public static String toLowercaseFirst(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }
    

    private static String getMethodName(String fildeName) throws Exception {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }

    /**
     * 获取实体类集合
     * @param rs 结果集
     * @param cls 实体类的类型
     * @return 实体类集合
     */
    public static <T> ArrayList<T> getEntitysByRs(ResultSet rs, Class<T> cls) {
        ArrayList<T> list = new ArrayList<T>();
        Method[] methods = cls.getMethods();
        HashMap<String, Method> map = new HashMap<String, Method>();

        for (int i = 0; i < methods.length; i++) {
            try {
                Method method = methods[i];
                String methodName = method.getName();
                if (methodName.startsWith("set")) {
                    String entityName = methodName.substring(3,
                            methodName.length());
                    String fieldName = getSqlFieldName(entityName);
                    if (rs.findColumn(fieldName) > 0) {
                        map.put(fieldName, method);
                    }
                }
            }
            catch (Exception e) {
            }
        }

        try {
            while (rs.next()) {
                T obj = cls.newInstance();
                Iterator<Entry<String, Method>> iter = map.entrySet()
                        .iterator();
                while (iter.hasNext()) {
                    Entry<String, Method> entry = iter.next();
                    String key = entry.getKey();
                    Method val = entry.getValue();
                    String strValue = rs.getString(key);
                    strValue = strValue == null ? "" : strValue;
                    val.invoke(obj, strValue);
                }
                list.add(obj);
            }
        }
        catch (Exception e) {
            return list;
        }
        return list;
    }

    /**
     * 通过sql获取实体类集合（不关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> ArrayList<T> getEntitysBySqlNoClsCon(String sql,
            Connection con, Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntitysByRs(rs, cls);
        }
        catch (SQLException e) {

        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }
    
    /**
     * 通过sql获取实体类（不关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> T getEntityBySqlNoClsCon(String sql,
            Connection con, Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntityByRs(rs, cls);
        }
        catch (SQLException e) {
        	e.printStackTrace();
        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }

    /**
     * 通过sql获取实体类集合（关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> ArrayList<T> getEntitysBySql(String sql, Connection con,
            Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntitysByRs(rs, cls);
        }
        catch (SQLException e) {

        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
            if (con != null) {
                try {
                    con.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }
    
    /**
     * 通过sql获取实体类（关闭Connection）
     * @param sql
     * @param con
     * @param cls
     * @return
     */
    public static <T> T getEntityBySql(String sql, Connection con,
            Class<T> cls) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            return getEntityByRs(rs, cls);
        }
        catch (SQLException e) {

        }
        finally {
            if (rs != null) {
                try {
                    rs.close();
                }
                catch (Exception ex) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                }
                catch (Exception ex) {
                }
            }
            if (con != null) {
                try {
                    con.close();
                }
                catch (Exception ex) {
                }
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getEntityByJSONStr(String strJSON, Class<T> cls) {
    	T list = null;
    	Method[] methods = cls.getMethods();
    	HashMap<String, Method> map = new HashMap<String, Method>();
    	JSONObject jsonObject = JSONObject.fromObject(strJSON);
    	for (int i = 0; i < methods.length; i++) {
    		try {
    			Method method = methods[i];
    			String methodName = method.getName();
    			if (methodName.startsWith("set")) {
                    String entityName = methodName.substring(3,
                            methodName.length());
                    String fieldName = toLowercaseFirst(entityName);
                    if (jsonObject.containsKey(fieldName)) {
                        map.put(fieldName, method);
                    }
                }
    		}catch (Exception e) {
                return list;
            }
    	}
    	try {
                T obj = cls.newInstance();
                Iterator<Entry<String, Method>> iter = map.entrySet()
                        .iterator();
                while (iter.hasNext()) {
                    Entry<String, Method> entry = iter.next();
                    String key = entry.getKey();
                    Method val = entry.getValue();
                    String strValue = jsonObject.getString(key);
                    strValue = strValue == null ? "" : strValue;
                    val.invoke(obj, strValue);
                }
                list = obj;
        }
        catch (Exception e) {
            return list;
        }
      //  T tEntity = (T) JSONObject.toBean(obj, cls);
        return list;
    }
    
//    /**
//     * 通过谷歌的Gson转换实体类
//     * @param json
//     * @param cls
//     * @return
//     */
//    public static<T> T getEntityByGson(String json, Class<T> cls){
//    	Gson gson = new Gson();
//    	return gson.fromJson(json, cls);
//    }
//    
//    /**
//     * 通过谷歌的Gson转换实体类
//     * @param json
//     * @param cls
//     * @return
//     */
//    public static<T> ArrayList<T> getEntitysByGson(String json, Type listType){
//    	Gson gson = new Gson();
//    	return gson.fromJson(json, listType);
//    }
//    
//    
//    /**
//     * 通过谷歌的Gson转换为字符串
//     * @param src
//     * @return
//     */
//    public static String getGsonByEntity(Object src){
//    	Gson gson = new Gson();
//    	return gson.toJson(src);
//    }

    /**
     * 通过结果集RS获取单个实体类
     * @param rs
     * @param cls
     * @return
     */
    public static <T> T getEntityByRs(ResultSet rs, Class<T> cls) {
        T list = null;
        Method[] methods = cls.getMethods();
        HashMap<String, Method> map = new HashMap<String, Method>();

        for (int i = 0; i < methods.length; i++) {
            try {
                Method method = methods[i];
                String methodName = method.getName();
                if (methodName.startsWith("set")) {
                    String entityName = methodName.substring(3,
                            methodName.length());
                    String fieldName = getSqlFieldName(entityName);
                    if (rs.findColumn(fieldName) > 0) {
                        map.put(fieldName, method);
                    }
                }
            }
            catch (Exception e) {
            }
        }

        try {
            if (rs.next()) {
                T obj = cls.newInstance();
                Iterator<Entry<String, Method>> iter = map.entrySet()
                        .iterator();
                while (iter.hasNext()) {
                    Entry<String, Method> entry = iter.next();
                    String key = entry.getKey();
                    Method val = entry.getValue();
                    String strValue = rs.getString(key);
                    strValue = strValue == null ? "" : strValue;
                    val.invoke(obj, strValue);
                }
                list = obj;
            }
        }
        catch (Exception e) {
            return list;
        }
        return list;
    }
    
    /**
     * 获取实体类指定方法的值。
     * @param obj
     * @param methodName
     * @return
     */
    @SuppressWarnings("all")
    public static String getValue(Object obj, String fieldName){
    	try {
			Method method = obj.getClass().getMethod("get" + fieldName, new Class[0]);
			
			return method.invoke(obj, new Object[0]).toString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	return "";
    }
    
//    /**
//     * 复制数据
//     * @param srcObj
//     * @param desObj
//     */
//    public static <T> T copy(Object srcObj, Class<T> cls){
//    	return getEntityByGson(getGsonByEntity(srcObj), cls);
//    }
}
