Files
CodeChickenCore/src/codechicken/core/ReflectionManager.java
T
2014-04-29 00:35:55 +10:00

317 lines
10 KiB
Java

package codechicken.core;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import codechicken.lib.asm.ObfMapping;
public class ReflectionManager
{
public static HashMap<Class<?>, Class<?>> primitiveWrappers = new HashMap<Class<?>, Class<?>>();
static
{
primitiveWrappers.put(Integer.TYPE, Integer.class);
primitiveWrappers.put(Short.TYPE, Short.class);
primitiveWrappers.put(Byte.TYPE, Byte.class);
primitiveWrappers.put(Long.TYPE, Long.class);
primitiveWrappers.put(Double.TYPE, Double.class);
primitiveWrappers.put(Float.TYPE, Float.class);
primitiveWrappers.put(Boolean.TYPE, Boolean.class);
primitiveWrappers.put(Character.TYPE, Character.class);
}
public static boolean isInstance(Class<?> class1, Object obj)
{
Class<?> primitive = primitiveWrappers.get(class1);
if(primitive != null)
{
if(primitive == Long.class && Long.class.isInstance(obj))
return true;
if((primitive == Long.class || primitive == Integer.class) && Integer.class.isInstance(obj))
return true;
if((primitive == Long.class || primitive == Integer.class || primitive == Short.class) && Short.class.isInstance(obj))
return true;
if((primitive == Long.class || primitive == Integer.class || primitive == Short.class || primitive == Byte.class) && Integer.class.isInstance(obj))
return true;
if(primitive == Double.class && Double.class.isInstance(obj))
return true;
if((primitive == Double.class || primitive == Float.class) && Float.class.isInstance(obj))
return true;
return primitive.isInstance(obj);
}
return class1.isInstance(obj);
}
public static Class<?> findClass(String name)
{
return findClass(name, true);
}
public static boolean classExists(String name)
{
return findClass(name, false) != null;
}
public static Class<?> findClass(String name, boolean init)
{
try
{
return Class.forName(name, init, ReflectionManager.class.getClassLoader());
}
catch (ClassNotFoundException cnfe)
{
try
{
return Class.forName("net.minecraft.src."+name, init, ReflectionManager.class.getClassLoader());
}
catch (ClassNotFoundException cnfe2)
{
return null;
}
}
}
public static void setField(Class<?> class1, Object instance, String name, Object value) throws IllegalArgumentException, IllegalAccessException
{
setField(class1, instance, new String[]{name}, value);
}
public static void setField(Class<?> class1, Object instance, String[] names, Object value) throws IllegalArgumentException, IllegalAccessException
{
for(Field field : class1.getDeclaredFields())
{
boolean match = false;
for(String name : names)
{
if(field.getName().equals(name))
{
match = true;
break;
}
}
if(!match)
{
continue;
}
field.setAccessible(true);
field.set(instance, value);
return;
}
}
public static void setField(Class<?> class1, Object instance, int fieldindex, Object value) throws IllegalArgumentException, IllegalAccessException
{
Field field = class1.getDeclaredFields()[fieldindex];
field.setAccessible(true);
field.set(instance, value);
}
/**
* Static function
* void return type
* single name
*/
public static void callMethod(Class<?> class1, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
callMethod(class1, null, new String[]{name}, params);
}
/**
* Static function
* void return type
* single name
*/
public static void callMethod(Class<?> class1, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
callMethod(class1, null, names, params);
}
/**
* void return type
* single name
*/
public static void callMethod(Class<?> class1, Object instance, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
callMethod(class1, null, instance, new String[]{name}, params);
}
/**
* void return type
*/
public static void callMethod(Class<?> class1, Object instance, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
callMethod(class1, null, instance, names, params);
}
/**
* Static method
* single name
*/
public static <R> R callMethod(Class<?> class1, Class<R> returntype, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
return callMethod(class1, returntype, null, new String[]{name}, params);
}
/**
* Static method
*/
public static <R> R callMethod(Class<?> class1, Class<R> returntype, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
return callMethod(class1, returntype, null, names, params);
}
/**
* sinlge name
*/
public static <R> R callMethod(Class<?> class1, Class<R> returntype, Object instance, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
return callMethod(class1, returntype, instance, new String[]{name}, params);
}
public static <R> R callMethod(Class<?> class1, Class<R> returntype, Object instance, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
nextMethod: for(Method method : class1.getDeclaredMethods())
{
boolean match = false;
for(String name : names)
{
if(method.getName().equals(name))
{
match = true;
break;
}
}
if(!match)
{
continue;
}
Class<?>[] paramtypes = method.getParameterTypes();
if(paramtypes.length != params.length)
continue;
for(int i = 0; i < params.length; i++)
{
if(!isInstance(paramtypes[i], params[i]))
continue nextMethod;
}
method.setAccessible(true);
return (R)method.invoke(instance, params);
}
return null;
}
public static <T> T getField(Class<?> class1, Class<T> fieldType, Object instance, int fieldIndex) throws IllegalArgumentException, IllegalAccessException
{
Field field = class1.getDeclaredFields()[fieldIndex];
field.setAccessible(true);
return (T) field.get(instance);
}
public static <T> T getField(Class<?> class1, Class<T> fieldType, Object instance, String fieldName)
{
try
{
Field field = class1.getDeclaredField(fieldName);
field.setAccessible(true);
return (T) field.get(instance);
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
public static <T> T newInstance(Class<T> class1, Object... params) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
{
nextMethod: for(Constructor<?> constructor : class1.getDeclaredConstructors())
{
Class<?>[] paramtypes = constructor.getParameterTypes();
if(paramtypes.length != params.length)
continue;
for(int i = 0; i < params.length; i++)
{
if(!isInstance(paramtypes[i], params[i]))
continue nextMethod;
}
constructor.setAccessible(true);
return (T)constructor.newInstance(params);
}
return null;
}
public static boolean hasField(Class<?> class1, String fieldName)
{
try
{
class1.getDeclaredField(fieldName);
return true;
}
catch(NoSuchFieldException nfe)
{
return false;
}
}
public static <T> T get(Field field, Class<T> class1)
{
return get(field, class1, null);
}
public static <T> T get(Field field, Class<T> class1, Object instance)
{
try
{
return (T)field.get(instance);
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
public static void set(Field field, Object value)
{
set(field, null, value);
}
public static void set(Field field, Object instance, Object value)
{
try
{
field.set(instance, value);
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
public static Field getField(ObfMapping mapping)
{
mapping.toRuntime();
try
{
Class<?> clazz = ReflectionManager.class.getClassLoader().loadClass(mapping.javaClass());
Field field = clazz.getDeclaredField(mapping.s_name);
field.setAccessible(true);
return field;
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
}