package com.api.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

public class EntityUtil {
@SuppressWarnings("deprecation")
public static <T> void setFieldValue(T model,String fieldName,String value) {
try {
//Field f = model.getClass().getDeclaredField(fieldName);
Field f = getDeclaredField(model,fieldName);
f.setAccessible(true); //设置些属性是可以访问的
String type = f.getType().toString();//得到此属性的类型

if(type.endsWith("Integer") || type.endsWith("int")){
f.set(model,Integer.parseInt(value));
}
else if(type.endsWith("Long") || type.endsWith("long")){
f.set(model,Long.parseLong(value));
}
else if(type.endsWith("Date")){
f.set(model,Date.parse(value));
}
else if(type.endsWith("Boolean")){
f.set(model,Boolean.parseBoolean(value));
}
else {
f.set(model,value);
}

} catch (SecurityException e) {
LogUtil.error("",e);
} catch (IllegalAccessException e) {
LogUtil.error("",e);
} catch (IllegalArgumentException e) {
LogUtil.error("",e);
}
}

/**
* 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
* @param object : 子类对象
* @param fieldName : 父类中的属性名
* @return : 父类中的属性值
*/

@SuppressWarnings("unchecked")
public static <T> Object getFieldValue(T object, String fieldName){

//根据 对象和属性名通过反射 调用上面的方法获取 Field对象
Field field = getDeclaredField(object, fieldName) ;

//抑制Java对其的检查
field.setAccessible(true) ;

try {
//获取 object 中 field 所代表的属性值
return field.get(object) ;

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

return null;
}


/**
* 循环向上转型, 获取对象的 DeclaredMethod
* @param object : 子类对象
* @param methodName : 父类中的方法名
* @param parameterTypes : 父类中的方法参数类型
* @return 父类中的方法对象
*/

public static Method getDeclaredMethod(Object object, String methodName, Class<?> ... parameterTypes){
Method method = null ;

for(Class<?> clazz = object.getClass() ; clazz != Object.class ; clazz = clazz.getSuperclass()) {
try {
method = clazz.getDeclaredMethod(methodName, parameterTypes) ;
return method ;
} catch (Exception e) {
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了

}
}

return null;
}

/**
* 直接调用对象方法, 而忽略修饰符(private, protected, default)
* @param object : 子类对象
* @param methodName : 父类中的方法名
* @param parameterTypes : 父类中的方法参数类型
* @param parameters : 父类中的方法参数
* @return 父类中方法的执行结果
*/

@SuppressWarnings("unchecked")
public static <T> T invokeMethod(T object, String methodName, Class<?> [] parameterTypes,
Object [] parameters) {
//根据 对象、方法名和对应的方法参数 通过反射 调用上面的方法获取 Method 对象
Method method = getDeclaredMethod(object, methodName, parameterTypes) ;

//抑制Java对方法进行检查,主要是针对私有方法而言
method.setAccessible(true) ;

try {
if(null != method) {

//调用object 的 method 所代表的方法,其方法的参数是 parameters
return (T) method.invoke(object, parameters) ;
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

return null;
}

/**
* 循环向上转型, 获取对象的 DeclaredField
* @param object : 子类对象
* @param fieldName : 父类中的属性名
* @return 父类中的属性对象
*/

public static <T> Field getDeclaredField(T model, String fieldName){
Field field = null ;

Class<?> clazz = model.getClass() ;

for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
try {
field = clazz.getDeclaredField(fieldName) ;
return field ;
} catch (Exception e) {
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了

}
}

return null;
}

}