diff --git a/lib/src/main/java/net/tomatentum/cutin/BestCandidateMethod.java b/lib/src/main/java/net/tomatentum/cutin/BestCandidateMethod.java new file mode 100644 index 0000000..2f468d8 --- /dev/null +++ b/lib/src/main/java/net/tomatentum/cutin/BestCandidateMethod.java @@ -0,0 +1,53 @@ +package net.tomatentum.cutin; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import net.tomatentum.cutin.util.ReflectionUtil; + +public class BestCandidateMethod extends ReflectedMethod { + + private String methodName; + private I identifier; + private List additionalParameters; + + protected BestCandidateMethod(String methodName, Object containingObject, I identifer, Object... additionalParameters) { + super(getMethod(containingObject, methodName), containingObject); + this.methodName = methodName; + this.identifier = identifer; + this.additionalParameters = Arrays.asList(additionalParameters); + } + + @Override + public Object getParameter(Object context, int index) { + return additionalParameters.get(index); + } + + @Override + public I identifier() { + return this.identifier; + } + + @Override + public Object run(Object context) { + Method[] methods = Arrays.stream(containingObject.getClass().getDeclaredMethods()) + .filter(x -> x.getName().equals(methodName)) + .filter(x -> !x.isBridge()) + .toArray(Method[]::new); + Class[] parameters = Stream.concat( + Stream.of(context.getClass()), + additionalParameters.stream().map(Object::getClass) + ).toArray(Class[]::new); + super.method = ReflectionUtil.getMostSpecificMethod(methods, parameters); + return super.run(context); + } + + private static Method getMethod(Object containingMethod, String methodName) { + return Arrays.stream(containingMethod.getClass().getDeclaredMethods()) + .filter(m -> m.getName().equals(methodName)) + .findFirst().orElse(null); + } + +}