From ef61cf455da9769f13c34d31b37fc6f5fca8a5dd Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 23 Nov 2025 21:14:09 +0100 Subject: [PATCH] Fix MapperHandler, SupplierHandler, ValidatorHandler Improve HandlerForVariableElement.getAnnotations() Improve HandlerForTypeMirror.isEnum Add HandlerForTypeMirror.getTypeName --- .../command/HandlerForTypeMirror.java | 18 ++++++++- .../command/HandlerForVariableElement.java | 38 +++++++++++++++++-- .../de/steamwar/command/AbstractCommand.java | 2 +- .../src/de/steamwar/command/Handler.java | 21 +++++----- .../command/handler/MapperHandler.java | 2 +- .../command/handler/SupplierHandler.java | 13 +++---- .../command/handler/ValidatorHandler.java | 4 +- 7 files changed, 69 insertions(+), 29 deletions(-) diff --git a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForTypeMirror.java b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForTypeMirror.java index d5622056..576fc752 100644 --- a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForTypeMirror.java +++ b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForTypeMirror.java @@ -19,7 +19,10 @@ package de.steamwar.command; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; @@ -64,8 +67,14 @@ public class HandlerForTypeMirror implements Handler.TypeWrapper { @Override public boolean isEnum() { - System.out.println(type); - return false; + if (type.getKind() != TypeKind.DECLARED) { + return false; + } + + DeclaredType declaredType = (DeclaredType) type; + Element element = declaredType.asElement(); + + return element.getKind() == ElementKind.ENUM; } @Override @@ -104,4 +113,9 @@ public class HandlerForTypeMirror implements Handler.TypeWrapper { public String getName() { return type.toString(); } + + @Override + public String getTypeName() { + return type.toString(); + } } diff --git a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java index 492a08a5..7bceb912 100644 --- a/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java +++ b/CommandFramework/CommandFrameworkAnnotationProcessor/src/de/steamwar/command/HandlerForVariableElement.java @@ -24,8 +24,9 @@ import javax.lang.model.element.VariableElement; import javax.lang.model.util.Elements; 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.Arrays; import java.util.Collections; import java.util.List; @@ -74,10 +75,39 @@ public class HandlerForVariableElement implements Handler.ParameterWrapper { for (AnnotationMirror annotationMirror : parameter.getAnnotationMirrors()) { Class clazz = getClass(annotationMirror.getAnnotationType().toString()); if (clazz == null) continue; - annotations.addAll(Arrays.asList(parameter.getAnnotationsByType((Class) clazz))); + annotations.add(parameter.getAnnotation((Class) clazz)); } - annotations.removeIf(annotation -> !annotation.annotationType().isAnnotationPresent(Handler.Implementation.class)); - return annotations; + 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; } private Class getClass(String name) { diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java index 92087536..384fe1e3 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, dataMethodAnnotationTriple.b, dataMethodAnnotationTriple.a); + annotationHandlerMethod.check(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 5529af6e..c04a1d3a 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java @@ -106,12 +106,7 @@ public interface Handler { } interface HandlerMethod extends Handler { - 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 { - } + void check(T annotation, MethodWrapper method, DataCheckable dataCheckable) throws HandlerException; int getRunPriority(); @@ -119,12 +114,7 @@ public interface Handler { } interface HandlerParameter extends Handler { - 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 { - } + void check(T annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException; default boolean needsParentTypeMapper() { return false; @@ -263,6 +253,8 @@ public interface Handler { String getName(); + String getTypeName(); + class ForClass implements TypeWrapper { @Getter private final Class clazz; @@ -321,6 +313,11 @@ public interface Handler { public String getName() { return this.clazz.getName(); } + + @Override + public String getTypeName() { + return this.clazz.getTypeName(); + } } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java index 57122912..cc99fd19 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java @@ -82,7 +82,7 @@ public final class MapperHandler { throw new HandlerException("Mapper annotation cannot be used on first parameter"); } if (!dataCheckable.hasMapper(annotation.value())) { - throw new UnsupportedOperationException("Mapper '" + annotation.value() + "' not found"); + throw new HandlerException("Mapper '" + annotation.value() + "' not found"); } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java index 62160ec4..792a099c 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java @@ -26,8 +26,6 @@ import de.steamwar.command.annotations.Name; import de.steamwar.command.annotations.Supplier; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.util.Arrays; import java.util.Optional; public final class SupplierHandler { @@ -80,21 +78,22 @@ public final class SupplierHandler { } @Override - public void check(Supplier annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + public void check(Supplier annotation, MethodWrapper methodWrapper, ParameterWrapper parameter, int index, DataCheckable dataCheckable) throws HandlerException { if (index == 0) { - throw new UnsupportedOperationException("Supplier annotation cannot be used on the first parameter"); + throw new HandlerException("Supplier annotation cannot be used on the first parameter"); } String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); if (!dataCheckable.hasSupplier(s)) { - throw new UnsupportedOperationException("Supplier '" + annotation.value() + "' not found"); + throw new HandlerException("Supplier '" + annotation.value() + "' not found"); } - boolean hasDisallowedAnnotations = Arrays.stream(parameter.getAnnotations()) + 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)); if (hasDisallowedAnnotations) { - throw new UnsupportedOperationException("Only AllowNull or Name can be used in conjunction with Supplier annotation"); + throw new HandlerException("Only AllowNull or Name can be used in conjunction with Supplier annotation"); } } } diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java index 9d1dc80c..f7ed5b80 100644 --- a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java @@ -77,10 +77,10 @@ public final class ValidatorHandler { } @Override - public void check(Validator annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + 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(); if (!dataCheckable.hasValidator(s)) { - throw new UnsupportedOperationException("Validator '" + annotation.value() + "' not found"); + throw new HandlerException("Validator '" + annotation.value() + "' not found"); } }