forked from SteamWar/SteamWar
Add Annotation Processor for compile time checks
This commit is contained in:
@@ -132,14 +132,14 @@ public class CommandUtils {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
public static ToIntFunction<Number> createComparator(String type, Class<?> clazz, int iValue, long lValue, float fValue, double dValue) {
|
||||
if (clazz == int.class || clazz == Integer.class) {
|
||||
public static ToIntFunction<Number> createComparator(String type, Handler.TypeWrapper clazz, int iValue, long lValue, float fValue, double dValue) {
|
||||
if (clazz.is(int.class) || clazz.is(Integer.class)) {
|
||||
return number -> Integer.compare(number.intValue(), iValue);
|
||||
} else if (clazz == long.class || clazz == Long.class) {
|
||||
} else if (clazz.is(long.class) || clazz.is(Long.class)) {
|
||||
return number -> Long.compare(number.longValue(), lValue);
|
||||
} else if (clazz == float.class || clazz == Float.class) {
|
||||
} else if (clazz.is(float.class) || clazz.is(Float.class)) {
|
||||
return number -> Float.compare(number.floatValue(), fValue);
|
||||
} else if (clazz == double.class || clazz == Double.class) {
|
||||
} else if (clazz.is(double.class) || clazz.is(Double.class)) {
|
||||
return number -> Double.compare(number.doubleValue(), dValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException(type + " annotation is not supported for " + clazz);
|
||||
|
||||
@@ -19,11 +19,15 @@
|
||||
|
||||
package de.steamwar.command;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -58,17 +62,29 @@ public interface Handler {
|
||||
Class<? extends Handler> value();
|
||||
}
|
||||
|
||||
class HandlerException extends Exception {
|
||||
public HandlerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
interface DataCheckable {
|
||||
boolean hasExecutorMapper(Class<?> clazz);
|
||||
|
||||
boolean hasMapper(String key);
|
||||
|
||||
boolean hasValidator(String key);
|
||||
|
||||
boolean hasSupplier(String key);
|
||||
}
|
||||
|
||||
interface DataReadable {
|
||||
Function<?, ?> getExecutorMapper(Class<?> clazz);
|
||||
|
||||
<A, B> AbstractTypeMapper<A, B> getMapper(String key);
|
||||
|
||||
<A, B> AbstractTypeValidator<A, B> getValidator(String key);
|
||||
|
||||
<A, B> AbstractTypeSupplier<A, B> getSupplier(String key);
|
||||
}
|
||||
|
||||
@@ -76,17 +92,26 @@ public interface Handler {
|
||||
Function<?, ?> getExecutorMapper(Class<?> clazz);
|
||||
|
||||
<A, B> void addMapper(String key, boolean local, AbstractTypeMapper<A, B> mapper);
|
||||
|
||||
<A, B> void addValidator(String key, boolean local, AbstractTypeValidator<A, B> validator);
|
||||
|
||||
<A, B> void addSupplier(String key, boolean local, AbstractTypeSupplier<A, B> supplier);
|
||||
|
||||
/**
|
||||
* Invoking the same method twice will result in the exact same result.
|
||||
*/
|
||||
<T> T invoke(Method method);
|
||||
|
||||
void addCommand(Method method, String[] subCommand, String[] description, boolean noTabComplete);
|
||||
}
|
||||
|
||||
interface HandlerMethod<T extends Annotation> extends Handler {
|
||||
void check(T annotation, Method method, DataCheckable dataCheckable) throws Exception;
|
||||
default void check(T annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
check(annotation, new MethodWrapper.ForMethod(method), dataCheckable);
|
||||
}
|
||||
|
||||
default void check(T annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
}
|
||||
|
||||
int getRunPriority();
|
||||
|
||||
@@ -94,7 +119,12 @@ public interface Handler {
|
||||
}
|
||||
|
||||
interface HandlerParameter<T extends Annotation, A, B> extends Handler {
|
||||
void check(T annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception;
|
||||
default void check(T annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
check(annotation, new MethodWrapper.ForMethod((Method) parameter.getDeclaringExecutable()), new ParameterWrapper.ForParameter(parameter), index, dataCheckable);
|
||||
}
|
||||
|
||||
default void check(T annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
}
|
||||
|
||||
default boolean needsParentTypeMapper() {
|
||||
return false;
|
||||
@@ -118,4 +148,179 @@ public interface Handler {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface MethodWrapper {
|
||||
String getName();
|
||||
|
||||
int getParameterCount();
|
||||
|
||||
TypeWrapper getReturnType();
|
||||
|
||||
ParameterWrapper[] getParameters();
|
||||
|
||||
class ForMethod implements MethodWrapper {
|
||||
|
||||
@Getter
|
||||
private final Method method;
|
||||
|
||||
public ForMethod(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return method.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParameterCount() {
|
||||
return method.getParameterCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeWrapper getReturnType() {
|
||||
return new TypeWrapper.ForClass(method.getReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParameterWrapper[] getParameters() {
|
||||
return Arrays.stream(method.getParameters()).map(ParameterWrapper.ForParameter::new).toArray(ParameterWrapper[]::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface ParameterWrapper {
|
||||
TypeWrapper getType();
|
||||
|
||||
boolean isVarArgs();
|
||||
|
||||
boolean isAnnotationPresent(Class<? extends Annotation> annotation);
|
||||
|
||||
<A extends Annotation> A getAnnotation(Class<A> annotation);
|
||||
|
||||
String getName();
|
||||
|
||||
List<Annotation> getAnnotations();
|
||||
|
||||
class ForParameter implements ParameterWrapper {
|
||||
|
||||
@Getter
|
||||
private final Parameter parameter;
|
||||
|
||||
public ForParameter(Parameter parameter) {
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeWrapper getType() {
|
||||
return new TypeWrapper.ForClass(this.parameter.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVarArgs() {
|
||||
return parameter.isVarArgs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotationPresent(Class<? extends Annotation> annotation) {
|
||||
return parameter.isAnnotationPresent(annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotation) {
|
||||
return parameter.getAnnotation(annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return parameter.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Annotation> getAnnotations() {
|
||||
return CommandUtils.getAnnotations(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface TypeWrapper {
|
||||
|
||||
boolean isAssignableTo(Class<?> clazz);
|
||||
|
||||
boolean isAssignableTo(TypeWrapper type);
|
||||
|
||||
boolean isPrimitive();
|
||||
|
||||
boolean isArray();
|
||||
|
||||
boolean isEnum();
|
||||
|
||||
boolean is(Class<?> clazz);
|
||||
|
||||
boolean is(TypeWrapper type);
|
||||
|
||||
TypeWrapper getComponentType();
|
||||
|
||||
String getName();
|
||||
|
||||
class ForClass implements TypeWrapper {
|
||||
@Getter
|
||||
private final Class<?> clazz;
|
||||
|
||||
public ForClass(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignableTo(Class<?> clazz) {
|
||||
return clazz.isAssignableFrom(this.clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignableTo(TypeWrapper type) {
|
||||
if (type instanceof ForClass) {
|
||||
return ((ForClass) type).getClazz().isAssignableFrom(clazz);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrimitive() {
|
||||
return clazz.isPrimitive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArray() {
|
||||
return clazz.isArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnum() {
|
||||
return clazz.isEnum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(Class<?> clazz) {
|
||||
return this.clazz == clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(TypeWrapper type) {
|
||||
if (type instanceof ForClass) {
|
||||
return ((ForClass) type).getClazz() == this.clazz;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeWrapper getComponentType() {
|
||||
return new TypeWrapper.ForClass(this.clazz.getComponentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.clazz.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -36,12 +36,12 @@ public final class AllowNullHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<AllowNull, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(AllowNull annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(AllowNull annotation, MethodWrapper method, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("AllowNull annotation cannot be used on the first parameter");
|
||||
throw new HandlerException("AllowNull annotation cannot be used on the first parameter");
|
||||
}
|
||||
if (parameter.getType().isPrimitive()) {
|
||||
throw new UnsupportedOperationException("AllowNull annotation cannot be used on primitive types");
|
||||
throw new HandlerException("AllowNull annotation cannot be used on primitive types");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -47,15 +47,15 @@ public final class ArrayLengthHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<ArrayLength, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(ArrayLength arrayLength, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(ArrayLength arrayLength, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("ArrayLength annotation cannot be used on first parameter");
|
||||
throw new HandlerException("ArrayLength annotation cannot be used on first parameter");
|
||||
}
|
||||
if (!parameter.getType().isArray()) {
|
||||
throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable().getName() + " is not an array");
|
||||
throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not an array");
|
||||
}
|
||||
if (arrayLength.min() > arrayLength.max()) {
|
||||
throw new UnsupportedOperationException("Min ArrayLength cannot be smaller than Max ArrayLength");
|
||||
throw new HandlerException("Min ArrayLength cannot be smaller than Max ArrayLength");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -31,12 +31,12 @@ public final class CachedHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<Cached> {
|
||||
|
||||
@Override
|
||||
public void check(Cached annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Cached annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() != 0) {
|
||||
throw new UnsupportedOperationException("Cached method must have no parameters");
|
||||
throw new HandlerException("Cached method must have no parameters");
|
||||
}
|
||||
if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) {
|
||||
throw new UnsupportedOperationException("Cached method must return AbstractTypeMapper");
|
||||
if (!method.getReturnType().isAssignableTo(AbstractTypeMapper.class)) {
|
||||
throw new HandlerException("Cached method must return AbstractTypeMapper");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -31,12 +31,12 @@ public final class ClassMapperHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<ClassMapper> {
|
||||
|
||||
@Override
|
||||
public void check(ClassMapper annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(ClassMapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() != 0) {
|
||||
throw new UnsupportedOperationException("ClassMapper method must have no parameters");
|
||||
throw new HandlerException("ClassMapper method must have no parameters");
|
||||
}
|
||||
if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) {
|
||||
throw new UnsupportedOperationException("ClassMapper method must return AbstractTypeMapper");
|
||||
if (!method.getReturnType().isAssignableTo(AbstractTypeMapper.class)) {
|
||||
throw new HandlerException("ClassMapper method must return AbstractTypeMapper");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -31,12 +31,12 @@ public final class ClassValidatorHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<ClassValidator> {
|
||||
|
||||
@Override
|
||||
public void check(ClassValidator annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(ClassValidator annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() != 0) {
|
||||
throw new UnsupportedOperationException("ClassValidator method must have no parameters");
|
||||
throw new HandlerException("ClassValidator method must have no parameters");
|
||||
}
|
||||
if (!AbstractTypeValidator.class.isAssignableFrom(method.getReturnType())) {
|
||||
throw new UnsupportedOperationException("ClassValidator method must return AbstractValidator");
|
||||
if (!method.getReturnType().isAssignableTo(AbstractTypeValidator.class)) {
|
||||
throw new HandlerException("ClassValidator method must return AbstractValidator");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -35,12 +35,12 @@ public final class EndsWithHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<EndsWith, Object, String> {
|
||||
|
||||
@Override
|
||||
public void check(EndsWith annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(EndsWith annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("EndsWith annotation cannot be used on first parameter");
|
||||
throw new HandlerException("EndsWith annotation cannot be used on first parameter");
|
||||
}
|
||||
if (parameter.getType() != String.class) {
|
||||
throw new UnsupportedOperationException("EndsWith annotation cannot be used on String parameter");
|
||||
if (!parameter.getType().is(String.class)) {
|
||||
throw new HandlerException("EndsWith annotation cannot be used on String parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -31,12 +31,12 @@ public final class ErrorMessageHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<ErrorMessage, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(ErrorMessage errorMessage, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(ErrorMessage errorMessage, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("ErrorMessage annotation cannot be used on first parameter");
|
||||
throw new HandlerException("ErrorMessage annotation cannot be used on first parameter");
|
||||
}
|
||||
if (!errorMessage.allowEAs() && !(parameter.isVarArgs() || parameter.getType().isArray())) {
|
||||
throw new UnsupportedOperationException("ErrorMessage allowESs cannot be used on non array or varargs parameter");
|
||||
throw new HandlerException("ErrorMessage allowESs cannot be used on non array or varargs parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -44,9 +44,9 @@ public final class GreedyHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Greedy, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Greedy annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Greedy annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (!parameter.getType().isArray() || parameter.isVarArgs()) {
|
||||
throw new UnsupportedOperationException("Greedy annotation cannot be used on non array parameters");
|
||||
throw new HandlerException("Greedy annotation cannot be used on non array parameters");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -35,9 +35,9 @@ public final class LengthHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Length, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Length annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Length annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Length annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Length annotation cannot be used on first parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-14
@@ -32,26 +32,29 @@ public final class MapperHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<Mapper>, Handler.HandlerParameter<Mapper, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Mapper annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Mapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() != 0) {
|
||||
throw new UnsupportedOperationException("Mapper method must have no parameters");
|
||||
throw new HandlerException("Mapper method must have no parameters");
|
||||
}
|
||||
if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) {
|
||||
throw new UnsupportedOperationException("Mapper method must return AbstractTypeMapper");
|
||||
if (!method.getReturnType().isAssignableTo(AbstractTypeMapper.class)) {
|
||||
throw new HandlerException("Mapper method must return AbstractTypeMapper");
|
||||
}
|
||||
|
||||
if (annotation.value() != null && !annotation.value().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<Class<?>> genericType = getGenericTypeOfReturn(method);
|
||||
if (annotation.type() == void.class) {
|
||||
if (genericType.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Please supply a class type to the Mapper");
|
||||
}
|
||||
} else {
|
||||
if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) {
|
||||
throw new UnsupportedOperationException("Supplied type does not conform to actual type");
|
||||
// TODO: Implement! for AnnotationProcessor as well!
|
||||
if (method instanceof MethodWrapper.ForMethod) {
|
||||
Optional<Class<?>> genericType = getGenericTypeOfReturn(((MethodWrapper.ForMethod) method).getMethod());
|
||||
if (annotation.type() == void.class) {
|
||||
if (genericType.isEmpty()) {
|
||||
throw new HandlerException("Please supply a class type to the Mapper");
|
||||
}
|
||||
} else {
|
||||
if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) {
|
||||
throw new HandlerException("Supplied type does not conform to actual type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,9 +77,9 @@ public final class MapperHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(Mapper annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Mapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Mapper annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Mapper annotation cannot be used on first parameter");
|
||||
}
|
||||
if (!dataCheckable.hasMapper(annotation.value())) {
|
||||
throw new UnsupportedOperationException("Mapper '" + annotation.value() + "' not found");
|
||||
|
||||
+13
-13
@@ -34,15 +34,15 @@ public final class MaxHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Max, Object, Number> {
|
||||
|
||||
@Override
|
||||
public void check(Max max, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Max max, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Max annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Max annotation cannot be used on first parameter");
|
||||
}
|
||||
Class<?> type = parameter.getType();
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (parameter.isVarArgs()) type = type.getComponentType();
|
||||
|
||||
if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != float.class && type != Float.class && type != double.class && type != Double.class) {
|
||||
throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number.");
|
||||
if (!type.is(int.class) && !type.is(Integer.class) && !type.is(long.class) && !type.is(Long.class) && !type.is(float.class) && !type.is(Float.class) && !type.is(double.class) && !type.is(Double.class)) {
|
||||
throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.");
|
||||
}
|
||||
|
||||
if (!parameter.isAnnotationPresent(Min.class)) {
|
||||
@@ -52,13 +52,13 @@ public final class MaxHandler {
|
||||
Min min = parameter.getAnnotation(Min.class);
|
||||
|
||||
Number minValue;
|
||||
if (type.equals(int.class) || type.equals(Integer.class)) {
|
||||
if (type.is(int.class) || type.is(Integer.class)) {
|
||||
minValue = min.intValue();
|
||||
} else if (type.equals(long.class) || type.equals(Long.class)) {
|
||||
} else if (type.is(long.class) || type.is(Long.class)) {
|
||||
minValue = min.longValue();
|
||||
} else if (type.equals(float.class) || type.equals(Float.class)) {
|
||||
} else if (type.is(float.class) || type.is(Float.class)) {
|
||||
minValue = min.floatValue();
|
||||
} else if (type.equals(double.class) || type.equals(Double.class)) {
|
||||
} else if (type.is(double.class) || type.is(Double.class)) {
|
||||
minValue = min.doubleValue();
|
||||
} else {
|
||||
throw new SecurityException();
|
||||
@@ -66,9 +66,9 @@ public final class MaxHandler {
|
||||
|
||||
ToIntFunction<Number> maxComparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue());
|
||||
if (!(min.inclusive() && max.inclusive()) && maxComparator.applyAsInt(minValue) == 0) {
|
||||
throw new UnsupportedOperationException("Min and Max cannot be equal if not both are inclusive");
|
||||
throw new HandlerException("Min and Max cannot be equal if not both are inclusive");
|
||||
} else if (maxComparator.applyAsInt(minValue) > 0) {
|
||||
throw new UnsupportedOperationException("Max must be bigger then Min");
|
||||
throw new HandlerException("Max must be bigger then Min");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public final class MaxHandler {
|
||||
if (parameter.isVarArgs()) type = type.getComponentType();
|
||||
|
||||
int compareValue = max.inclusive() ? 0 : -1;
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue());
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Max", new TypeWrapper.ForClass(type), max.intValue(), max.longValue(), max.floatValue(), max.doubleValue());
|
||||
boolean onlyNegative = comparator.applyAsInt(0) >= 0;
|
||||
|
||||
Min min = parameter.getAnnotation(Min.class);
|
||||
@@ -155,7 +155,7 @@ public final class MaxHandler {
|
||||
}
|
||||
|
||||
int compareValue = max.inclusive() ? 0 : -1;
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue());
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Max", new TypeWrapper.ForClass(type), max.intValue(), max.longValue(), max.floatValue(), max.doubleValue());
|
||||
|
||||
return (sender, value, messageSender) -> {
|
||||
if (value == null) return true;
|
||||
|
||||
+13
-13
@@ -36,20 +36,20 @@ public final class MaxReferenceHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Max.Reference, Object, Number> {
|
||||
|
||||
@Override
|
||||
public void check(Max.Reference annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Max.Reference annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Max.Reference annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Max.Reference annotation cannot be used on first parameter");
|
||||
}
|
||||
|
||||
Class<?> type = parameter.getType();
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != float.class && type != Float.class && type != double.class && type != Double.class) {
|
||||
throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number.");
|
||||
if (!type.is(int.class) && !type.is(Integer.class) && !type.is(long.class) && !type.is(Long.class) && !type.is(float.class) && !type.is(Float.class) && !type.is(double.class) && !type.is(Double.class)) {
|
||||
throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.");
|
||||
}
|
||||
|
||||
Parameter[] parameters = parameter.getDeclaringExecutable().getParameters();
|
||||
ParameterWrapper[] parameters = methodWrapper.getParameters();
|
||||
for (int i = index - 1; i >= 1; i--) {
|
||||
Parameter toCheck = parameters[i];
|
||||
ParameterWrapper toCheck = parameters[i];
|
||||
Name name = toCheck.getAnnotation(Name.class);
|
||||
String parameterName;
|
||||
if (name == null) {
|
||||
@@ -60,14 +60,14 @@ public final class MaxReferenceHandler {
|
||||
if (!parameterName.equals(annotation.value())) {
|
||||
continue;
|
||||
}
|
||||
Class<?> parameterType = toCheck.getType();
|
||||
if (!type.isAssignableFrom(parameterType)) {
|
||||
throw new UnsupportedOperationException("Parameter type being referenced cannot be assigned here!");
|
||||
TypeWrapper parameterType = toCheck.getType();
|
||||
if (!parameterType.isAssignableTo(type)) {
|
||||
throw new HandlerException("Parameter type being referenced cannot be assigned here!");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Parameter with name '" + annotation.value() + "' does not exist.");
|
||||
throw new HandlerException("Parameter with name '" + annotation.value() + "' does not exist.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +79,7 @@ public final class MaxReferenceHandler {
|
||||
public AbstractTypeMapper<Object, Number> getTypeMapper(Max.Reference maxReference, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper<Object, Number> parentTypeMapper) {
|
||||
Class<?> type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
Class<?> finalType = type;
|
||||
Handler.TypeWrapper finalType = new TypeWrapper.ForClass(type);
|
||||
|
||||
String name = maxReference.value();
|
||||
int compareValue = maxReference.inclusive() ? 0 : -1;
|
||||
@@ -119,7 +119,7 @@ public final class MaxReferenceHandler {
|
||||
public AbstractTypeValidator<Object, Number> getValidator(Max.Reference maxReference, Parameter parameter, int index, DataReadable dataReadable) {
|
||||
Class<?> type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
Class<?> finalType = type;
|
||||
Handler.TypeWrapper finalType = new TypeWrapper.ForClass(type);
|
||||
|
||||
String name = maxReference.value();
|
||||
int compareValue = maxReference.inclusive() ? 0 : -1;
|
||||
|
||||
+10
-11
@@ -32,19 +32,18 @@ import java.util.function.ToIntFunction;
|
||||
public final class MinHandler {
|
||||
|
||||
public static final class Impl implements Handler.HandlerParameter<Min, Object, Number> {
|
||||
|
||||
@Override
|
||||
public void check(Min min, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Min annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Min annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Min annotation cannot be used on first parameter");
|
||||
}
|
||||
Class<?> type = parameter.getType();
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (parameter.isVarArgs()) type = type.getComponentType();
|
||||
if (type == int.class || type == Integer.class) return;
|
||||
if (type == long.class || type == Long.class) return;
|
||||
if (type == float.class || type == Float.class) return;
|
||||
if (type == double.class || type == Double.class) return;
|
||||
throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number.");
|
||||
if (type.is(int.class) || type.is(Integer.class)) return;
|
||||
if (type.is(long.class) || type.is(Long.class)) return;
|
||||
if (type.is(float.class) || type.is(Float.class)) return;
|
||||
if (type.is(double.class) || type.is(Double.class)) return;
|
||||
throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +57,7 @@ public final class MinHandler {
|
||||
if (parameter.isVarArgs()) type = type.getComponentType();
|
||||
|
||||
int compareValue = min.inclusive() ? 0 : 1;
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Min", type, min.intValue(), min.longValue(), min.floatValue(), min.doubleValue());
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Min", new TypeWrapper.ForClass(type), min.intValue(), min.longValue(), min.floatValue(), min.doubleValue());
|
||||
boolean onlyPositive = comparator.applyAsInt(0) < 0;
|
||||
|
||||
Max max = parameter.getAnnotation(Max.class);
|
||||
@@ -130,7 +129,7 @@ public final class MinHandler {
|
||||
}
|
||||
|
||||
int compareValue = min.inclusive() ? 0 : 1;
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Min", type, min.intValue(), min.longValue(), min.floatValue(), min.doubleValue());
|
||||
ToIntFunction<Number> comparator = CommandUtils.createComparator("Min", new TypeWrapper.ForClass(type), min.intValue(), min.longValue(), min.floatValue(), min.doubleValue());
|
||||
|
||||
return (sender, value, messageSender) -> {
|
||||
if (value == null) return true;
|
||||
|
||||
+13
-13
@@ -36,20 +36,20 @@ public final class MinReferenceHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Min.Reference, Object, Number> {
|
||||
|
||||
@Override
|
||||
public void check(Min.Reference annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Min.Reference annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Min.Reference annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Min.Reference annotation cannot be used on first parameter");
|
||||
}
|
||||
|
||||
Class<?> type = parameter.getType();
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != float.class && type != Float.class && type != double.class && type != Double.class) {
|
||||
throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number.");
|
||||
if (!type.is(int.class) && !type.is(Integer.class) && !type.is(long.class) && !type.is(Long.class) && !type.is(float.class) && !type.is(Float.class) && !type.is(double.class) && !type.is(Double.class)) {
|
||||
throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.");
|
||||
}
|
||||
|
||||
Parameter[] parameters = parameter.getDeclaringExecutable().getParameters();
|
||||
ParameterWrapper[] parameters = methodWrapper.getParameters();
|
||||
for (int i = index - 1; i >= 1; i--) {
|
||||
Parameter toCheck = parameters[i];
|
||||
ParameterWrapper toCheck = parameters[i];
|
||||
Name name = toCheck.getAnnotation(Name.class);
|
||||
String parameterName;
|
||||
if (name == null) {
|
||||
@@ -60,14 +60,14 @@ public final class MinReferenceHandler {
|
||||
if (!parameterName.equals(annotation.value())) {
|
||||
continue;
|
||||
}
|
||||
Class<?> parameterType = toCheck.getType();
|
||||
if (!type.isAssignableFrom(parameterType)) {
|
||||
throw new UnsupportedOperationException("Parameter type being referenced cannot be assigned here!");
|
||||
TypeWrapper parameterType = toCheck.getType();
|
||||
if (!parameterType.isAssignableTo(type)) {
|
||||
throw new HandlerException("Parameter type being referenced cannot be assigned here!");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Parameter with name '" + annotation.value() + "' does not exist.");
|
||||
throw new HandlerException("Parameter with name '" + annotation.value() + "' does not exist.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +79,7 @@ public final class MinReferenceHandler {
|
||||
public AbstractTypeMapper<Object, Number> getTypeMapper(Min.Reference minReference, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper<Object, Number> parentTypeMapper) {
|
||||
Class<?> type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
Class<?> finalType = type;
|
||||
Handler.TypeWrapper finalType = new TypeWrapper.ForClass(type);
|
||||
|
||||
String name = minReference.value();
|
||||
int compareValue = minReference.inclusive() ? 0 : 1;
|
||||
@@ -119,7 +119,7 @@ public final class MinReferenceHandler {
|
||||
public AbstractTypeValidator<Object, Number> getValidator(Min.Reference minReference, Parameter parameter, int index, DataReadable dataReadable) {
|
||||
Class<?> type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
Class<?> finalType = type;
|
||||
Handler.TypeWrapper finalType = new TypeWrapper.ForClass(type);
|
||||
|
||||
String name = minReference.value();
|
||||
int compareValue = minReference.inclusive() ? 0 : 1;
|
||||
|
||||
+3
-3
@@ -35,12 +35,12 @@ public final class OptionalValueHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<OptionalValue, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(OptionalValue annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(OptionalValue annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("OptionalValue annotation cannot be used on the first parameter");
|
||||
throw new HandlerException("OptionalValue annotation cannot be used on the first parameter");
|
||||
}
|
||||
if (parameter.isVarArgs() || parameter.getType().isArray()) {
|
||||
throw new UnsupportedOperationException("OptionalValue annotation cannot be used on varargs or array parameters");
|
||||
throw new HandlerException("OptionalValue annotation cannot be used on varargs or array parameters");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -31,12 +31,12 @@ public final class RegexHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Regex, Object, String> {
|
||||
|
||||
@Override
|
||||
public void check(Regex annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Regex annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Regex annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Regex annotation cannot be used on first parameter");
|
||||
}
|
||||
if (parameter.getType() != String.class) {
|
||||
throw new UnsupportedOperationException("Regex annotation cannot be used on String parameter");
|
||||
if (!parameter.getType().is(String.class)) {
|
||||
throw new HandlerException("Regex annotation cannot be used on String parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-15
@@ -34,52 +34,55 @@ public final class RegisterHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<Register> {
|
||||
|
||||
@Override
|
||||
public void check(de.steamwar.command.annotations.Register annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Register annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() == 0) {
|
||||
throw new UnsupportedOperationException("Register method must have at least one parameter");
|
||||
throw new HandlerException("Register method must have at least one parameter");
|
||||
}
|
||||
if (method.getReturnType() != void.class) {
|
||||
throw new UnsupportedOperationException("Register method must return void");
|
||||
if (!method.getReturnType().is(void.class)) {
|
||||
throw new HandlerException("Register method must return void");
|
||||
}
|
||||
if (!dataCheckable.hasExecutorMapper(method.getParameterTypes()[0])) {
|
||||
throw new UnsupportedOperationException("Register method first parameter must have a executor mapper registered");
|
||||
// TODO: Implement hasExecutorMapper!
|
||||
if (method instanceof MethodWrapper.ForMethod) {
|
||||
if (!dataCheckable.hasExecutorMapper(((MethodWrapper.ForMethod) method).getMethod().getParameterTypes()[0])) {
|
||||
throw new HandlerException("Register method first parameter must have a executor mapper registered");
|
||||
}
|
||||
}
|
||||
|
||||
Parameter[] parameters = method.getParameters();
|
||||
ParameterWrapper[] parameters = method.getParameters();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
Parameter parameter = parameters[i];
|
||||
List<Annotation> annotationList = CommandUtils.getAnnotations(parameter);
|
||||
ParameterWrapper parameter = parameters[i];
|
||||
List<Annotation> annotationList = parameter.getAnnotations();
|
||||
if (annotationList.isEmpty()) {
|
||||
if (i == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?> type = parameter.getType();
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (type.isArray()) {
|
||||
type = type.getComponentType();
|
||||
}
|
||||
if (!type.isEnum() && !dataCheckable.hasMapper(type.getName())) {
|
||||
throw new UnsupportedOperationException("Register method parameter " + parameter.getName() + " must be annotated or have a type mapper");
|
||||
throw new HandlerException("Register method parameter " + parameter.getName() + " must be annotated or have a type mapper");
|
||||
}
|
||||
} else {
|
||||
for (Annotation annotation1 : annotationList) {
|
||||
getParameterHandler(annotation1).check(annotation1, parameter, i, dataCheckable);
|
||||
getParameterHandler(annotation1).check(annotation1, method, parameter, i, dataCheckable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static HandlerParameter getParameterHandler(Annotation annotation) {
|
||||
public static HandlerParameter getParameterHandler(Annotation annotation) throws HandlerException {
|
||||
Implementation handler = annotation.annotationType().getAnnotation(Implementation.class);
|
||||
Handler handlerObject;
|
||||
try {
|
||||
handlerObject = handler.value().getConstructor().newInstance();
|
||||
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
|
||||
InvocationTargetException e) {
|
||||
throw new UnsupportedOperationException("Handler " + handler.value().getName() + " cannot be used to check the argument validity", e);
|
||||
throw new HandlerException("Handler " + handler.value().getName() + " cannot be used to check the argument validity");
|
||||
}
|
||||
if (!(handlerObject instanceof HandlerParameter)) {
|
||||
throw new UnsupportedOperationException("Handler " + handlerObject.getClass().getName() + " is not a HandlerParameter");
|
||||
throw new HandlerException("Handler " + handlerObject.getClass().getName() + " is not a HandlerParameter");
|
||||
}
|
||||
return (HandlerParameter) handlerObject;
|
||||
}
|
||||
|
||||
+4
-4
@@ -35,12 +35,12 @@ public final class StartsWithHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<StartsWith, Object, String> {
|
||||
|
||||
@Override
|
||||
public void check(StartsWith annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(StartsWith annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("StartsWith annotation cannot be used on first parameter");
|
||||
throw new HandlerException("StartsWith annotation cannot be used on first parameter");
|
||||
}
|
||||
if (parameter.getType() != String.class) {
|
||||
throw new UnsupportedOperationException("StartsWith annotation cannot be used on String parameter");
|
||||
if (!parameter.getType().is(String.class)) {
|
||||
throw new HandlerException("StartsWith annotation cannot be used on String parameter");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -34,16 +34,16 @@ public final class StaticValueHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<StaticValue, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(StaticValue annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(StaticValue annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("StaticValue annotation cannot be used on first parameter");
|
||||
throw new HandlerException("StaticValue annotation cannot be used on first parameter");
|
||||
}
|
||||
Class<?> type = parameter.getType();
|
||||
if (type == String.class) return;
|
||||
if (type == int.class || type == Integer.class) return;
|
||||
if (type == long.class || type == Long.class) return;
|
||||
if (type == boolean.class || type == Boolean.class) return;
|
||||
throw new UnsupportedOperationException("StaticValue parameter must be String, int, long or boolean");
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (type.is(String.class)) return;
|
||||
if (type.is(int.class) || type.is(Integer.class)) return;
|
||||
if (type.is(long.class) || type.is(Long.class)) return;
|
||||
if (type.is(boolean.class) || type.is(Boolean.class)) return;
|
||||
throw new HandlerException("StaticValue parameter must be String, int, long or boolean");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+15
-13
@@ -19,7 +19,6 @@
|
||||
|
||||
package de.steamwar.command.handler;
|
||||
|
||||
import de.steamwar.command.AbstractTypeMapper;
|
||||
import de.steamwar.command.AbstractTypeSupplier;
|
||||
import de.steamwar.command.Handler;
|
||||
import de.steamwar.command.annotations.AllowNull;
|
||||
@@ -36,26 +35,29 @@ public final class SupplierHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<Supplier>, Handler.HandlerParameter<Supplier, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Supplier annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Supplier annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() != 0) {
|
||||
throw new UnsupportedOperationException("Supplier method must have no parameters");
|
||||
throw new HandlerException("Supplier method must have no parameters");
|
||||
}
|
||||
if (!AbstractTypeSupplier.class.isAssignableFrom(method.getReturnType())) {
|
||||
throw new UnsupportedOperationException("Supplier method must return AbstractTypeSupplier");
|
||||
if (!method.getReturnType().isAssignableTo(AbstractTypeSupplier.class)) {
|
||||
throw new HandlerException("Supplier method must return AbstractTypeSupplier");
|
||||
}
|
||||
|
||||
if (annotation.value() != null && !annotation.value().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<Class<?>> genericType = getGenericTypeOfReturn(method);
|
||||
if (annotation.type() == void.class) {
|
||||
if (genericType.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Please supply a class type to the Supplier");
|
||||
}
|
||||
} else {
|
||||
if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) {
|
||||
throw new UnsupportedOperationException("Supplied type does not conform to actual type");
|
||||
// TODO: Implement! for AnnotationProcessor as well!
|
||||
if (method instanceof MethodWrapper.ForMethod) {
|
||||
Optional<Class<?>> genericType = getGenericTypeOfReturn(((MethodWrapper.ForMethod) method).getMethod());
|
||||
if (annotation.type() == void.class) {
|
||||
if (genericType.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Please supply a class type to the Supplier");
|
||||
}
|
||||
} else {
|
||||
if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) {
|
||||
throw new UnsupportedOperationException("Supplied type does not conform to actual type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -40,9 +40,9 @@ public final class TabFilterHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<TabFilter, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(TabFilter annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(TabFilter annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("TabFilter annotation cannot be used on first parameter");
|
||||
throw new HandlerException("TabFilter annotation cannot be used on first parameter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -36,12 +36,12 @@ public final class UniqueHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Unique, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Unique annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Unique annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Unique annotation cannot be used on the first parameter");
|
||||
throw new HandlerException("Unique annotation cannot be used on the first parameter");
|
||||
}
|
||||
if (!parameter.getType().isArray() && !parameter.isVarArgs()) {
|
||||
throw new UnsupportedOperationException("Unique annotation cannot be used on non array types");
|
||||
throw new HandlerException("Unique annotation cannot be used on non array types");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-12
@@ -32,26 +32,29 @@ public final class ValidatorHandler {
|
||||
public static final class Impl implements Handler.HandlerMethod<Validator>, Handler.HandlerParameter<Validator, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Validator annotation, Method method, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Validator annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (method.getParameterCount() != 0) {
|
||||
throw new UnsupportedOperationException("Validator method must have no parameters");
|
||||
throw new HandlerException("Validator method must have no parameters");
|
||||
}
|
||||
if (!AbstractTypeValidator.class.isAssignableFrom(method.getReturnType())) {
|
||||
throw new UnsupportedOperationException("Validator method must return AbstractValidator");
|
||||
if (!method.getReturnType().isAssignableTo(AbstractTypeValidator.class)) {
|
||||
throw new HandlerException("Validator method must return AbstractValidator");
|
||||
}
|
||||
|
||||
if (annotation.value() != null && !annotation.value().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<Class<?>> genericType = getGenericTypeOfReturn(method);
|
||||
if (annotation.type() == void.class) {
|
||||
if (genericType.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Please supply a class type to the Validator");
|
||||
}
|
||||
} else {
|
||||
if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) {
|
||||
throw new UnsupportedOperationException("Supplied type does not conform to actual type");
|
||||
// TODO: Implement! for AnnotationProcessor as well!
|
||||
if (method instanceof MethodWrapper.ForMethod) {
|
||||
Optional<Class<?>> genericType = getGenericTypeOfReturn(((MethodWrapper.ForMethod) method).getMethod());
|
||||
if (annotation.type() == void.class) {
|
||||
if (genericType.isEmpty()) {
|
||||
throw new HandlerException("Please supply a class type to the Validator");
|
||||
}
|
||||
} else {
|
||||
if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) {
|
||||
throw new HandlerException("Supplied type does not conform to actual type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -33,16 +33,16 @@ public final class ValuesHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Values, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Values annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Values annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Values annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Values annotation cannot be used on first parameter");
|
||||
}
|
||||
Class<?> type = parameter.getType();
|
||||
if (type == String.class) return;
|
||||
if (type == int.class || type == Integer.class) return;
|
||||
if (type == long.class || type == Long.class) return;
|
||||
if (type == boolean.class || type == Boolean.class) return;
|
||||
throw new UnsupportedOperationException("Values parameter must be String, int, long or boolean");
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (type.is(String.class)) return;
|
||||
if (type.is(int.class) || type.is(Integer.class)) return;
|
||||
if (type.is(long.class) || type.is(Long.class)) return;
|
||||
if (type.is(boolean.class) || type.is(Boolean.class)) return;
|
||||
throw new HandlerException("Values parameter must be String, int, long or boolean");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-12
@@ -25,7 +25,6 @@ import de.steamwar.command.PreviousArguments;
|
||||
import de.steamwar.command.annotations.Name;
|
||||
import de.steamwar.command.annotations.Values;
|
||||
import de.steamwar.command.mapper.internal.DelegatingMapper;
|
||||
import de.steamwar.command.utils.ClassEquality;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
@@ -37,20 +36,20 @@ public class ValuesReferenceHandler {
|
||||
public static final class Impl implements Handler.HandlerParameter<Values.Reference, Object, Object> {
|
||||
|
||||
@Override
|
||||
public void check(Values.Reference annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception {
|
||||
public void check(Values.Reference annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException {
|
||||
if (index == 0) {
|
||||
throw new UnsupportedOperationException("Values.Reference annotation cannot be used on first parameter");
|
||||
throw new HandlerException("Values.Reference annotation cannot be used on first parameter");
|
||||
}
|
||||
|
||||
Class<?> type = parameter.getType();
|
||||
TypeWrapper type = parameter.getType();
|
||||
if (type.isArray()) type = type.getComponentType();
|
||||
if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != String.class) {
|
||||
throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a String or Int or Long.");
|
||||
if (!type.is(int.class) && !type.is(Integer.class) && !type.is(long.class) && !type.is(Long.class) && !type.is(String.class)) {
|
||||
throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a String or Int or Long.");
|
||||
}
|
||||
|
||||
Parameter[] parameters = parameter.getDeclaringExecutable().getParameters();
|
||||
ParameterWrapper[] parameters = methodWrapper.getParameters();
|
||||
for (int i = index - 1; i >= 1; i--) {
|
||||
Parameter toCheck = parameters[i];
|
||||
ParameterWrapper toCheck = parameters[i];
|
||||
Name name = toCheck.getAnnotation(Name.class);
|
||||
String parameterName;
|
||||
if (name == null) {
|
||||
@@ -61,15 +60,15 @@ public class ValuesReferenceHandler {
|
||||
if (!parameterName.equals(annotation.value())) {
|
||||
continue;
|
||||
}
|
||||
Class<?> toCheckType = toCheck.getType();
|
||||
TypeWrapper toCheckType = toCheck.getType();
|
||||
if (toCheckType.isArray()) toCheckType = toCheckType.getComponentType();
|
||||
if (!ClassEquality.classEquals(type, toCheckType)) {
|
||||
throw new UnsupportedOperationException("Parameter type being referenced cannot be assigned here!");
|
||||
if (!toCheckType.is(type)) {
|
||||
throw new HandlerException("Parameter type being referenced cannot be assigned here!");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Parameter with name '" + annotation.value() + "' does not exist.");
|
||||
throw new HandlerException("Parameter with name '" + annotation.value() + "' does not exist.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user