package com.xplora.xpsettings;

import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 反射操作
 */
public class RefInvoke {

    /**
     * 获取对象的属性值
     * @param className 类名
     * @param fieldName 属性名
     * @param owner 所属对象
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchFieldException 属性不存在异常
     * @throws Exception 其它异常
     */
    public static Object getField(String className, String fieldName, Object owner) throws SecurityException, NoSuchFieldException, Exception{
    	Class<?> ownerClass = Class.forName(className);
    	Field field = ownerClass.getDeclaredField(fieldName);
		// 私有化属性也能使用
		field.setAccessible(true);
		return field.get(owner);
    }

    /**
     * 设置对象的属性值
     * @param className 类名
     * @param fieldName 属性名
     * @param owner 所属对象
     * @return value 属性值
     * @throws SecurityException 权限异常
     * @throws NoSuchFieldException 属性不存在异常
     * @throws Exception 其它异常
     */
    public static void setField(String className, String fieldName, Object owner, Object value) throws SecurityException, NoSuchFieldException, Exception{
    	Class<?> ownerClass = Class.forName(className);
    	Field field = ownerClass.getDeclaredField(fieldName);
		// 私有化属性也能使用
		field.setAccessible(true);
		field.set(owner, value);
    }

    /**
     * 获取对象的静态属性值
     * @param className 类名
     * @param fieldName 属性名
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchFieldException 属性不存在异常
     * @throws Exception 其它异常
     */
    public static Object getStaticField(String className, String fieldName) throws SecurityException, NoSuchFieldException, Exception{
		Class<?> ownerClass = Class.forName(className);
		Field field = ownerClass.getDeclaredField(fieldName);
		// 私有化属性也能使用
		field.setAccessible(true);
		return field.get(null);
    }

    /**
     * 设置对象的静态属性值
     * @param className 类名
     * @param fieldName 属性名
     * @return value 属性值
     * @throws SecurityException 权限异常
     * @throws NoSuchFieldException 属性不存在异常
     * @throws Exception 其它异常
     */
    public static void setStaticField(String className, String fieldName, Object value) throws SecurityException, NoSuchFieldException, Exception{
    	Class<?> ownerClass = Class.forName(className);
    	Field field = ownerClass.getDeclaredField(fieldName);
		// 私有化属性也能使用
		field.setAccessible(true);
		field.set(null, value);
    }


    /**
     * 调用对象中的方法
     * @param className 类名
     * @param methodName 方法名
     * @param owner 所属对象
     * @param argsClass 参数类型集
     * @param paras 参数集
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchMethodException 方法不存在异常
     * @throws Exception 其它异常
     */
    public static Object invokeMethod(String className, String methodName, Object owner, Class<?>[] argsClass, Object[] paras) throws SecurityException, NoSuchMethodException, Exception{
    	Class<?> ownerClass = Class.forName(className);
		Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
		// 私有化函数也能使用
		method.setAccessible(true);
		// 执行方法
		return method.invoke(owner, paras);
    }

    /**
     * 调用对象中的静态方法
     * @param className 类名
     * @param methodName 方法名
     * @param argsClass 参数类型集
     * @param paras 参数集
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchMethodException 方法不存在异常
     * @throws Exception 其它异常
     */
	public static Object invokeStaticMethod(String className, String methodName, Class<?>[] argsClass, Object[] paras) throws SecurityException, NoSuchMethodException, Exception{
		Class<?> ownerClass = Class.forName(className);
		Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
		// 私有化函数也能使用
		method.setAccessible(true);
		// 执行方法
		return method.invoke(null, paras);
	}


    /**
     * 调用对象中的方法
     * @param className 类名
     * @param methodName 方法名
     * @param owner 所属对象
     * @param paras 参数集
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchMethodException 方法不存在异常
     * @throws Exception 其它异常
     */
    public static Object invokeMethod(String className, String methodName, Object owner, Object... paras) throws SecurityException, NoSuchMethodException, Exception{
    	Class<?> ownerClass = Class.forName(className);
    	Class<?>[] argsClass = new Class[paras.length];
		for (int i = 0, j = paras.length; i < j; i++) {
			argsClass[i] = paras[i].getClass();
		}
		Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
		// 私有化函数也能使用
		method.setAccessible(true);
		// 执行方法
		return method.invoke(owner, paras);
    }

    /**
     * 调用对象中的静态方法
     * @param className 类名
     * @param methodName 方法名
     * @param paras 参数集
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchMethodException 方法不存在异常
     * @throws Exception 其它异常
     */
	public static Object invokeStaticMethod(String className, String methodName, Object... paras) throws SecurityException, NoSuchMethodException, Exception{
		Class<?> ownerClass = Class.forName(className);
		Class<?>[] argsClass = new Class[paras.length];
		for (int i = 0, j = paras.length; i < j; i++) {
			argsClass[i] = paras[i].getClass();
		}
		Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
		Log.d("losion", "invokeStaticMethod: " + method.toString());
		// 私有化函数也能使用
		method.setAccessible(true);
		// 执行方法
		return method.invoke(null, paras);
	}

	public static Object invokeStaticMethod2(String className, String methodName, Object... paras) throws SecurityException, NoSuchMethodException, Exception{
		Class<?> ownerClass = Class.forName(className);
		Class<?>[] argsClass = new Class[paras.length];
		for (int i = 0, j = paras.length; i < j; i++) {
			argsClass[i] = paras[i].getClass();
		}
		Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
		// 私有化函数也能使用
		method.setAccessible(true);
		// 执行方法
		return method.invoke(null, paras);
	}

	public static Object invokeStaticMethod3(String className, String method_name, Class<?> pareTyples, Object pareVaules) throws SecurityException, NoSuchMethodException, Exception {
		try {
			Class obj_class = Class.forName(className);
			Method method = obj_class.getDeclaredMethod(method_name, pareTyples);
			Log.d("losion", "invokeStaticMethod3: " + method.toString());
			method.setAccessible(true);
			return method.invoke(null, pareVaules);
		} catch (Exception e) {
			Log.d("losion", "invokeStaticMethod3: Exception ");
			e.printStackTrace();
		}
		Log.d("losion", "invokeStaticMethod3: null ");
		return null;
	}


    /**
     * 获取对象的属性值
     * @param fieldName 属性名
     * @param owner 所属对象
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchFieldException 属性不存在异常
     * @throws Exception 其它异常
     */
    public static Object getFieldByOwner(String fieldName, Object owner) throws SecurityException, NoSuchFieldException, Exception{
    	Class<?> ownerClass = owner.getClass();
    	Field field = ownerClass.getDeclaredField(fieldName);
		// 私有化属性也能使用
		field.setAccessible(true);
		return field.get(owner);
    }

    /**
     * 设置对象的属性值
     * @param fieldName 属性名
     * @param owner 所属对象
     * @return value 属性值
     * @throws SecurityException 权限异常
     * @throws NoSuchFieldException 属性不存在异常
     * @throws Exception 其它异常
     */
    public static void setFieldByOwner(String fieldName, Object owner, Object value) throws SecurityException, NoSuchFieldException, Exception{
    	Class<?> ownerClass = owner.getClass();
    	Field field = ownerClass.getDeclaredField(fieldName);
		// 私有化属性也能使用
		field.setAccessible(true);
		field.set(owner, value);
    }

    /**
     * 调用对象中的方法
     * @param methodName 方法名
     * @param owner 所属对象
     * @param paras 参数集
     * @return 返回值
     * @throws SecurityException 权限异常
     * @throws NoSuchMethodException 方法不存在异常
     * @throws Exception 其它异常
     */
    public static Object invokeMethodByOwner(String methodName, Object owner, Object... paras) throws SecurityException, NoSuchMethodException, Exception{
    	Class<?> ownerClass = owner.getClass();
    	Class<?>[] argsClass = new Class[paras.length];
		for (int i = 0, j = paras.length; i < j; i++) {
			argsClass[i] = paras[i].getClass();
		}
		Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
		// 私有化函数也能使用
		method.setAccessible(true);
		// 执行方法
		return method.invoke(owner, paras);
    }
    
}
