Compare commits
2 Commits
f89ae5e425
...
659218682e
Author | SHA1 | Date | |
---|---|---|---|
659218682e | |||
019ba8f552 |
@ -2,22 +2,36 @@ package net.tomatentum.marinara.checks;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.tomatentum.marinara.util.ReflectionUtil;
|
||||
|
||||
public record AppliedCheck(InteractionCheck<?> check, Annotation annotation) {
|
||||
|
||||
public boolean pre() {
|
||||
public boolean pre(Object context) {
|
||||
Method[] methods = Arrays.stream(check.getClass().getMethods())
|
||||
.filter(x -> x.getName().equals("preExec"))
|
||||
.toArray(s -> new Method[s]);
|
||||
Method method = ReflectionUtil.getMostSpecificMethod(methods, context.getClass());
|
||||
method.setAccessible(true);
|
||||
try {
|
||||
return (boolean) check.getClass().getMethod("preExec", annotation.getClass()).invoke(check, annotation);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
return (boolean) method.invoke(check, annotation);
|
||||
} catch (IllegalAccessException | InvocationTargetException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean post() {
|
||||
public boolean post(Object context) {
|
||||
Method[] methods = Arrays.stream(check.getClass().getMethods())
|
||||
.filter(x -> x.getName().equals("postExec"))
|
||||
.toArray(s -> new Method[s]);
|
||||
Method method = ReflectionUtil.getMostSpecificMethod(methods, context.getClass());
|
||||
method.setAccessible(true);
|
||||
try {
|
||||
return (boolean) check.getClass().getMethod("postExec", annotation.getClass()).invoke(check, annotation);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
return (boolean) method.invoke(check, annotation);
|
||||
} catch (IllegalAccessException | InvocationTargetException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import java.lang.annotation.Annotation;
|
||||
|
||||
public interface InteractionCheck<A extends Annotation> {
|
||||
|
||||
public boolean preExec(A annotation);
|
||||
public boolean postExec(A annotation);
|
||||
public boolean preExec(Object context, A annotation);
|
||||
public boolean postExec(Object context, A annotation);
|
||||
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public abstract class InteractionMethod {
|
||||
public abstract InteractionType getType();
|
||||
|
||||
public void run(Object context) {
|
||||
this.appliedChecks.forEach(AppliedCheck::pre);
|
||||
this.appliedChecks.forEach(x -> x.pre(context));
|
||||
|
||||
method.setAccessible(true);
|
||||
try {
|
||||
@ -69,7 +69,7 @@ public abstract class InteractionMethod {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
this.appliedChecks.forEach(AppliedCheck::post);
|
||||
this.appliedChecks.forEach(x -> x.post(context));
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
|
@ -2,6 +2,10 @@ package net.tomatentum.marinara.util;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class ReflectionUtil {
|
||||
|
||||
@ -17,5 +21,79 @@ public final class ReflectionUtil {
|
||||
method.getAnnotation(annotationClass) :
|
||||
method.getDeclaringClass().getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
public static int getCastDepth(Class<?> child, Class<?> parent) {
|
||||
if (!parent.isAssignableFrom(child)) {
|
||||
throw new IllegalArgumentException("The specified class is not a child class of the specified parent.");
|
||||
}
|
||||
|
||||
int depth = 0;
|
||||
Class<?> curr = child;
|
||||
List<Class<?>> parents = new ArrayList<>();
|
||||
|
||||
while (!curr.equals(parent)) {
|
||||
depth++;
|
||||
parents.add(curr.getSuperclass());
|
||||
parents.addAll(Arrays.asList(curr.getInterfaces()));
|
||||
|
||||
for (Class<?> currParent : parents) {
|
||||
if (currParent != null && parent.isAssignableFrom(currParent)) {
|
||||
curr = currParent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
parents.clear();
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
public static Method getMostSpecificMethod(Method[] methods, Class<?>... parameters) {
|
||||
List<Method> compatibleMethods = Arrays.stream(methods)
|
||||
.filter(x -> isMethodCallable(x, parameters))
|
||||
.toList();
|
||||
|
||||
if (compatibleMethods.size() == 0)
|
||||
throw new IllegalArgumentException("There are no compatible Methods provided");
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
final int currI = i;
|
||||
Class<?>[] parameterTypes = compatibleMethods.stream()
|
||||
.map(x -> x.getParameterTypes()[currI])
|
||||
.toArray(x -> new Class[x]);
|
||||
|
||||
Class<?> mostSpecific = getMostSpecificClass(parameterTypes, parameters[i]);
|
||||
|
||||
compatibleMethods = compatibleMethods.stream()
|
||||
.filter(x -> Objects.equals(x.getParameterTypes()[currI], mostSpecific))
|
||||
.toList();
|
||||
}
|
||||
|
||||
return compatibleMethods.getFirst();
|
||||
}
|
||||
|
||||
public static Class<?> getMostSpecificClass(Class<?>[] classes, Class<?> base) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
Class<?> currMostSpecific = null;
|
||||
for (Class<?> currClass : classes) {
|
||||
int currCastDepth = getCastDepth(base, currClass);
|
||||
if (currCastDepth < min) {
|
||||
min = currCastDepth;
|
||||
currMostSpecific = currClass;
|
||||
}
|
||||
}
|
||||
return currMostSpecific;
|
||||
}
|
||||
|
||||
public static boolean isMethodCallable(Method method, Class<?>... parameters) {
|
||||
if (!Objects.equals(method.getParameterCount(), parameters.length))
|
||||
return false;
|
||||
|
||||
Class<?>[] methodParams = method.getParameterTypes();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
if (!methodParams[i].isAssignableFrom(parameters[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user