package com.library.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 泛类与map转换
 * @author Administrator
 *
 */
public class TransformationTools {
	
	
	/**
	 * 除掉避免sql注入的参数
	 */
	public static String TransactSQLInjection(String str){
          return str.replaceAll(".*([';]+|(--)+).*", " ");
       // 我认为 应该是return str.replaceAll("([';])+|(--)+","");
    }
	
	
	
	
	/**
	 * 转成类对象
	 */
	public static Object ToObjectOne(Class c ,Map<String, Object> map) throws Exception{
		Object object=c.newInstance();
		Field[] fields = c.getDeclaredFields();  
        for(int i=0; i<fields.length; i++){  
            Field f = fields[i];  
            f.setAccessible(true); 
            //System.out.println("属性名:" + f.getName() + " 属性值:" + f.getType());  
            setAttrributeValue(object, f.getName(), map.get(f.getName()));
        } 
		return object;
	}
	
	/**
	 * 转成类对象
	 */
	public static List<Object> ToObjectList(Class c ,List<Map<String, Object>> list_map) throws Exception{
		List<Object> list=new ArrayList<Object>();
		Field[] fields = c.getDeclaredFields();//获得所有属性集合
		
		for(Map<String, Object> map:list_map){
			Object object=c.newInstance();
	        for(int i=0; i<fields.length; i++){  
	            Field f = fields[i];  
	            f.setAccessible(true); 
	           setAttrributeValue(object, f.getName(), map.get(f.getName()));
	        }
	        list.add(object);
		}
		return list;
	}
	
	

    
    private static void setAttrributeValue(Object obj,String attribute,Object value)
    {
    	if(value==null){
    		return ;
    	}
        String method_name = convertToMethodName(attribute,obj.getClass(),true);
        Method[] methods = obj.getClass().getMethods();
        for (Method method : methods) {
            /**
             *     因为这里只是调用bean中属性的set方法，属性名称不能重复
             * 所以set方法也不会重复，所以就直接用方法名称去锁定一个方法
             * （注：在java中，锁定一个方法的条件是方法名及参数）
             * **/
            if(method.getName().equals(method_name))
            {
                Class[] parameterC = method.getParameterTypes();
                try {
                    /**如果是基本数据类型时（如int、float、double、byte、char、boolean）
                     * 需要先将Object转换成相应的封装类之后再转换成对应的基本数据类型
                     * 否则会报 ClassCastException**/
                    if(parameterC[0] == int.class)
                    {
                        method.invoke(obj,((Integer)value).intValue()); 
                        break;
                    }else if(parameterC[0] == float.class){
                        method.invoke(obj, ((Float)value).floatValue());
                        break;
                    }else if(parameterC[0] == double.class)
                    {
                        method.invoke(obj, ((Double)value).doubleValue());
                        break;
                    }else if(parameterC[0] == byte.class)
                    {
                        method.invoke(obj, ((Byte)value).byteValue());
                        break;
                    }else if(parameterC[0] == char.class)
                    {
                        method.invoke(obj, ((Character)value).charValue());
                        break;
                    }else if(parameterC[0] == boolean.class)
                    {
                        method.invoke(obj, ((Boolean)value).booleanValue());
                        break;
                    }else
                    {
                        method.invoke(obj,parameterC[0].cast(value));
                        break;
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } 
            }
        }
    }
	
    private static final String REGEX = "[a-zA-Z]";
	
    private static String convertToMethodName(String attribute,Class objClass,boolean isSet)
    {
        /** 通过正则表达式来匹配第一个字符 **/
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(attribute);
        StringBuilder sb = new StringBuilder();
        /** 如果是set方法名称 **/
        if(isSet)
        {
            sb.append("set");
        }else{
        /** get方法名称 **/
            try {
                Field attributeField = objClass.getDeclaredField(attribute);
                /** 如果类型为boolean **/
                if(attributeField.getType() == boolean.class||attributeField.getType() == Boolean.class)
                {
                    sb.append("is");
                }else
                {
                    sb.append("get");
                }
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        /** 针对以下划线开头的属性 **/
        if(attribute.charAt(0)!='_' && m.find())
        {
            sb.append(m.replaceFirst(m.group().toUpperCase()));
        }else{
            sb.append(attribute);
        }
        return sb.toString();
    }
    
    
	/**
	 * 生成修改的mysql语句
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * 第四个参数是，不需要生成sql的属性集合名称，可以是null
	 */
	public static String CreatUpdateMysql(Object object,String tableName,String key,List<String> list_attr){
		
		Field[] fields = object.getClass() .getDeclaredFields();//获得所有属性集合
		String mysql="update "+tableName+" set ";
		try {
			for(int i=0; i<fields.length; i++){  
				Field f = fields[i];
				f.setAccessible(true); 
				System.out.println("属性名:" + f.getName() + " 属性值:" + f.getType()+"---"+f.get(object));  
				
				boolean is_continue=false;
				//判断是不是不需要生成的属性
				if(list_attr!=null && list_attr.size()>0){
					for(String attr:list_attr){
						if(f.getName().equals(attr)){
							is_continue=true;
							break;
						}
					}
				}
				if(f.get(object)==null || is_continue){
					continue;
				}
				
				//运算出语句
				if(!f.getName().equals(key)){
					if((f.getType().toString().equals("class java.lang.String") || f.getType().toString().equals("class java.sql.Timestamp")
							|| f.getType().toString().equals("class java.sql.Time"))
							&& f.get(object)!=null){
						mysql+=f.getName()+"='"+TurnCharacter(f.get(object).toString())+"',";
					}else{
						mysql+=f.getName()+"="+f.get(object)+",";
					}
				}
			}
			mysql=mysql.substring(0, mysql.length()-1);
			//到where语句
			for(int i=0; i<fields.length; i++){  
				Field f = fields[i];
				f.setAccessible(true); 
				//运算出语句
				if(f.getName().equals(key)){
					if(f.getType().toString().equals("class java.lang.String")){
						mysql+=" where "+key+"='"+TurnCharacter(f.get(object).toString())+"'";
					}else{
						mysql+=" where "+key+"="+f.get(object);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(mysql);
		return mysql;
	}
	
	
	
	
	/**
	 * 生成添加的mysql语句
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * 第四个参数是，不需要生成sql的属性集合名称，可以是null
	 */
	public static String CreatAddMysql(Object object,String tableName,String key,List<String> list_attr){
		
//		insert into user (phone_num,password,username,nickname,address,head_img,points,invitee_id,time,openid)
//		values ( #{phone_num},#{password},#{username} ,#{nickname} ,#{address} ,#{head_img} ,#{points} ,#{invitee_id}  ,#{time},#{openid}  )
		
		Field[] fields = object.getClass() .getDeclaredFields();//获得所有属性集合
		String mysql="insert into "+tableName+" (";
		try {
			String attrSql="";//属性语句
			String valueSql="";//值语句
			for(int i=0; i<fields.length; i++){  
				Field f = fields[i];
				f.setAccessible(true); 
				System.out.println("属性名:" + f.getName() + " 属性值:" + f.getType()+"---"+f.get(object));  
				
				boolean is_continue=false;
				//判断是不是不需要生成的属性
				if(list_attr!=null && list_attr.size()>0){
					for(String attr:list_attr){
						if(f.getName().equals(attr)){
							is_continue=true;
							break;
						}
					}
				}
				if(f.get(object)==null || is_continue){
					continue;
				}
				
				//运算出语句
				if(!f.getName().equals(key)){
					attrSql+=f.getName()+",";
					
					if((f.getType().toString().equals("class java.lang.String") || f.getType().toString().equals("class java.sql.Timestamp")
							|| f.getType().toString().equals("class java.sql.Time")|| f.getType().toString().equals("class java.util.Date"))
							&& f.get(object)!=null){
						valueSql+="'"+TurnCharacter(f.get(object).toString())+"',";
					}else{
						valueSql+=f.get(object)+",";
						
					}
				}
			}
			attrSql=attrSql.substring(0, attrSql.length()-1);
			valueSql=valueSql.substring(0, valueSql.length()-1);
			
			//拼凑mysql语句
			mysql+=attrSql+") values ("+valueSql+")";
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(mysql);
		return mysql;
	}
    

	/**
	 * 生成批量添加的mysql语句
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * 第四个参数是，不需要生成sql的属性集合名称，可以是null
	 */
	public static String CreatAddListMysql(List list,String tableName,String key,List<String> list_attr){
		
//		insert into user (phone_num,password,username,nickname,address,head_img,points,invitee_id,time,openid)
//		values ( #{phone_num},#{password},#{username} ,#{nickname} ,#{address} ,#{head_img} ,#{points} ,#{invitee_id}  ,#{time},#{openid}  )
		if(list==null || list.size()==0){
			return "";
		}
		
		String mysql="insert into "+tableName+" (";
		try {
			String attrSql="";//属性语句
			String valueSql="";//值语句
			
			for(int j=0;j<list.size();j++){//循环对象
				Object object=list.get(j);
				
				Field[] fields = object.getClass() .getDeclaredFields();//获得所有属性集合
				
				valueSql+="(";
				for(int i=0; i<fields.length; i++){  
					Field f = fields[i];
					f.setAccessible(true); 
					System.out.println("属性名:" + f.getName() + " 属性值:" + f.getType()+"---"+f.get(object));  
					
					boolean is_continue=false;
					//判断是不是不需要生成的属性
					if(list_attr!=null && list_attr.size()>0){
						for(String attr:list_attr){
							if(f.getName().equals(attr)){
								is_continue=true;
								break;
							}
						}
					}
					if(f.get(object)==null || is_continue){
						continue;
					}
					
					//运算出语句
					if(!f.getName().equals(key)){
						if(j==0){// 只需要拼接一次
							attrSql+=f.getName()+",";							
						}
						
						if((f.getType().toString().equals("class java.lang.String") || f.getType().toString().equals("class java.sql.Timestamp")
								|| f.getType().toString().equals("class java.sql.Time"))
								&& f.get(object)!=null){
							valueSql+="'"+TurnCharacter(f.get(object).toString())+"',";
						}else{
							valueSql+=f.get(object)+",";
							
						}
					}
				}
				//一个对象循环结束了
				valueSql=valueSql.substring(0, valueSql.length()-1)+"),";
				
			}
			
			
			attrSql=attrSql.substring(0, attrSql.length()-1);
			valueSql=valueSql.substring(0, valueSql.length()-1);
			
			//拼凑mysql语句
			mysql+=attrSql+") values "+valueSql;
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(mysql);
		return mysql;
	}
	
	
	
	
	
	/**
	 * 给字符串加上\'转字符
	 * @param content
	 * @return
	 */
	private static String TurnCharacter(String str){
		return str.replaceAll("\'", "\\\\'");
	}
	
    
}
