From 3d6c50938c545605c94669e13942207fda23816c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 24 Nov 2025 10:00:45 +0100 Subject: [PATCH] Improve error messages --- .../command/HandlerForAnnotationMirror.java | 43 +++++++ .../command/HandlerForExecutableElement.java | 3 + .../command/HandlerForVariableElement.java | 105 +++++++++++------- .../AbstractAnnotationProcessor.java | 33 +++++- .../de/steamwar/command/AbstractCommand.java | 2 +- .../src/de/steamwar/command/Handler.java | 65 +++++++++-- .../command/handler/AllowNullHandler.java | 6 +- .../command/handler/ArrayLengthHandler.java | 10 +- .../command/handler/CachedHandler.java | 6 +- .../command/handler/ClassMapperHandler.java | 6 +- .../handler/ClassValidatorHandler.java | 6 +- .../command/handler/EndsWithHandler.java | 6 +- .../command/handler/ErrorMessageHandler.java | 8 +- .../command/handler/GreedyHandler.java | 4 +- .../command/handler/LengthHandler.java | 4 +- .../command/handler/MapperHandler.java | 24 ++-- .../steamwar/command/handler/MaxHandler.java | 24 ++-- .../command/handler/MaxReferenceHandler.java | 18 +-- .../steamwar/command/handler/MinHandler.java | 6 +- .../command/handler/MinReferenceHandler.java | 18 +-- .../command/handler/OptionalValueHandler.java | 6 +- .../command/handler/RegexHandler.java | 6 +- .../command/handler/RegisterHandler.java | 27 ++--- .../command/handler/StartsWithHandler.java | 6 +- .../command/handler/StaticValueHandler.java | 6 +- .../command/handler/SupplierHandler.java | 35 +++--- .../command/handler/TabFilterHandler.java | 4 +- .../command/handler/UniqueHandler.java | 6 +- .../command/handler/ValidatorHandler.java | 22 ++-- .../command/handler/ValuesHandler.java | 6 +- .../handler/ValuesReferenceHandler.java | 18 +-- 31 files changed, 336 insertions(+), 203 deletions(-) create mode 100644 CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForAnnotationMirror.java diff --git a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForAnnotationMirror.java b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForAnnotationMirror.java new file mode 100644 index 00000000..d7c0bff4 --- /dev/null +++ b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForAnnotationMirror.java @@ -0,0 +1,43 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import lombok.Getter; + +import javax.lang.model.element.AnnotationMirror; +import java.lang.annotation.Annotation; + +public class HandlerForAnnotationMirror implements Handler.AnnotationWrapper { + + private A annotation; + + @Getter + private AnnotationMirror annotationMirror; + + public HandlerForAnnotationMirror(A annotation, AnnotationMirror annotationMirror) { + this.annotation = annotation; + this.annotationMirror = annotationMirror; + } + + @Override + public A getAnnotation() { + return annotation; + } +} diff --git a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForExecutableElement.java b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForExecutableElement.java index 5810b2bf..20e86015 100644 --- a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForExecutableElement.java +++ b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForExecutableElement.java @@ -19,6 +19,8 @@ package de.steamwar.command; +import lombok.Getter; + import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.VariableElement; import javax.lang.model.util.Elements; @@ -27,6 +29,7 @@ import java.util.List; public class HandlerForExecutableElement implements Handler.MethodWrapper { + @Getter private final ExecutableElement method; private final Types types; private final Elements elements; diff --git a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java index 7bceb912..1336cc77 100644 --- a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java +++ b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java @@ -19,6 +19,9 @@ package de.steamwar.command; +import de.steamwar.command.utils.Pair; +import lombok.Getter; + import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.VariableElement; import javax.lang.model.util.Elements; @@ -26,12 +29,15 @@ import javax.lang.model.util.Types; import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; public class HandlerForVariableElement implements Handler.ParameterWrapper { + @Getter private final VariableElement parameter; private final Types types; private final Elements elements; @@ -60,8 +66,14 @@ public class HandlerForVariableElement implements Handler.ParameterWrapper { } @Override - public A getAnnotation(Class annotation) { - return parameter.getAnnotation(annotation); + public Handler.AnnotationWrapper getAnnotation(Class annotation) { + A ann = parameter.getAnnotation(annotation); + AnnotationMirror annMirror = parameter.getAnnotationMirrors() + .stream() + .filter(am -> new HandlerForTypeMirror(am.getAnnotationType(), types, elements).is(annotation)) + .findFirst() + .orElse(null); + return new HandlerForAnnotationMirror<>(ann, annMirror); } @Override @@ -70,44 +82,53 @@ public class HandlerForVariableElement implements Handler.ParameterWrapper { } @Override - public List getAnnotations() { - List annotations = new ArrayList<>(); - for (AnnotationMirror annotationMirror : parameter.getAnnotationMirrors()) { - Class clazz = getClass(annotationMirror.getAnnotationType().toString()); - if (clazz == null) continue; - annotations.add(parameter.getAnnotation((Class) clazz)); - } - List annotationList = new ArrayList<>(); - for (Annotation annotation : annotations) { - try { - Method method = annotation.annotationType().getMethod("value"); - Class returnType = method.getReturnType(); - if (!returnType.isArray()) { - annotationList.add(annotation); - continue; - } - Class innerReturnType = returnType.getComponentType(); - if (!(innerReturnType.isAnnotation() && innerReturnType.isAnnotationPresent(Repeatable.class))) { - annotationList.add(annotation); - continue; - } - Repeatable repeatable = innerReturnType.getAnnotation(Repeatable.class); - Class containerType = repeatable.value(); - if (containerType == returnType) { - throw new UnsupportedOperationException("Repeatable annotation must have a container annotation"); - } - try { - Annotation[] innerAnnotations = (Annotation[]) method.invoke(annotation); - Collections.addAll(annotationList, innerAnnotations); - } catch (Exception e) { - annotationList.add(annotation); - } - } catch (NoSuchMethodException e) { - annotationList.add(annotation); - } - } - annotationList.removeIf(annotation -> !annotation.annotationType().isAnnotationPresent(Handler.Implementation.class)); - return annotationList; + public List> getAnnotations() { + return parameter.getAnnotationMirrors() + .stream() + .collect(Collectors.toMap(Function.identity(), annotationMirror -> { + Class clazz = getClass(annotationMirror.getAnnotationType().toString()); + if (clazz == null) return null; + return parameter.getAnnotation((Class) clazz); + })) + .entrySet() + .stream() + .filter(entry -> entry.getValue() != null) + .collect(Collectors.toMap(Map.Entry::getKey, entry -> { + Annotation annotation = entry.getValue(); + try { + Method method = annotation.annotationType().getMethod("value"); + Class returnType = method.getReturnType(); + if (!returnType.isArray()) { + return List.of(annotation); + } + Class innerReturnType = returnType.getComponentType(); + if (!(innerReturnType.isAnnotation() && innerReturnType.isAnnotationPresent(Repeatable.class))) { + return List.of(annotation); + } + Repeatable repeatable = innerReturnType.getAnnotation(Repeatable.class); + Class containerType = repeatable.value(); + if (containerType == returnType) { + throw new UnsupportedOperationException("Repeatable annotation must have a container annotation"); + } + try { + return Arrays.asList((Annotation[]) method.invoke(annotation)); + } catch (Exception e) { + return List.of(annotation); + } + } catch (NoSuchMethodException e) { + return List.of(annotation); + } + })) + .entrySet() + .stream() + .flatMap(entry -> { + return entry.getValue() + .stream() + .map(annotation -> new Pair(entry.getKey(), annotation)); + }) + .filter(pair -> pair.b.annotationType().isAnnotationPresent(Handler.Implementation.class)) + .map(pair -> new HandlerForAnnotationMirror<>(pair.b, pair.a)) + .collect(Collectors.toList()); } private Class getClass(String name) { diff --git a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/annotationprocessor/AbstractAnnotationProcessor.java b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/annotationprocessor/AbstractAnnotationProcessor.java index f42aee58..e0192693 100644 --- a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/annotationprocessor/AbstractAnnotationProcessor.java +++ b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/annotationprocessor/AbstractAnnotationProcessor.java @@ -20,22 +20,22 @@ package de.steamwar.command.annotationprocessor; import de.steamwar.command.Handler; +import de.steamwar.command.HandlerForAnnotationMirror; import de.steamwar.command.HandlerForExecutableElement; +import de.steamwar.command.HandlerForVariableElement; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; +import javax.lang.model.element.*; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; @@ -102,9 +102,30 @@ public abstract class AbstractAnnotationProcessor extends AbstractProcessor { } Handler.HandlerMethod handlerMethod = (Handler.HandlerMethod) handler; try { - handlerMethod.check(annotation, new HandlerForExecutableElement(method, types, elements), DataCheckableImpl.INSTANCE); + handlerMethod.check(new HandlerForAnnotationMirror(annotation, null), new HandlerForExecutableElement(method, types, elements), DataCheckableImpl.INSTANCE); } catch (Handler.HandlerException e) { - messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), method); + Handler.CodePlace codePlace = e.getCodePlace(); + AnnotationMirror[] annotationMirrors = new AnnotationMirror[0]; + if (codePlace.getAnnotations().length > 0) { + annotationMirrors = Arrays.stream(codePlace.getAnnotations()) + .map(annotationWrapper -> (HandlerForAnnotationMirror) annotationWrapper) + .map(HandlerForAnnotationMirror::getAnnotationMirror) + .toArray(AnnotationMirror[]::new); + } + Element element = null; + if (codePlace.getMethod() != null) { + element = ((HandlerForExecutableElement) codePlace.getMethod()).getMethod(); + } else if (codePlace.getParameter() != null) { + element = ((HandlerForVariableElement) codePlace.getParameter()).getParameter(); + } + + if (annotationMirrors.length > 0) { + for (int i = 0; i < annotationMirrors.length; i++) { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element, annotationMirrors[i]); + } + } else { + messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), element); + } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java index 384fe1e3..8c539475 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java @@ -185,7 +185,7 @@ public abstract class AbstractCommand { handlerMap.get(runPriority).forEach((dataMethodAnnotationTriple, handlerMethods) -> { handlerMethods.forEach(annotationHandlerMethod -> { try { - annotationHandlerMethod.check(dataMethodAnnotationTriple.c, new Handler.MethodWrapper.ForMethod(dataMethodAnnotationTriple.b), dataMethodAnnotationTriple.a); + annotationHandlerMethod.check(new Handler.AnnotationWrapper.ForAnnotation<>(dataMethodAnnotationTriple.c), new Handler.MethodWrapper.ForMethod(dataMethodAnnotationTriple.b), dataMethodAnnotationTriple.a); } catch (Exception e) { throw new UnsupportedOperationException("Method check failed for " + dataMethodAnnotationTriple.b.getName(), e); } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java index c04a1d3a..ebc577ef 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.function.Function; +import java.util.stream.Collectors; public interface Handler { @@ -63,8 +64,12 @@ public interface Handler { } class HandlerException extends Exception { - public HandlerException(String message) { + @Getter + private final CodePlace codePlace; + + public HandlerException(String message, CodePlace codePlace) { super(message); + this.codePlace = codePlace; } } @@ -106,7 +111,7 @@ public interface Handler { } interface HandlerMethod extends Handler { - void check(T annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException; + void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException; int getRunPriority(); @@ -114,7 +119,7 @@ public interface Handler { } interface HandlerParameter extends Handler { - void check(T annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException; + void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException; default boolean needsParentTypeMapper() { return false; @@ -139,6 +144,26 @@ public interface Handler { } } + @Getter + class CodePlace { + + private final MethodWrapper method; + private final ParameterWrapper parameter; + private final AnnotationWrapper[] annotations; + + public CodePlace(MethodWrapper method, AnnotationWrapper... annotations) { + this.method = method; + this.parameter = null; + this.annotations = annotations; + } + + public CodePlace(ParameterWrapper parameter, AnnotationWrapper... annotations) { + this.method = null; + this.parameter = parameter; + this.annotations = annotations; + } + } + interface MethodWrapper { String getName(); @@ -186,11 +211,11 @@ public interface Handler { boolean isAnnotationPresent(Class annotation); - A getAnnotation(Class annotation); + AnnotationWrapper getAnnotation(Class annotation); String getName(); - List getAnnotations(); + List> getAnnotations(); class ForParameter implements ParameterWrapper { @@ -217,8 +242,8 @@ public interface Handler { } @Override - public A getAnnotation(Class annotation) { - return parameter.getAnnotation(annotation); + public AnnotationWrapper getAnnotation(Class annotation) { + return new AnnotationWrapper.ForAnnotation<>(parameter.getAnnotation(annotation)); } @Override @@ -227,8 +252,11 @@ public interface Handler { } @Override - public List getAnnotations() { - return CommandUtils.getAnnotations(parameter); + public List> getAnnotations() { + return CommandUtils.getAnnotations(parameter) + .stream() + .map(AnnotationWrapper.ForAnnotation::new) + .collect(Collectors.toList()); } } } @@ -320,4 +348,23 @@ public interface Handler { } } } + + interface AnnotationWrapper { + + A getAnnotation(); + + class ForAnnotation implements AnnotationWrapper { + + private A annotation; + + public ForAnnotation(A annotation) { + this.annotation = annotation; + } + + @Override + public A getAnnotation() { + return this.annotation; + } + } + } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java index 340cc833..771bc78f 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java @@ -36,12 +36,12 @@ public final class AllowNullHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(AllowNull annotation, MethodWrapper method, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("AllowNull annotation cannot be used on the first parameter"); + throw new HandlerException("AllowNull annotation cannot be used on the first parameter", new CodePlace(parameter, annotation)); } if (parameter.getType().isPrimitive()) { - throw new HandlerException("AllowNull annotation cannot be used on primitive types"); + throw new HandlerException("AllowNull annotation cannot be used on primitive types", new CodePlace(parameter)); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java index 65ff83a4..24c7289a 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java @@ -47,15 +47,15 @@ public final class ArrayLengthHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(ArrayLength arrayLength, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper arrayLength, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("ArrayLength annotation cannot be used on first parameter"); + throw new HandlerException("ArrayLength annotation cannot be used on first parameter", new CodePlace(parameter, arrayLength)); } if (!parameter.getType().isArray()) { - throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not an array"); + throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not an array", new CodePlace(parameter)); } - if (arrayLength.min() > arrayLength.max()) { - throw new HandlerException("Min ArrayLength cannot be smaller than Max ArrayLength"); + if (arrayLength.getAnnotation().min() > arrayLength.getAnnotation().max()) { + throw new HandlerException("Min ArrayLength cannot be smaller than Max ArrayLength", new CodePlace(parameter, arrayLength)); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java index a72023d8..f44a3f2f 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java @@ -31,12 +31,12 @@ public final class CachedHandler { public static final class Impl implements Handler.HandlerMethod { @Override - public void check(Cached annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() != 0) { - throw new HandlerException("Cached method must have no parameters"); + throw new HandlerException("Cached method must have no parameters", new CodePlace(method)); } if (!method.getReturnType().isAssignableTo(AbstractTypeMapper.class)) { - throw new HandlerException("Cached method must return AbstractTypeMapper"); + throw new HandlerException("Cached method must return AbstractTypeMapper", new CodePlace(method)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java index 15d7a97d..d98d1784 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java @@ -31,12 +31,12 @@ public final class ClassMapperHandler { public static final class Impl implements Handler.HandlerMethod { @Override - public void check(ClassMapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() != 0) { - throw new HandlerException("ClassMapper method must have no parameters"); + throw new HandlerException("ClassMapper method must have no parameters", new CodePlace(method)); } if (!method.getReturnType().isAssignableTo(AbstractTypeMapper.class)) { - throw new HandlerException("ClassMapper method must return AbstractTypeMapper"); + throw new HandlerException("ClassMapper method must return AbstractTypeMapper", new CodePlace(method)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java index 2a282cf0..c12d5d54 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java @@ -31,12 +31,12 @@ public final class ClassValidatorHandler { public static final class Impl implements Handler.HandlerMethod { @Override - public void check(ClassValidator annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() != 0) { - throw new HandlerException("ClassValidator method must have no parameters"); + throw new HandlerException("ClassValidator method must have no parameters", new CodePlace(method)); } if (!method.getReturnType().isAssignableTo(AbstractTypeValidator.class)) { - throw new HandlerException("ClassValidator method must return AbstractValidator"); + throw new HandlerException("ClassValidator method must return AbstractValidator", new CodePlace(method)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java index 5ea8500f..bb33502c 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java @@ -35,12 +35,12 @@ public final class EndsWithHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(EndsWith annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("EndsWith annotation cannot be used on first parameter"); + throw new HandlerException("EndsWith annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } if (!parameter.getType().is(String.class)) { - throw new HandlerException("EndsWith annotation cannot be used on String parameter"); + throw new HandlerException("EndsWith annotation cannot be used on String parameter", new CodePlace(parameter)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java index 56dd5e0a..f7050c55 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java @@ -31,12 +31,12 @@ public final class ErrorMessageHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(ErrorMessage errorMessage, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper errorMessage, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("ErrorMessage annotation cannot be used on first parameter"); + throw new HandlerException("ErrorMessage annotation cannot be used on first parameter", new CodePlace(parameter, errorMessage)); } - if (!errorMessage.allowEAs() && !(parameter.isVarArgs() || parameter.getType().isArray())) { - throw new HandlerException("ErrorMessage allowESs cannot be used on non array or varargs parameter"); + if (!errorMessage.getAnnotation().allowEAs() && !(parameter.isVarArgs() || parameter.getType().isArray())) { + throw new HandlerException("ErrorMessage allowESs cannot be used on non array or varargs parameter", new CodePlace(parameter)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java index 4d595a8e..86d6bce8 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java @@ -44,9 +44,9 @@ public final class GreedyHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Greedy annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (!parameter.getType().isArray() || parameter.isVarArgs()) { - throw new HandlerException("Greedy annotation cannot be used on non array parameters"); + throw new HandlerException("Greedy annotation cannot be used on non array parameters", new CodePlace(parameter)); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java index aedb45c9..0228fc51 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java @@ -35,9 +35,9 @@ public final class LengthHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Length annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Length annotation cannot be used on first parameter"); + throw new HandlerException("Length annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java index cc99fd19..6ff361b4 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java @@ -32,28 +32,28 @@ public final class MapperHandler { public static final class Impl implements Handler.HandlerMethod, Handler.HandlerParameter { @Override - public void check(Mapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() != 0) { - throw new HandlerException("Mapper method must have no parameters"); + throw new HandlerException("Mapper method must have no parameters", new CodePlace(method)); } if (!method.getReturnType().isAssignableTo(AbstractTypeMapper.class)) { - throw new HandlerException("Mapper method must return AbstractTypeMapper"); + throw new HandlerException("Mapper method must return AbstractTypeMapper", new CodePlace(method)); } - if (annotation.value() != null && !annotation.value().isEmpty()) { + if (annotation.getAnnotation().value() != null && !annotation.getAnnotation().value().isEmpty()) { return; } // TODO: Implement! for AnnotationProcessor as well! if (method instanceof MethodWrapper.ForMethod) { Optional> genericType = getGenericTypeOfReturn(((MethodWrapper.ForMethod) method).getMethod()); - if (annotation.type() == void.class) { + if (annotation.getAnnotation().type() == void.class) { if (genericType.isEmpty()) { - throw new HandlerException("Please supply a class type to the Mapper"); + throw new HandlerException("Please supply a class type to the Mapper", new CodePlace(method)); } } else { - if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) { - throw new HandlerException("Supplied type does not conform to actual type"); + if (genericType.isPresent() && !annotation.getAnnotation().type().isAssignableFrom(genericType.get())) { + throw new HandlerException("Supplied type does not conform to actual type", new CodePlace(method)); } } } @@ -77,12 +77,12 @@ public final class MapperHandler { } @Override - public void check(Mapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Mapper annotation cannot be used on first parameter"); + throw new HandlerException("Mapper annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } - if (!dataCheckable.hasMapper(annotation.value())) { - throw new HandlerException("Mapper '" + annotation.value() + "' not found"); + if (!dataCheckable.hasMapper(annotation.getAnnotation().value())) { + throw new HandlerException("Mapper '" + annotation.getAnnotation().value() + "' not found", new CodePlace(parameter)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java index 65d98be1..bc6fc769 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java @@ -34,41 +34,41 @@ public final class MaxHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Max max, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper max, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Max annotation cannot be used on first parameter"); + throw new HandlerException("Max annotation cannot be used on first parameter", new CodePlace(parameter, max)); } TypeWrapper type = parameter.getType(); if (parameter.isVarArgs()) type = type.getComponentType(); 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."); + throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.", new CodePlace(parameter)); } if (!parameter.isAnnotationPresent(Min.class)) { return; } - Min min = parameter.getAnnotation(Min.class); + AnnotationWrapper min = parameter.getAnnotation(Min.class); Number minValue; if (type.is(int.class) || type.is(Integer.class)) { - minValue = min.intValue(); + minValue = min.getAnnotation().intValue(); } else if (type.is(long.class) || type.is(Long.class)) { - minValue = min.longValue(); + minValue = min.getAnnotation().longValue(); } else if (type.is(float.class) || type.is(Float.class)) { - minValue = min.floatValue(); + minValue = min.getAnnotation().floatValue(); } else if (type.is(double.class) || type.is(Double.class)) { - minValue = min.doubleValue(); + minValue = min.getAnnotation().doubleValue(); } else { throw new SecurityException(); } - ToIntFunction maxComparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue()); - if (!(min.inclusive() && max.inclusive()) && maxComparator.applyAsInt(minValue) == 0) { - throw new HandlerException("Min and Max cannot be equal if not both are inclusive"); + ToIntFunction maxComparator = CommandUtils.createComparator("Max", type, max.getAnnotation().intValue(), max.getAnnotation().longValue(), max.getAnnotation().floatValue(), max.getAnnotation().doubleValue()); + if (!(min.getAnnotation().inclusive() && max.getAnnotation().inclusive()) && maxComparator.applyAsInt(minValue) == 0) { + throw new HandlerException("Min and Max cannot be equal if not both are inclusive", new CodePlace(parameter, max, min)); } else if (maxComparator.applyAsInt(minValue) > 0) { - throw new HandlerException("Max must be bigger then Min"); + throw new HandlerException("Max must be bigger then Min", new CodePlace(parameter, max, min)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java index ec2031f8..896aa978 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java @@ -36,38 +36,38 @@ public final class MaxReferenceHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Max.Reference annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Max.Reference annotation cannot be used on first parameter"); + throw new HandlerException("Max.Reference annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } TypeWrapper type = parameter.getType(); if (type.isArray()) type = type.getComponentType(); 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."); + throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.", new CodePlace(parameter)); } ParameterWrapper[] parameters = methodWrapper.getParameters(); for (int i = index - 1; i >= 1; i--) { ParameterWrapper toCheck = parameters[i]; - Name name = toCheck.getAnnotation(Name.class); + AnnotationWrapper name = toCheck.getAnnotation(Name.class); String parameterName; - if (name == null) { + if (name.getAnnotation() == null) { parameterName = toCheck.getName(); } else { - parameterName = name.value(); + parameterName = name.getAnnotation().value(); } - if (!parameterName.equals(annotation.value())) { + if (!parameterName.equals(annotation.getAnnotation().value())) { continue; } TypeWrapper parameterType = toCheck.getType(); if (!parameterType.isAssignableTo(type)) { - throw new HandlerException("Parameter type being referenced cannot be assigned here!"); + throw new HandlerException("Parameter type being referenced cannot be assigned here!", new CodePlace(toCheck, name)); } else { return; } } - throw new HandlerException("Parameter with name '" + annotation.value() + "' does not exist."); + throw new HandlerException("Parameter with name '" + annotation.getAnnotation().value() + "' does not exist.", new CodePlace(parameter, annotation)); } @Override diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java index 4b2c01bc..4e76222c 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java @@ -33,9 +33,9 @@ public final class MinHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Min annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Min annotation cannot be used on first parameter"); + throw new HandlerException("Min annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } TypeWrapper type = parameter.getType(); if (parameter.isVarArgs()) type = type.getComponentType(); @@ -43,7 +43,7 @@ public final class MinHandler { 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."); + throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.", new CodePlace(parameter)); } @Override diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java index 34b2c1c7..3d2bd495 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java @@ -36,38 +36,38 @@ public final class MinReferenceHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Min.Reference annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Min.Reference annotation cannot be used on first parameter"); + throw new HandlerException("Min.Reference annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } TypeWrapper type = parameter.getType(); if (type.isArray()) type = type.getComponentType(); 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."); + throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a number.", new CodePlace(parameter)); } ParameterWrapper[] parameters = methodWrapper.getParameters(); for (int i = index - 1; i >= 1; i--) { ParameterWrapper toCheck = parameters[i]; - Name name = toCheck.getAnnotation(Name.class); + AnnotationWrapper name = toCheck.getAnnotation(Name.class); String parameterName; - if (name == null) { + if (name.getAnnotation() == null) { parameterName = toCheck.getName(); } else { - parameterName = name.value(); + parameterName = name.getAnnotation().value(); } - if (!parameterName.equals(annotation.value())) { + if (!parameterName.equals(annotation.getAnnotation().value())) { continue; } TypeWrapper parameterType = toCheck.getType(); if (!parameterType.isAssignableTo(type)) { - throw new HandlerException("Parameter type being referenced cannot be assigned here!"); + throw new HandlerException("Parameter type being referenced cannot be assigned here!", new CodePlace(toCheck, name)); } else { return; } } - throw new HandlerException("Parameter with name '" + annotation.value() + "' does not exist."); + throw new HandlerException("Parameter with name '" + annotation.getAnnotation().value() + "' does not exist.", new CodePlace(parameter, annotation)); } @Override diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java index 02ae0a1e..84eb89e5 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java @@ -35,12 +35,12 @@ public final class OptionalValueHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(OptionalValue annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("OptionalValue annotation cannot be used on the first parameter"); + throw new HandlerException("OptionalValue annotation cannot be used on the first parameter", new CodePlace(parameter, annotation)); } if (parameter.isVarArgs() || parameter.getType().isArray()) { - throw new HandlerException("OptionalValue annotation cannot be used on varargs or array parameters"); + throw new HandlerException("OptionalValue annotation cannot be used on varargs or array parameters", new CodePlace(parameter)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java index a66d5e4e..7cc444cc 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java @@ -31,12 +31,12 @@ public final class RegexHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Regex annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Regex annotation cannot be used on first parameter"); + throw new HandlerException("Regex annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } if (!parameter.getType().is(String.class)) { - throw new HandlerException("Regex annotation cannot be used on String parameter"); + throw new HandlerException("Regex annotation cannot be used on String parameter", new CodePlace(parameter)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java index 55b4c133..3e2efb4f 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java @@ -19,14 +19,11 @@ package de.steamwar.command.handler; -import de.steamwar.command.CommandUtils; import de.steamwar.command.Handler; import de.steamwar.command.annotations.Register; -import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; import java.util.List; public final class RegisterHandler { @@ -34,24 +31,24 @@ public final class RegisterHandler { public static final class Impl implements Handler.HandlerMethod { @Override - public void check(Register annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() == 0) { - throw new HandlerException("Register method must have at least one parameter"); + throw new HandlerException("Register method must have at least one parameter", new CodePlace(method)); } if (!method.getReturnType().is(void.class)) { - throw new HandlerException("Register method must return void"); + throw new HandlerException("Register method must return void", new CodePlace(method)); } // 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"); + throw new HandlerException("Register method first parameter must have a executor mapper registered", new CodePlace(method)); } } ParameterWrapper[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { ParameterWrapper parameter = parameters[i]; - List annotationList = parameter.getAnnotations(); + List> annotationList = parameter.getAnnotations(); if (annotationList.isEmpty()) { if (i == 0) { continue; @@ -62,27 +59,27 @@ public final class RegisterHandler { type = type.getComponentType(); } if (!type.isEnum() && !dataCheckable.hasMapper(type.getName())) { - throw new HandlerException("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", new CodePlace(parameter)); } } else { - for (Annotation annotation1 : annotationList) { - getParameterHandler(annotation1).check(annotation1, method, parameter, i, dataCheckable); + for (AnnotationWrapper annotation1 : annotationList) { + getParameterHandler(parameter, annotation1).check(annotation1, method, parameter, i, dataCheckable); } } } } - public static HandlerParameter getParameterHandler(Annotation annotation) throws HandlerException { - Implementation handler = annotation.annotationType().getAnnotation(Implementation.class); + public static HandlerParameter getParameterHandler(ParameterWrapper parameter, AnnotationWrapper annotation) throws HandlerException { + Implementation handler = annotation.getAnnotation().annotationType().getAnnotation(Implementation.class); Handler handlerObject; try { handlerObject = handler.value().getConstructor().newInstance(); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new HandlerException("Handler " + handler.value().getName() + " cannot be used to check the argument validity"); + throw new HandlerException("Handler " + handler.value().getName() + " cannot be used to check the argument validity", new CodePlace(parameter, annotation)); } if (!(handlerObject instanceof HandlerParameter)) { - throw new HandlerException("Handler " + handlerObject.getClass().getName() + " is not a HandlerParameter"); + throw new HandlerException("Handler " + handlerObject.getClass().getName() + " is not a HandlerParameter", new CodePlace(parameter, annotation)); } return (HandlerParameter) handlerObject; } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java index 39e39cf5..f4767ca8 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java @@ -35,12 +35,12 @@ public final class StartsWithHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(StartsWith annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("StartsWith annotation cannot be used on first parameter"); + throw new HandlerException("StartsWith annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } if (!parameter.getType().is(String.class)) { - throw new HandlerException("StartsWith annotation cannot be used on String parameter"); + throw new HandlerException("StartsWith annotation cannot be used on String parameter", new CodePlace(parameter)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java index 4c07ed46..0308914e 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java @@ -34,16 +34,16 @@ public final class StaticValueHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(StaticValue annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("StaticValue annotation cannot be used on first parameter"); + throw new HandlerException("StaticValue annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } 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"); + throw new HandlerException("StaticValue parameter must be String, int, long or boolean", new CodePlace(parameter)); } @Override diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java index 792a099c..fd598a17 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java @@ -33,28 +33,28 @@ public final class SupplierHandler { public static final class Impl implements Handler.HandlerMethod, Handler.HandlerParameter { @Override - public void check(Supplier annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() != 0) { - throw new HandlerException("Supplier method must have no parameters"); + throw new HandlerException("Supplier method must have no parameters", new CodePlace(method)); } if (!method.getReturnType().isAssignableTo(AbstractTypeSupplier.class)) { - throw new HandlerException("Supplier method must return AbstractTypeSupplier"); + throw new HandlerException("Supplier method must return AbstractTypeSupplier", new CodePlace(method)); } - if (annotation.value() != null && !annotation.value().isEmpty()) { + if (annotation.getAnnotation().value() != null && !annotation.getAnnotation().value().isEmpty()) { return; } // TODO: Implement! for AnnotationProcessor as well! if (method instanceof MethodWrapper.ForMethod) { Optional> genericType = getGenericTypeOfReturn(((MethodWrapper.ForMethod) method).getMethod()); - if (annotation.type() == void.class) { + if (annotation.getAnnotation().type() == void.class) { if (genericType.isEmpty()) { - throw new UnsupportedOperationException("Please supply a class type to the Supplier"); + throw new HandlerException("Please supply a class type to the Supplier", new CodePlace(method)); } } else { - if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) { - throw new UnsupportedOperationException("Supplied type does not conform to actual type"); + if (genericType.isPresent() && !annotation.getAnnotation().type().isAssignableFrom(genericType.get())) { + throw new HandlerException("Supplied type does not conform to actual type", new CodePlace(method)); } } } @@ -78,22 +78,23 @@ public final class SupplierHandler { } @Override - public void check(Supplier annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Supplier annotation cannot be used on the first parameter"); + throw new HandlerException("Supplier annotation cannot be used on the first parameter", new CodePlace(parameter, annotation)); } - String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); + String s = annotation.getAnnotation().value() != null && !annotation.getAnnotation().value().isEmpty() ? annotation.getAnnotation().value() : parameter.getType().getTypeName(); if (!dataCheckable.hasSupplier(s)) { - throw new HandlerException("Supplier '" + annotation.value() + "' not found"); + throw new HandlerException("Supplier '" + annotation.getAnnotation().value() + "' not found", new CodePlace(parameter)); } boolean hasDisallowedAnnotations = parameter.getAnnotations() .stream() - .filter(anno -> !(anno instanceof Supplier)) - .filter(anno -> !(anno instanceof AllowNull)) - .filter(anno -> !(anno instanceof Name)) - .anyMatch(anno -> anno.getClass().isAnnotationPresent(Implementation.class)); + .filter(anno -> !(anno.getAnnotation() instanceof Supplier)) + .filter(anno -> !(anno.getAnnotation() instanceof AllowNull)) + .filter(anno -> !(anno.getAnnotation() instanceof Name)) + .anyMatch(anno -> anno.getAnnotation().annotationType().isAnnotationPresent(Implementation.class)); if (hasDisallowedAnnotations) { - throw new HandlerException("Only AllowNull or Name can be used in conjunction with Supplier annotation"); + // TODO: Improve annotation handling! + throw new HandlerException("Only AllowNull or Name can be used in conjunction with Supplier annotation", new CodePlace(parameter)); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java index 0b93ac90..52e3b59d 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java @@ -40,9 +40,9 @@ public final class TabFilterHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(TabFilter annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("TabFilter annotation cannot be used on first parameter"); + throw new HandlerException("TabFilter annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java index 4f410afb..c38963cf 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java @@ -36,12 +36,12 @@ public final class UniqueHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Unique annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Unique annotation cannot be used on the first parameter"); + throw new HandlerException("Unique annotation cannot be used on the first parameter", new CodePlace(parameter, annotation)); } if (!parameter.getType().isArray() && !parameter.isVarArgs()) { - throw new HandlerException("Unique annotation cannot be used on non array types"); + throw new HandlerException("Unique annotation cannot be used on non array types", new CodePlace(parameter)); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java index f7ed5b80..b22183b6 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java @@ -32,28 +32,28 @@ public final class ValidatorHandler { public static final class Impl implements Handler.HandlerMethod, Handler.HandlerParameter { @Override - public void check(Validator annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException { if (method.getParameterCount() != 0) { - throw new HandlerException("Validator method must have no parameters"); + throw new HandlerException("Validator method must have no parameters", new CodePlace(method)); } if (!method.getReturnType().isAssignableTo(AbstractTypeValidator.class)) { - throw new HandlerException("Validator method must return AbstractValidator"); + throw new HandlerException("Validator method must return AbstractValidator", new CodePlace(method)); } - if (annotation.value() != null && !annotation.value().isEmpty()) { + if (annotation.getAnnotation().value() != null && !annotation.getAnnotation().value().isEmpty()) { return; } // TODO: Implement! for AnnotationProcessor as well! if (method instanceof MethodWrapper.ForMethod) { Optional> genericType = getGenericTypeOfReturn(((MethodWrapper.ForMethod) method).getMethod()); - if (annotation.type() == void.class) { + if (annotation.getAnnotation().type() == void.class) { if (genericType.isEmpty()) { - throw new HandlerException("Please supply a class type to the Validator"); + throw new HandlerException("Please supply a class type to the Validator", new CodePlace(method)); } } else { - if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) { - throw new HandlerException("Supplied type does not conform to actual type"); + if (genericType.isPresent() && !annotation.getAnnotation().type().isAssignableFrom(genericType.get())) { + throw new HandlerException("Supplied type does not conform to actual type", new CodePlace(method)); } } } @@ -77,10 +77,10 @@ public final class ValidatorHandler { } @Override - public void check(Validator annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { - String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + String s = annotation.getAnnotation().value() != null && !annotation.getAnnotation().value().isEmpty() ? annotation.getAnnotation().value() : parameter.getType().getTypeName(); if (!dataCheckable.hasValidator(s)) { - throw new HandlerException("Validator '" + annotation.value() + "' not found"); + throw new HandlerException("Validator '" + annotation.getAnnotation().value() + "' not found", new CodePlace(parameter, annotation)); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java index 75536fcd..7cb369f2 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java @@ -33,16 +33,16 @@ public final class ValuesHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Values annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Values annotation cannot be used on first parameter"); + throw new HandlerException("Values annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } 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"); + throw new HandlerException("Values parameter must be String, int, long or boolean", new CodePlace(parameter)); } @Override diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java index b3543dd2..50dc9454 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java @@ -36,39 +36,39 @@ public class ValuesReferenceHandler { public static final class Impl implements Handler.HandlerParameter { @Override - public void check(Values.Reference annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { + public void check(AnnotationWrapper annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new HandlerException("Values.Reference annotation cannot be used on first parameter"); + throw new HandlerException("Values.Reference annotation cannot be used on first parameter", new CodePlace(parameter, annotation)); } TypeWrapper type = parameter.getType(); if (type.isArray()) type = type.getComponentType(); 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."); + throw new HandlerException("Parameter " + index + " of " + methodWrapper.getName() + " is not a String or Int or Long.", new CodePlace(parameter)); } ParameterWrapper[] parameters = methodWrapper.getParameters(); for (int i = index - 1; i >= 1; i--) { ParameterWrapper toCheck = parameters[i]; - Name name = toCheck.getAnnotation(Name.class); + AnnotationWrapper name = toCheck.getAnnotation(Name.class); String parameterName; - if (name == null) { + if (name.getAnnotation() == null) { parameterName = toCheck.getName(); } else { - parameterName = name.value(); + parameterName = name.getAnnotation().value(); } - if (!parameterName.equals(annotation.value())) { + if (!parameterName.equals(annotation.getAnnotation().value())) { continue; } TypeWrapper toCheckType = toCheck.getType(); if (toCheckType.isArray()) toCheckType = toCheckType.getComponentType(); if (!toCheckType.is(type)) { - throw new HandlerException("Parameter type being referenced cannot be assigned here!"); + throw new HandlerException("Parameter type being referenced cannot be assigned here!", new CodePlace(toCheck, name)); } else { return; } } - throw new HandlerException("Parameter with name '" + annotation.value() + "' does not exist."); + throw new HandlerException("Parameter with name '" + annotation.getAnnotation().value() + "' does not exist.", new CodePlace(parameter, annotation)); } @Override