diff --git a/src/de/steamwar/command/AbstractGuardChecker.java b/src/de/steamwar/command/AbstractGuardChecker.java deleted file mode 100644 index dd4c555..0000000 --- a/src/de/steamwar/command/AbstractGuardChecker.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 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; - -@Deprecated -@FunctionalInterface -public interface AbstractGuardChecker { - /** - * While guarding the first parameter of the command the parameter s of this method is {@code null} - */ - GuardResult guard(T t, GuardCheckType guardCheckType, String[] previousArguments, String s); -} diff --git a/src/de/steamwar/command/AbstractSWCommand.java b/src/de/steamwar/command/AbstractSWCommand.java index 1de5785..e30ac7b 100644 --- a/src/de/steamwar/command/AbstractSWCommand.java +++ b/src/de/steamwar/command/AbstractSWCommand.java @@ -38,7 +38,6 @@ public abstract class AbstractSWCommand { protected final List> commandHelpList = new ArrayList<>(); private final Map> localTypeMapper = new HashMap<>(); - private final Map> localGuardChecker = new HashMap<>(); private final Map> localValidators = new HashMap<>(); protected AbstractSWCommand(Class clazz, String command) { @@ -77,7 +76,8 @@ public abstract class AbstractSWCommand { errors.forEach(Runnable::run); return; } - commandHelpList.stream().anyMatch(s -> s.invoke((ignore) -> {}, sender, alias, args)); + commandHelpList.stream().anyMatch(s -> s.invoke((ignore) -> { + }, sender, alias, args)); } } catch (CommandNoHelpException e) { // Ignored @@ -126,20 +126,6 @@ public abstract class AbstractSWCommand { SWCommandUtils.getMAPPER_FUNCTIONS().putIfAbsent(anno.value().getTypeName(), typeMapper); } }); - addGuard(Guard.class, method, i -> i == 0, false, AbstractGuardChecker.class, (anno, guardChecker) -> { - if (anno.local()) { - localGuardChecker.putIfAbsent(anno.value(), (AbstractGuardChecker) guardChecker); - } else { - SWCommandUtils.getGUARD_FUNCTIONS().putIfAbsent(anno.value(), guardChecker); - } - }); - addGuard(ClassGuard.class, method, i -> i == 0, false, AbstractGuardChecker.class, (anno, guardChecker) -> { - if (anno.local()) { - localGuardChecker.putIfAbsent(anno.value().getTypeName(), (AbstractGuardChecker) guardChecker); - } else { - 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); @@ -168,7 +154,7 @@ public abstract class AbstractSWCommand { commandSystemWarning(() -> "The method '" + method.toString() + "' is lacking the varArgs parameters of type '" + String.class.getTypeName() + "' as last Argument"); return; } - commandHelpList.add(new SubCommand<>(this, method, anno.value(), new HashMap<>(), new HashMap<>(), localGuardChecker, true, null, anno.noTabComplete())); + commandHelpList.add(new SubCommand<>(this, method, anno.value(), new HashMap<>(), new HashMap<>(), true, null, anno.noTabComplete())); }); add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> { @@ -189,7 +175,7 @@ public abstract class AbstractSWCommand { return; } } - commandList.add(new SubCommand<>(this, method, anno.value(), localTypeMapper, localValidators, localGuardChecker, false, anno.description(), anno.noTabComplete())); + commandList.add(new SubCommand<>(this, method, anno.value(), localTypeMapper, localValidators, false, anno.description(), anno.noTabComplete())); }); } @@ -255,18 +241,6 @@ public abstract class AbstractSWCommand { }); } - @Deprecated - private void addGuard(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, (AbstractGuardChecker) 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) { @@ -327,24 +301,6 @@ public abstract class AbstractSWCommand { boolean global() default false; } - @Deprecated - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.PARAMETER, ElementType.METHOD}) - protected @interface Guard { - String value() default ""; - - boolean local() default false; - } - - @Deprecated - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD}) - protected @interface ClassGuard { - Class value(); - - boolean local() default false; - } - @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER, ElementType.METHOD}) protected @interface Validator { @@ -371,10 +327,12 @@ public abstract class AbstractSWCommand { * and can be set to true if you want to allow int as well as boolean as annotated parameter types. * The value array needs to be at least 2 long for this flag to be considered. * While using an int, the value will represent the index into the value array. - * While using a boolean, the value array must only be 2 long and the value will be {@code false} - * for the first index and {@code true} for the second index. + * While using a boolean, the {@link #falseValues()} defines which indices are + * considered {@code false} or {@code true}. */ boolean allowISE() default false; + + int[] falseValues() default { 0 }; } @Retention(RetentionPolicy.RUNTIME) @@ -384,6 +342,11 @@ public abstract class AbstractSWCommand { * Will pe parsed against the TypeMapper specified by the parameter or annotation. */ String value(); + + /** + * The method name stands for 'onlyUseIfNoneIsGiven'. + */ + boolean onlyUINIG() default false; } @Retention(RetentionPolicy.RUNTIME) @@ -399,4 +362,9 @@ public abstract class AbstractSWCommand { */ boolean allowEAs() default true; } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + protected @interface AllowNull { + } } diff --git a/src/de/steamwar/command/AbstractValidator.java b/src/de/steamwar/command/AbstractValidator.java index 60efd19..aab4876 100644 --- a/src/de/steamwar/command/AbstractValidator.java +++ b/src/de/steamwar/command/AbstractValidator.java @@ -19,6 +19,12 @@ package de.steamwar.command; +import lombok.RequiredArgsConstructor; + +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.function.Predicate; + @FunctionalInterface public interface AbstractValidator { @@ -32,8 +38,57 @@ public interface AbstractValidator { */ boolean validate(K sender, T value, MessageSender messageSender); + default Validator validate(C value, MessageSender messageSender) { + return new Validator<>(value, messageSender); + } + + @RequiredArgsConstructor + class Validator { + private final C value; + private final MessageSender messageSender; + + private boolean valid = true; + + public Validator map(Function mapper) { + return new Validator<>(mapper.apply(value), messageSender).set(valid); + } + + public Validator set(boolean value) { + this.valid = value; + return this; + } + + public Validator and(Predicate predicate) { + valid &= predicate.test(value); + return this; + } + + public Validator or(Predicate predicate) { + valid |= predicate.test(value); + return this; + } + + public Validator errorMessage(String s, Object... args) { + if (!valid) messageSender.send(s, args); + return this; + } + + public boolean result() { + return valid; + } + } + @FunctionalInterface interface MessageSender { void send(String s, Object... args); + + default boolean send(boolean condition, String s, Object... args) { + if (condition) send(s, args); + return condition; + } + + default boolean send(BooleanSupplier condition, String s, Object... args) { + return send(condition.getAsBoolean(), s, args); + } } } diff --git a/src/de/steamwar/command/CommandPart.java b/src/de/steamwar/command/CommandPart.java index d5a5220..80f0048 100644 --- a/src/de/steamwar/command/CommandPart.java +++ b/src/de/steamwar/command/CommandPart.java @@ -23,7 +23,6 @@ import lombok.AllArgsConstructor; import lombok.Setter; import java.lang.reflect.Array; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -42,24 +41,26 @@ class CommandPart { private AbstractSWCommand command; private AbstractTypeMapper typeMapper; private AbstractValidator validator; - private AbstractGuardChecker guardChecker; private Class varArgType; private String optional; - private GuardCheckType guardCheckType; private CommandPart next = null; @Setter private boolean ignoreAsArgument = false; - public CommandPart(AbstractSWCommand command, AbstractTypeMapper typeMapper, AbstractValidator validator, AbstractGuardChecker guardChecker, Class varArgType, String optional, GuardCheckType guardCheckType) { + @Setter + private boolean onlyUseIfNoneIsGiven = false; + + @Setter + private boolean allowNullValues = false; + + public CommandPart(AbstractSWCommand command, AbstractTypeMapper typeMapper, AbstractValidator validator, Class varArgType, String optional) { this.command = command; this.typeMapper = typeMapper; this.validator = validator; - this.guardChecker = guardChecker; this.varArgType = varArgType; this.optional = optional; - this.guardCheckType = guardCheckType; validatePart(); } @@ -72,9 +73,6 @@ class CommandPart { } private void validatePart() { - if (guardCheckType == GuardCheckType.TAB_COMPLETE) { - throw new IllegalArgumentException("Tab complete is not allowed as a guard check type!"); - } if (optional != null && varArgType != null) { throw new IllegalArgumentException("A vararg part can't have an optional part!"); } @@ -92,7 +90,7 @@ class CommandPart { if (varArgType != null) { Object array = Array.newInstance(varArgType, args.length - startIndex); for (int i = startIndex; i < args.length; i++) { - CheckArgumentResult validArgument = checkArgument(null, null, sender, args, i); + CheckArgumentResult validArgument = checkArgument(null, sender, args, i); if (!validArgument.success) { throw new CommandParseException(); } @@ -107,13 +105,19 @@ class CommandPart { return; } - CheckArgumentResult validArgument = checkArgument(errors, null, sender, args, startIndex); + CheckArgumentResult validArgument = checkArgument(errors, sender, args, startIndex); if (!validArgument.success && optional == null) { throw new CommandParseException(); } if (!validArgument.success) { if (!ignoreAsArgument) { - current.add(typeMapper.map(sender, EMPTY_ARRAY, optional)); + if (!onlyUseIfNoneIsGiven) { + current.add(typeMapper.map(sender, EMPTY_ARRAY, optional)); + } else if(startIndex >= args.length) { + current.add(typeMapper.map(sender, EMPTY_ARRAY, optional)); + } else { + throw new CommandParseException(); + } } if (next != null) { next.generateArgumentArray(errors, current, sender, args, startIndex); @@ -128,43 +132,10 @@ class CommandPart { } } - public boolean guardCheck(T sender, String[] args, int startIndex) { - if (varArgType != null) { - for (int i = startIndex; i < args.length; i++) { - GuardResult guardResult = checkGuard(guardCheckType, sender, args, i); - if (guardResult == GuardResult.DENIED) { - throw new CommandNoHelpException(); - } - if (guardResult == GuardResult.DENIED_WITH_HELP) { - return false; - } - } - return true; - } - - GuardResult guardResult = checkGuard(guardCheckType, sender, args, startIndex); - if (guardResult == GuardResult.DENIED) { - if (optional != null && next != null) { - return next.guardCheck(sender, args, startIndex); - } - throw new CommandNoHelpException(); - } - if (guardResult == GuardResult.DENIED_WITH_HELP) { - if (optional != null && next != null) { - return next.guardCheck(sender, args, startIndex); - } - return false; - } - if (next != null) { - return next.guardCheck(sender, args, startIndex + 1); - } - return true; - } - public void generateTabComplete(List current, T sender, String[] args, int startIndex) { if (varArgType != null) { for (int i = startIndex; i < args.length - 1; i++) { - CheckArgumentResult validArgument = checkArgument((ignore) -> {}, GuardCheckType.TAB_COMPLETE, sender, args, i); + CheckArgumentResult validArgument = checkArgument((ignore) -> {}, sender, args, i); if (!validArgument.success) { return; } @@ -177,7 +148,7 @@ class CommandPart { } if (args.length - 1 > startIndex) { - CheckArgumentResult checkArgumentResult = checkArgument((ignore) -> {}, GuardCheckType.TAB_COMPLETE, sender, args, startIndex); + CheckArgumentResult checkArgumentResult = checkArgument((ignore) -> {}, sender, args, startIndex); if (checkArgumentResult.success && next != null) { next.generateTabComplete(current, sender, args, startIndex + 1); return; @@ -203,7 +174,7 @@ class CommandPart { }); } - private CheckArgumentResult checkArgument(Consumer errors, GuardCheckType guardCheckType, T sender, String[] args, int index) { + private CheckArgumentResult checkArgument(Consumer errors, T sender, String[] args, int index) { try { Object value = typeMapper.map(sender, Arrays.copyOf(args, index), args[index]); if (validator != null && errors != null) { @@ -214,31 +185,10 @@ class CommandPart { })) { return new CheckArgumentResult(false, null); } - return new CheckArgumentResult(value != null, value); - } - if (value == null) { - return new CheckArgumentResult(false, null); - } - - GuardResult guardResult = checkGuard(guardCheckType, sender, args, index); - switch (guardResult) { - case ALLOWED: - return new CheckArgumentResult(true, value); - case DENIED: - throw new CommandNoHelpException(); - case DENIED_WITH_HELP: - default: - return new CheckArgumentResult(false, null); } + return new CheckArgumentResult(allowNullValues || value != null, value); } catch (Exception e) { return new CheckArgumentResult(false, null); } } - - private GuardResult checkGuard(GuardCheckType guardCheckType, T sender, String[] args, int index) { - if (guardChecker != null && guardCheckType != null) { - return guardChecker.guard(sender, guardCheckType, Arrays.copyOf(args, index), args[index]); - } - return GuardResult.ALLOWED; - } } diff --git a/src/de/steamwar/command/GuardCheckType.java b/src/de/steamwar/command/GuardCheckType.java deleted file mode 100644 index d2e6ed0..0000000 --- a/src/de/steamwar/command/GuardCheckType.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 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; - -@Deprecated -public enum GuardCheckType { - COMMAND, - HELP_COMMAND, - TAB_COMPLETE -} diff --git a/src/de/steamwar/command/GuardResult.java b/src/de/steamwar/command/GuardResult.java deleted file mode 100644 index 3e6aafc..0000000 --- a/src/de/steamwar/command/GuardResult.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 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; - -@Deprecated -public enum GuardResult { - ALLOWED, - DENIED_WITH_HELP, - DENIED -} diff --git a/src/de/steamwar/command/SWCommandUtils.java b/src/de/steamwar/command/SWCommandUtils.java index 9620631..f6aa8f3 100644 --- a/src/de/steamwar/command/SWCommandUtils.java +++ b/src/de/steamwar/command/SWCommandUtils.java @@ -37,10 +37,6 @@ public class SWCommandUtils { @Getter private final Map> MAPPER_FUNCTIONS = new HashMap<>(); - @Getter - @Deprecated - private final Map> GUARD_FUNCTIONS = new HashMap<>(); - @Getter private final Map> VALIDATOR_FUNCTIONS = new HashMap<>(); @@ -78,11 +74,11 @@ public class SWCommandUtils { MAPPER_FUNCTIONS.put(alternativeClazz.getTypeName(), mapper); } - static CommandPart generateCommandPart(AbstractSWCommand command, boolean help, String[] subCommand, Parameter[] parameters, Map> localTypeMapper, Map> localValidator, Map> localGuardChecker) { + static CommandPart generateCommandPart(AbstractSWCommand command, boolean help, String[] subCommand, Parameter[] parameters, Map> localTypeMapper, Map> localValidator) { CommandPart first = null; CommandPart current = null; for (String s : subCommand) { - CommandPart commandPart = new CommandPart(command, createMapper(s), null, null, null, null, help ? GuardCheckType.HELP_COMMAND : GuardCheckType.COMMAND); + CommandPart commandPart = new CommandPart(command, createMapper(s), null, null, null); commandPart.setIgnoreAsArgument(true); if (current != null) { current.setNext(commandPart); @@ -96,11 +92,13 @@ public class SWCommandUtils { Parameter parameter = parameters[i]; AbstractTypeMapper typeMapper = getTypeMapper(parameter, localTypeMapper); AbstractValidator validator = (AbstractValidator) getValidator(parameter, localValidator); - AbstractGuardChecker guardChecker = getGuardChecker(parameter, localGuardChecker); Class varArgType = parameter.isVarArgs() ? parameter.getType().getComponentType() : null; AbstractSWCommand.OptionalValue optionalValue = parameter.getAnnotation(AbstractSWCommand.OptionalValue.class); + AbstractSWCommand.AllowNull allowNull = parameter.getAnnotation(AbstractSWCommand.AllowNull.class); - CommandPart commandPart = new CommandPart<>(command, typeMapper, validator, guardChecker, varArgType, optionalValue != null ? optionalValue.value() : null, help ? GuardCheckType.HELP_COMMAND : GuardCheckType.COMMAND); + CommandPart commandPart = new CommandPart<>(command, typeMapper, validator, varArgType, optionalValue != null ? optionalValue.value() : null); + commandPart.setOnlyUseIfNoneIsGiven(optionalValue != null && optionalValue.onlyUINIG()); + commandPart.setAllowNullValues(allowNull != null); if (current != null) { current.setNext(commandPart); } @@ -136,25 +134,20 @@ public class SWCommandUtils { return createMapper(staticValue.value()); } if (staticValue.allowISE()) { - if ((parameter.getType() == boolean.class || parameter.getType() == Boolean.class) && staticValue.value().length == 2) { + if ((parameter.getType() == boolean.class || parameter.getType() == Boolean.class)) { List tabCompletes = new ArrayList<>(Arrays.asList(staticValue.value())); + Set falseValues = new HashSet<>(); + for (int i : staticValue.falseValues()) falseValues.add(i); return createMapper(s -> { int index = tabCompletes.indexOf(s); - return index == -1 ? null : index != 0; + return index == -1 ? null : !falseValues.contains(index); }, (commandSender, s) -> tabCompletes); } - if ((parameter.getType() == int.class || parameter.getType() == Integer.class) && staticValue.value().length >= 2) { + if ((parameter.getType() == int.class || parameter.getType() == Integer.class || parameter.getType() == long.class || parameter.getType() == Long.class) && staticValue.value().length >= 2) { List tabCompletes = new ArrayList<>(Arrays.asList(staticValue.value())); return createMapper(s -> { - int index = tabCompletes.indexOf(s); - return index == -1 ? null : index; - }, (commandSender, s) -> tabCompletes); - } - if ((parameter.getType() == long.class || parameter.getType() == Long.class) && staticValue.value().length >= 2) { - List tabCompletes = new ArrayList<>(Arrays.asList(staticValue.value())); - return createMapper(s -> { - long index = tabCompletes.indexOf(s); - return index == -1 ? null : index; + Number index = tabCompletes.indexOf(s); + return index.longValue() == -1 ? null : index; }, (commandSender, s) -> tabCompletes); } } @@ -208,40 +201,6 @@ public class SWCommandUtils { return validator; } - @Deprecated - public static AbstractGuardChecker getGuardChecker(Parameter parameter, Map> localGuardChecker) { - Class clazz = parameter.getType(); - if (parameter.isVarArgs()) { - clazz = clazz.getComponentType(); - } - - AbstractSWCommand.ClassGuard classGuard = parameter.getAnnotation(AbstractSWCommand.ClassGuard.class); - if (classGuard != null) { - if (classGuard.value() != null) { - return getGuardChecker(classGuard.value().getTypeName(), localGuardChecker); - } - return getGuardChecker(clazz.getTypeName(), localGuardChecker); - } - - AbstractSWCommand.Guard guard = parameter.getAnnotation(AbstractSWCommand.Guard.class); - if (guard != null) { - if (guard.value() != null && !guard.value().isEmpty()) { - return getGuardChecker(guard.value(), localGuardChecker); - } - return getGuardChecker(clazz.getTypeName(), localGuardChecker); - } - return null; - } - - @Deprecated - private static AbstractGuardChecker getGuardChecker(String s, Map> localGuardChecker) { - AbstractGuardChecker guardChecker = localGuardChecker.getOrDefault(s, (AbstractGuardChecker) GUARD_FUNCTIONS.getOrDefault(s, null)); - if (guardChecker == null) { - throw new IllegalArgumentException("No guard found for " + s); - } - return guardChecker; - } - public static void addMapper(Class clazz, AbstractTypeMapper mapper) { addMapper(clazz.getTypeName(), mapper); } @@ -258,16 +217,6 @@ public class SWCommandUtils { VALIDATOR_FUNCTIONS.putIfAbsent(name, validator); } - @Deprecated - public static void addGuard(Class clazz, AbstractGuardChecker guardChecker) { - addGuard(clazz.getTypeName(), guardChecker); - } - - @Deprecated - public static void addGuard(String name, AbstractGuardChecker guardChecker) { - GUARD_FUNCTIONS.putIfAbsent(name, guardChecker); - } - public static , K> T createMapper(String... values) { List strings = Arrays.stream(values).map(String::toLowerCase).collect(Collectors.toList()); List tabCompletes = Arrays.asList(values); diff --git a/src/de/steamwar/command/SWTypeMapperCreator.java b/src/de/steamwar/command/SWTypeMapperCreator.java index 33c5dcb..f21b0a8 100644 --- a/src/de/steamwar/command/SWTypeMapperCreator.java +++ b/src/de/steamwar/command/SWTypeMapperCreator.java @@ -19,10 +19,10 @@ package de.steamwar.command; -import java.util.List; +import java.util.Collection; import java.util.function.BiFunction; import java.util.function.Function; public interface SWTypeMapperCreator, K, V> { - T createTypeMapper(Function mapper, BiFunction> tabCompleter); + T createTypeMapper(Function mapper, BiFunction> tabCompleter); } diff --git a/src/de/steamwar/command/SubCommand.java b/src/de/steamwar/command/SubCommand.java index d3a266c..9a497e5 100644 --- a/src/de/steamwar/command/SubCommand.java +++ b/src/de/steamwar/command/SubCommand.java @@ -38,13 +38,12 @@ public class SubCommand { private Predicate senderPredicate; private Function senderFunction; AbstractValidator validator; - AbstractGuardChecker guardChecker; boolean noTabComplete; int comparableValue; private CommandPart commandPart; - SubCommand(AbstractSWCommand abstractSWCommand, Method method, String[] subCommand, Map> localTypeMapper, Map> localValidator, Map> localGuardChecker, boolean help, String[] description, boolean noTabComplete) { + SubCommand(AbstractSWCommand abstractSWCommand, Method method, String[] subCommand, Map> localTypeMapper, Map> localValidator, boolean help, String[] description, boolean noTabComplete) { this.abstractSWCommand = abstractSWCommand; this.method = method; this.subCommand = subCommand; @@ -55,9 +54,8 @@ public class SubCommand { comparableValue = parameters[parameters.length - 1].isVarArgs() ? Integer.MAX_VALUE : -parameters.length; validator = (AbstractValidator) SWCommandUtils.getValidator(parameters[0], localValidator); - guardChecker = SWCommandUtils.getGuardChecker(parameters[0], localGuardChecker); - commandPart = SWCommandUtils.generateCommandPart(abstractSWCommand, help, subCommand, parameters, localTypeMapper, localValidator, localGuardChecker); + commandPart = SWCommandUtils.generateCommandPart(abstractSWCommand, help, subCommand, parameters, localTypeMapper, localValidator); senderPredicate = t -> parameters[0].getType().isAssignableFrom(t.getClass()); senderFunction = t -> parameters[0].getType().cast(t); @@ -77,18 +75,7 @@ public class SubCommand { if (!validator.validate(sender, sender, (s, objectArgs) -> { abstractSWCommand.sendMessage(sender, s, objectArgs); })) { - throw new CommandNoHelpException(); - } - } else if (guardChecker != null) { - GuardResult guardResult = guardChecker.guard(sender, GuardCheckType.COMMAND, new String[0], null); - switch (guardResult) { - case ALLOWED: - break; - case DENIED: - throw new CommandNoHelpException(); - case DENIED_WITH_HELP: - default: - return true; + return false; } } method.setAccessible(true); @@ -100,21 +87,9 @@ public class SubCommand { if (!validator.validate(sender, sender, (s, objectArgs) -> { abstractSWCommand.sendMessage(sender, s, objectArgs); })) { - throw new CommandNoHelpException(); - } - } else if (guardChecker != null) { - GuardResult guardResult = guardChecker.guard(sender, GuardCheckType.COMMAND, new String[0], null); - switch (guardResult) { - case ALLOWED: - break; - case DENIED: - throw new CommandNoHelpException(); - case DENIED_WITH_HELP: - default: - return true; + return false; } } - commandPart.guardCheck(sender, args, 0); objects.add(0, senderFunction.apply(sender)); method.setAccessible(true); method.invoke(abstractSWCommand, objects.toArray()); @@ -138,8 +113,6 @@ public class SubCommand { })) { return null; } - } else if (guardChecker != null && guardChecker.guard(sender, GuardCheckType.TAB_COMPLETE, new String[0], null) != GuardResult.ALLOWED) { - return null; } if (commandPart == null) { return null; diff --git a/src/de/steamwar/command/TabCompletionCache.java b/src/de/steamwar/command/TabCompletionCache.java index 5cf555c..6f2d0ff 100644 --- a/src/de/steamwar/command/TabCompletionCache.java +++ b/src/de/steamwar/command/TabCompletionCache.java @@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.UtilityClass; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @UtilityClass @@ -36,12 +37,16 @@ public class TabCompletionCache { void add(AbstractTypeMapper typeMapper, AbstractSWCommand.Cached cached) { if (cached != null) { - TabCompletionCache.cached.add(typeMapper); - if (cached.global()) TabCompletionCache.global.add(typeMapper); - TabCompletionCache.cacheDuration.put(typeMapper, cached.timeUnit().toMillis(cached.cacheDuration())); + add(typeMapper, cached.global(), cached.cacheDuration(), cached.timeUnit()); } } + public void add(AbstractTypeMapper typeMapper, boolean global, long cacheDuration, TimeUnit timeUnit) { + TabCompletionCache.cached.add(typeMapper); + if (global) TabCompletionCache.global.add(typeMapper); + TabCompletionCache.cacheDuration.put(typeMapper, timeUnit.toMillis(cacheDuration)); + } + @EqualsAndHashCode @AllArgsConstructor private static class Key { diff --git a/testsrc/de/steamwar/command/GuardCommand.java b/testsrc/de/steamwar/command/GuardCommand.java deleted file mode 100644 index 7ee1854..0000000 --- a/testsrc/de/steamwar/command/GuardCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 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 de.steamwar.command.dto.ExecutionIdentifier; -import de.steamwar.command.dto.TestGuardChecker; -import de.steamwar.command.dto.TestSWCommand; - -public class GuardCommand extends TestSWCommand { - - public GuardCommand() { - super("typemapper"); - } - - @Register - public void test(@Guard String sender) { - throw new ExecutionIdentifier("RunTypeMapper"); - } - - @ClassGuard(value = String.class, local = true) - public AbstractGuardChecker getGuardChecker() { - return (TestGuardChecker) (s, guardCheckType, previousArguments, s2) -> { - throw new ExecutionIdentifier("GuardChecker " + guardCheckType); - }; - } -} diff --git a/testsrc/de/steamwar/command/NullMapperCommand.java b/testsrc/de/steamwar/command/NullMapperCommand.java new file mode 100644 index 0000000..e47eab7 --- /dev/null +++ b/testsrc/de/steamwar/command/NullMapperCommand.java @@ -0,0 +1,59 @@ +/* + * 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; + +import de.steamwar.command.dto.ExecutionIdentifier; +import de.steamwar.command.dto.TestSWCommand; +import de.steamwar.command.dto.TestTypeMapper; + +import java.util.Collection; + +public class NullMapperCommand extends TestSWCommand { + + public NullMapperCommand() { + super("nullmapper"); + } + + @Register + public void test(String sender, @AllowNull String arg) { + if (arg == null) { + throw new ExecutionIdentifier("null"); + } + throw new ExecutionIdentifier("notnull"); + } + + @ClassMapper(value = String.class, local = true) + public TestTypeMapper typeMapper() { + return new TestTypeMapper() { + @Override + public String map(String sender, String[] previousArguments, String s) { + if (s.equals("Hello World")) { + return null; + } + return s; + } + + @Override + public Collection tabCompletes(String sender, String[] previousArguments, String s) { + return null; + } + }; + } +} diff --git a/testsrc/de/steamwar/command/GuardCommandTest.java b/testsrc/de/steamwar/command/NullMapperCommandTest.java similarity index 64% rename from testsrc/de/steamwar/command/GuardCommandTest.java rename to testsrc/de/steamwar/command/NullMapperCommandTest.java index 51eae0e..1e19d13 100644 --- a/testsrc/de/steamwar/command/GuardCommandTest.java +++ b/testsrc/de/steamwar/command/NullMapperCommandTest.java @@ -1,7 +1,7 @@ /* * This file is a part of the SteamWar software. * - * Copyright (C) 2020 SteamWar.de-Serverteam + * 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 @@ -24,29 +24,29 @@ import org.junit.Test; import static de.steamwar.AssertionUtils.assertCMDFramework; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; -public class GuardCommandTest { +public class NullMapperCommandTest { @Test - public void test() { - GuardCommand cmd = new GuardCommand(); + public void testNull() { + NullMapperCommand command = new NullMapperCommand(); try { - cmd.execute("test", "", new String[0]); + command.execute("test", "", new String[] {"Hello World"}); + assertThat(true, is(false)); } catch (Exception e) { - assertThat(e.getMessage(), is("GuardChecker COMMAND")); + assertCMDFramework(e, ExecutionIdentifier.class, "null"); } } @Test - public void testTabComplete() { - GuardCommand cmd = new GuardCommand(); + public void testNonNull() { + NullMapperCommand command = new NullMapperCommand(); try { - cmd.tabComplete("test", "", new String[]{""}); + command.execute("test", "", new String[] {"Hello"}); + assertThat(true, is(false)); } catch (Exception e) { - assertThat(e, is(instanceOf(ExecutionIdentifier.class))); - assertThat(e.getMessage(), is("GuardChecker TAB_COMPLETE")); + assertCMDFramework(e, ExecutionIdentifier.class, "notnull"); } } } diff --git a/testsrc/de/steamwar/command/StaticValueCommand.java b/testsrc/de/steamwar/command/StaticValueCommand.java new file mode 100644 index 0000000..0eca60d --- /dev/null +++ b/testsrc/de/steamwar/command/StaticValueCommand.java @@ -0,0 +1,55 @@ +/* + * 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; + +import de.steamwar.command.dto.ExecutionIdentifier; +import de.steamwar.command.dto.TestSWCommand; + +public class StaticValueCommand extends TestSWCommand { + + public StaticValueCommand() { + super("staticvalue"); + } + + @Register + public void defaultStaticValue(String s, @StaticValue({"hello", "world"}) String staticValue) { + throw new ExecutionIdentifier("RunStaticValue with " + staticValue); + } + + @Register + public void booleanStaticValue(String s, @StaticValue(value = {"-a", "-b", "-c"}, allowISE = true) boolean staticValue) { + throw new ExecutionIdentifier("RunStaticValue with " + staticValue); + } + + @Register + public void booleanStaticValueOtherFalseValue(String s, @StaticValue(value = {"-d", "-e", "-f"}, allowISE = true, falseValues = { 1 }) boolean staticValue) { + throw new ExecutionIdentifier("RunStaticValue with " + staticValue); + } + + @Register + public void intStaticValue(String s, @StaticValue(value = {"-g", "-h", "-i"}, allowISE = true) int staticValue) { + throw new ExecutionIdentifier("RunStaticValue with int " + staticValue); + } + + @Register + public void longStaticValue(String s, @StaticValue(value = {"-j", "-k", "-l"}, allowISE = true) long staticValue) { + throw new ExecutionIdentifier("RunStaticValue with long " + staticValue); + } +} diff --git a/testsrc/de/steamwar/command/StaticValueCommandTest.java b/testsrc/de/steamwar/command/StaticValueCommandTest.java new file mode 100644 index 0000000..665250a --- /dev/null +++ b/testsrc/de/steamwar/command/StaticValueCommandTest.java @@ -0,0 +1,133 @@ +/* + * 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; + +import de.steamwar.command.dto.ExecutionIdentifier; +import org.junit.Test; + +import java.util.List; + +import static de.steamwar.AssertionUtils.assertCMDFramework; +import static de.steamwar.AssertionUtils.assertTabCompletes; + +public class StaticValueCommandTest { + + @Test + public void tabCompletionTest() { + StaticValueCommand cmd = new StaticValueCommand(); + List strings = cmd.tabComplete("", "", new String[]{""}); + assertTabCompletes(strings, "hello", "world", "-a", "-b", "-c", "-d", "-e", "-f", "-g", "-h", "-i", "-j", "-k", "-l"); + } + + @Test + public void defaultTest() { + StaticValueCommand cmd = new StaticValueCommand(); + try { + cmd.execute("", "", new String[] {"hello"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with hello"); + } + try { + cmd.execute("", "", new String[] {"world"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with world"); + } + } + + @Test + public void booleanTest() { + StaticValueCommand cmd = new StaticValueCommand(); + try { + cmd.execute("", "", new String[] {"-a"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with false"); + } + try { + cmd.execute("", "", new String[] {"-b"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with true"); + } + try { + cmd.execute("", "", new String[] {"-c"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with true"); + } + } + + @Test + public void booleanOtherFalseTest() { + StaticValueCommand cmd = new StaticValueCommand(); + try { + cmd.execute("", "", new String[] {"-d"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with true"); + } + try { + cmd.execute("", "", new String[] {"-e"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with false"); + } + try { + cmd.execute("", "", new String[] {"-f"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with true"); + } + } + + @Test + public void intTest() { + StaticValueCommand cmd = new StaticValueCommand(); + try { + cmd.execute("", "", new String[] {"-g"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with int 0"); + } + try { + cmd.execute("", "", new String[] {"-h"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with int 1"); + } + try { + cmd.execute("", "", new String[] {"-i"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with int 2"); + } + } + + @Test + public void longTest() { + StaticValueCommand cmd = new StaticValueCommand(); + try { + cmd.execute("", "", new String[] {"-j"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with long 0"); + } + try { + cmd.execute("", "", new String[] {"-k"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with long 1"); + } + try { + cmd.execute("", "", new String[] {"-l"}); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunStaticValue with long 2"); + } + } +} \ No newline at end of file diff --git a/testsrc/de/steamwar/command/ValidatorCommand.java b/testsrc/de/steamwar/command/ValidatorCommand.java index ea95a5e..b0e4a36 100644 --- a/testsrc/de/steamwar/command/ValidatorCommand.java +++ b/testsrc/de/steamwar/command/ValidatorCommand.java @@ -43,11 +43,13 @@ public class ValidatorCommand extends TestSWCommand { @Register public void onError(String sender, @ErrorMessage("Hello World") int error) { + System.out.println("onError: " + sender + " " + error); throw new ExecutionIdentifier("RunOnError"); } @Register public void onError(String sender, double error) { + System.out.println("onError: " + sender + " " + error); throw new ExecutionIdentifier("RunOnErrorDouble"); } diff --git a/testsrc/de/steamwar/command/dto/TestGuardChecker.java b/testsrc/de/steamwar/command/dto/TestGuardChecker.java deleted file mode 100644 index b85fa17..0000000 --- a/testsrc/de/steamwar/command/dto/TestGuardChecker.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 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.dto; - -import de.steamwar.command.AbstractGuardChecker; - -public interface TestGuardChecker extends AbstractGuardChecker { -}