All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.github.kiryu1223.expressionTree.util.ReflectUtil Maven / Gradle / Ivy
package io.github.kiryu1223.expressionTree.util;
import io.github.kiryu1223.expressionTree.expressions.annos.Recode;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ReflectUtil
{
private final static Map, Map> fieldCache = new ConcurrentHashMap<>();
private final static Map, Map[], Method>>> methodCache = new ConcurrentHashMap<>();
public static Field getField(@Recode Class> clazz, String name)
{
try
{
if (!fieldCache.containsKey(clazz))
{
fieldCache.put(clazz, new ConcurrentHashMap<>());
}
Map fieldMap = fieldCache.get(clazz);
if (!fieldMap.containsKey(name))
{
Field declaredField = clazz.getDeclaredField(name);
declaredField.setAccessible(true);
fieldMap.put(name, declaredField);
}
return fieldMap.get(name);
}
catch (NoSuchFieldException e)
{
throw new RuntimeException(e);
}
}
public static Method getMethod(@Recode Class> clazz, String name, Class>[] classes)
{
try
{
Map[], Method> methodMap = getMethodMap(clazz, name);
if (!methodMap.containsKey(classes))
{
Method declaredMethod = clazz.getDeclaredMethod(name, classes);
declaredMethod.setAccessible(true);
methodMap.put(classes, declaredMethod);
}
return methodMap.get(classes);
}
catch (NoSuchMethodException e)
{
for (Method declaredMethod : clazz.getDeclaredMethods())
{
if (!declaredMethod.getName().equals(name)) continue;
if (declaredMethod.getParameterCount() != classes.length) continue;
Class>[] parameterTypes = declaredMethod.getParameterTypes();
if (AllAssignableFrom(parameterTypes, classes))
{
Map[], Method> methodMap = getMethodMap(clazz, name);
declaredMethod.setAccessible(true);
methodMap.put(classes, declaredMethod);
return declaredMethod;
}
}
throw new RuntimeException(e);
}
}
public static Constructor> getConstructor(@Recode Class> clazz, Class>[] parameterTypes)
{
try
{
Constructor> declaredConstructor = clazz.getDeclaredConstructor(parameterTypes);
declaredConstructor.setAccessible(true);
return declaredConstructor;
}
catch (NoSuchMethodException e)
{
if (clazz.isAnonymousClass()) return null;
else throw new RuntimeException(e);
}
}
private static Map[], Method> getMethodMap(Class> clazz, String name)
{
if (!methodCache.containsKey(clazz))
{
methodCache.put(clazz, new ConcurrentHashMap<>());
}
Map[], Method>> nameMethodMap = methodCache.get(clazz);
if (!nameMethodMap.containsKey(name))
{
nameMethodMap.put(name, new ConcurrentHashMap<>());
}
return nameMethodMap.get(name);
}
private static boolean AllAssignableFrom(Class>[] parameterTypes, Class>[] classes)
{
for (int i = 0; i < parameterTypes.length; i++)
{
if (parameterTypes[i].isPrimitive() || classes[i].isPrimitive())
{
if (!specialJudgments(parameterTypes[i], classes[i]))
{
return false;
}
}
else if (!parameterTypes[i].isAssignableFrom(classes[i]))
{
return false;
}
}
return true;
}
private static boolean specialJudgments(Class> classA, Class> classB)
{
if (classA == classB) return true;
else if (classA == Long.TYPE || classA == Long.class)
{
if (classB != Long.TYPE && classB != Long.class
&& classB != Integer.TYPE && classB != Integer.class
&& classB != Short.TYPE && classB != Short.class
&& classB != Byte.TYPE && classB != Byte.class)
{
return false;
}
}
else if (classA == Integer.TYPE || classA == Integer.class)
{
if (classB != Integer.TYPE && classB != Integer.class
&& classB != Short.TYPE && classB != Short.class
&& classB != Byte.TYPE && classB != Byte.class)
{
return false;
}
}
else if (classA == Short.TYPE || classA == Short.class)
{
if (classB != Short.TYPE && classB != Short.class
&& classB != Byte.TYPE && classB != Byte.class)
{
return false;
}
}
else if (classA == Byte.TYPE || classA == Byte.class)
{
if (classB != Byte.TYPE && classB != Byte.class)
{
return false;
}
}
else if (classA == Character.TYPE || classA == Character.class)
{
if (classB != Character.TYPE && classB != Character.class)
{
return false;
}
}
else if (classA == Boolean.TYPE || classA == Boolean.class)
{
if (classB != Boolean.TYPE && classB != Boolean.class)
{
return false;
}
}
else if (classA == Double.TYPE || classA == Double.class)
{
if (classB != Long.TYPE && classB != Long.class
&& classB != Integer.TYPE && classB != Integer.class
&& classB != Short.TYPE && classB != Short.class
&& classB != Byte.TYPE && classB != Byte.class
&& classB != Float.TYPE && classB != Float.class
&& classB != Double.TYPE && classB != Double.class)
{
return false;
}
}
else if (classA == Float.TYPE || classA == Float.class)
{
if (classB != Long.TYPE && classB != Long.class
&& classB != Integer.TYPE && classB != Integer.class
&& classB != Short.TYPE && classB != Short.class
&& classB != Byte.TYPE && classB != Byte.class
&& classB != Float.TYPE && classB != Float.class)
{
return false;
}
}
return true;
}
public static T getFieldValue(Object o, String name)
{
try
{
Field field = getField(o.getClass(), name);
field.setAccessible(true);
return (T) field.get(o);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
public static T invokeMethod(Object o, String name, List values)
{
try
{
Method method = getMethod(o.getClass(), name, values.stream().map(Object::getClass).toArray(Class[]::new));
method.setAccessible(true);
return (T) method.invoke(o, values.toArray());
}
catch (IllegalAccessException | InvocationTargetException e)
{
throw new RuntimeException(e);
}
}
}