package io.micronaut.context;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.annotation.UsedByGeneratedCode;
import io.micronaut.core.reflect.ReflectionUtils;
import io.micronaut.core.type.Argument;
import io.micronaut.core.type.Executable;
import io.micronaut.core.util.ArrayUtils;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
@Internal
abstract class AbstractExecutable implements Executable {
protected final Class declaringType;
protected final String methodName;
protected final Class[] argTypes;
private Argument[] arguments;
private Method method;
AbstractExecutable(Class declaringType, String methodName, Argument[] arguments) {
Objects.requireNonNull(declaringType, "Declaring type cannot be null");
Objects.requireNonNull(methodName, "Method name cannot be null");
this.argTypes = Argument.toClassArray(arguments);
this.declaringType = declaringType;
this.methodName = methodName;
if (ArrayUtils.isNotEmpty(arguments)) {
this.arguments = arguments;
} else {
this.arguments = Argument.ZERO_ARGUMENTS;
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof AbstractExecutable)) {
return false;
}
AbstractExecutable that = (AbstractExecutable) o;
return Objects.equals(declaringType, that.declaringType) &&
Objects.equals(methodName, that.methodName) &&
Arrays.equals(argTypes, that.argTypes);
}
@Override
public int hashCode() {
int result = Objects.hash(declaringType, methodName);
result = 31 * result + Arrays.hashCode(argTypes);
return result;
}
@Override
public Argument[] getArguments() {
return arguments;
}
public final Method getTargetMethod() {
if (method == null) {
Method resolvedMethod = resolveTargetMethod();
resolvedMethod.setAccessible(true);
this.method = resolvedMethod;
}
return this.method;
}
@NonNull
@UsedByGeneratedCode
protected Method resolveTargetMethod() {
return ReflectionUtils.getRequiredMethod(declaringType, methodName, argTypes);
}
}