From b8d659d1c6d9d51475d37ba1ba402d1670a453c1 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Thu, 16 Jun 2022 13:18:14 +0200 Subject: [PATCH] Add AbstractValidator Deprecate AbstractGuardChecker --- .../command/AbstractGuardChecker.java | 1 + .../steamwar/command/AbstractSWCommand.java | 53 +++++++++++++++++++ .../steamwar/command/AbstractTypeMapper.java | 2 +- .../steamwar/command/AbstractValidator.java | 26 +++++++++ src/de/steamwar/command/GuardCheckType.java | 1 + src/de/steamwar/command/GuardResult.java | 1 + src/de/steamwar/command/SWCommandUtils.java | 10 +++- 7 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/de/steamwar/command/AbstractValidator.java diff --git a/src/de/steamwar/command/AbstractGuardChecker.java b/src/de/steamwar/command/AbstractGuardChecker.java index f5f2597..dd4c555 100644 --- a/src/de/steamwar/command/AbstractGuardChecker.java +++ b/src/de/steamwar/command/AbstractGuardChecker.java @@ -19,6 +19,7 @@ package de.steamwar.command; +@Deprecated @FunctionalInterface public interface AbstractGuardChecker { /** diff --git a/src/de/steamwar/command/AbstractSWCommand.java b/src/de/steamwar/command/AbstractSWCommand.java index d654df7..2500bd1 100644 --- a/src/de/steamwar/command/AbstractSWCommand.java +++ b/src/de/steamwar/command/AbstractSWCommand.java @@ -38,6 +38,7 @@ public abstract class AbstractSWCommand { private final Map> localTypeMapper = new HashMap<>(); private final Map> localGuardChecker = new HashMap<>(); + private final Map> localValidators = new HashMap<>(); protected AbstractSWCommand(Class clazz, String command) { this(clazz, command, new String[0]); @@ -127,6 +128,20 @@ public abstract class AbstractSWCommand { SWCommandUtils.getGUARD_FUNCTIONS().putIfAbsent(anno.value().getTypeName(), guardChecker); } }); + addValidator(Validator.class, method, i -> i == 0, false, AbstractValidator.class, (anno, validator) -> { + if (anno.local()) { + localValidators.putIfAbsent(anno.value(), (AbstractValidator) validator); + } else { + SWCommandUtils.getVALIDATOR_FUNCTIONS().putIfAbsent(anno.value(), validator); + } + }); + addValidator(ClassValidator.class, method, i -> i == 0, false, AbstractValidator.class, (anno, validator) -> { + if (anno.local()) { + localValidators.putIfAbsent(anno.value().getTypeName(), (AbstractValidator) validator); + } else { + SWCommandUtils.getVALIDATOR_FUNCTIONS().putIfAbsent(anno.value().getTypeName(), validator); + } + }); } for (Method method : methods) { add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> { @@ -228,6 +243,17 @@ public abstract class AbstractSWCommand { }); } + private void addValidator(Class annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class returnType, BiConsumer> consumer) { + add(annotation, method, parameterTester, firstParameter, returnType, (anno, parameters) -> { + try { + method.setAccessible(true); + consumer.accept(anno, (AbstractValidator) method.invoke(this)); + } catch (Exception e) { + throw new SecurityException(e.getMessage(), e); + } + }); + } + // TODO: Implement this when Message System is ready /* public void addDefaultHelpMessage(String message) { @@ -280,6 +306,7 @@ public abstract class AbstractSWCommand { boolean local() default false; } + @Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER, ElementType.METHOD}) protected @interface Guard { @@ -288,6 +315,7 @@ public abstract class AbstractSWCommand { boolean local() default false; } + @Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) protected @interface ClassGuard { @@ -296,6 +324,22 @@ public abstract class AbstractSWCommand { boolean local() default false; } + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER, ElementType.METHOD}) + protected @interface Validator { + String value() default ""; + + boolean local() default false; + } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD}) + protected @interface ClassValidator { + Class value(); + + boolean local() default false; + } + @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) protected @interface StaticValue { @@ -320,4 +364,13 @@ public abstract class AbstractSWCommand { */ String value(); } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + protected @interface ErrorMessage { + /** + * Error message to be displayed when the parameter is invalid. + */ + String value(); + } } diff --git a/src/de/steamwar/command/AbstractTypeMapper.java b/src/de/steamwar/command/AbstractTypeMapper.java index 744b726..a9174dc 100644 --- a/src/de/steamwar/command/AbstractTypeMapper.java +++ b/src/de/steamwar/command/AbstractTypeMapper.java @@ -21,7 +21,7 @@ package de.steamwar.command; import java.util.Collection; -public interface AbstractTypeMapper { +public interface AbstractTypeMapper extends AbstractValidator { /** * The CommandSender can be null! */ diff --git a/src/de/steamwar/command/AbstractValidator.java b/src/de/steamwar/command/AbstractValidator.java new file mode 100644 index 0000000..c4df8ed --- /dev/null +++ b/src/de/steamwar/command/AbstractValidator.java @@ -0,0 +1,26 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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; + +public interface AbstractValidator { + default boolean validate(K sender, T value) { + return true; + } +} diff --git a/src/de/steamwar/command/GuardCheckType.java b/src/de/steamwar/command/GuardCheckType.java index 0f023b8..d2e6ed0 100644 --- a/src/de/steamwar/command/GuardCheckType.java +++ b/src/de/steamwar/command/GuardCheckType.java @@ -19,6 +19,7 @@ package de.steamwar.command; +@Deprecated public enum GuardCheckType { COMMAND, HELP_COMMAND, diff --git a/src/de/steamwar/command/GuardResult.java b/src/de/steamwar/command/GuardResult.java index 9ffbf77..3e6aafc 100644 --- a/src/de/steamwar/command/GuardResult.java +++ b/src/de/steamwar/command/GuardResult.java @@ -19,6 +19,7 @@ package de.steamwar.command; +@Deprecated public enum GuardResult { ALLOWED, DENIED_WITH_HELP, diff --git a/src/de/steamwar/command/SWCommandUtils.java b/src/de/steamwar/command/SWCommandUtils.java index aaf0c7a..4e57876 100644 --- a/src/de/steamwar/command/SWCommandUtils.java +++ b/src/de/steamwar/command/SWCommandUtils.java @@ -28,6 +28,7 @@ import java.lang.reflect.Parameter; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.stream.Collectors; @UtilityClass public class SWCommandUtils { @@ -36,8 +37,12 @@ public class SWCommandUtils { private final Map> MAPPER_FUNCTIONS = new HashMap<>(); @Getter + @Deprecated private final Map> GUARD_FUNCTIONS = new HashMap<>(); + @Getter + private final Map> VALIDATOR_FUNCTIONS = new HashMap<>(); + private SWTypeMapperCreator swTypeMapperCreator = (mapper, tabCompleter) -> new AbstractTypeMapper() { @Override public Object map(Object sender, String[] previousArguments, String s) { @@ -209,8 +214,9 @@ public class SWCommandUtils { } public static , K> T createMapper(String... values) { - List strings = Arrays.asList(values); - return createMapper((s) -> strings.contains(s) ? s : null, s -> strings); + List strings = Arrays.stream(values).map(String::toLowerCase).collect(Collectors.toList()); + List tabCompletes = Arrays.asList(values); + return createMapper(s -> strings.contains(s.toLowerCase()) ? s : null, s -> tabCompletes); } public static , K, V> T createMapper(Function mapper, Function> tabCompleter) {