From 2e45e375b174788d6b9f4a07e95ae25bd75f9c11 Mon Sep 17 00:00:00 2001 From: delvh Date: Fri, 17 Jul 2020 23:27:54 +0200 Subject: [PATCH] Revised SystemCommand mechanism and implemented theoretical execution --- .../data/commands/NoArgSystemCommand.java | 26 --- .../data/commands/StringArgSystemCommand.java | 26 --- .../client/data/commands/SystemCommand.java | 52 +++--- .../data/commands/SystemCommandsMap.java | 159 ++++++++++++++++++ 4 files changed, 192 insertions(+), 71 deletions(-) delete mode 100644 client/src/main/java/envoy/client/data/commands/NoArgSystemCommand.java delete mode 100644 client/src/main/java/envoy/client/data/commands/StringArgSystemCommand.java create mode 100644 client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java diff --git a/client/src/main/java/envoy/client/data/commands/NoArgSystemCommand.java b/client/src/main/java/envoy/client/data/commands/NoArgSystemCommand.java deleted file mode 100644 index 4968c58..0000000 --- a/client/src/main/java/envoy/client/data/commands/NoArgSystemCommand.java +++ /dev/null @@ -1,26 +0,0 @@ -package envoy.client.data.commands; - -import java.util.function.Function; - -/** - * This class is the base class for all {@link SystemCommand}s that do not need - * another argument to parse their function. - *

- * Project: envoy-client
- * File: NoArgSystemCommand.java
- * Created: 16.07.2020
- * - * @author Leon Hofmeister - * @since Envoy Client v0.1-beta - */ -public class NoArgSystemCommand extends SystemCommand { - - /** - * Constructs a new {@code NoArgSystemCommand} that takes no arguments. - * - * @param command the string that must be inputted to execute the given action - * @param action the action that should be performed - * @since Envoy Client v0.1-beta - */ - public NoArgSystemCommand(String command, Function action) { super(command, action); } -} diff --git a/client/src/main/java/envoy/client/data/commands/StringArgSystemCommand.java b/client/src/main/java/envoy/client/data/commands/StringArgSystemCommand.java deleted file mode 100644 index 5349724..0000000 --- a/client/src/main/java/envoy/client/data/commands/StringArgSystemCommand.java +++ /dev/null @@ -1,26 +0,0 @@ -package envoy.client.data.commands; - -import java.util.function.Function; - -/** - * This class is the base class for all {@link SystemCommand}s that need a - * String to parse their function. - *

- * Project: envoy-client
- * File: StringArgSystemCommand.java
- * Created: 16.07.2020
- * - * @author Leon Hofmeister - * @since Envoy Client v0.1-beta - */ -public class StringArgSystemCommand extends SystemCommand { - - /** - * Constructs a new {@code NoArgSystemCommand} that takes a String argument. - * - * @param command the string that must be inputted to execute the given action - * @param action the action that should be performed - * @since Envoy Client v0.1-beta - */ - public StringArgSystemCommand(String command, Function action) { super(command, action); } -} diff --git a/client/src/main/java/envoy/client/data/commands/SystemCommand.java b/client/src/main/java/envoy/client/data/commands/SystemCommand.java index 793de46..7bca617 100644 --- a/client/src/main/java/envoy/client/data/commands/SystemCommand.java +++ b/client/src/main/java/envoy/client/data/commands/SystemCommand.java @@ -4,48 +4,62 @@ import java.util.function.Function; /** * This class is the base class of all {@code SystemCommands} and contains an - * action and a command that needs to be inputted to execute the given action. + * action and a number of arguments that should be used as input for this + * function. * No {@code SystemCommand} can return anything. + * Every {@code SystemCommand} must have as argument type {@code String[]} so + * that the words following the indicator String can be used as input of the + * function. This approach has one limitation:
+ * Order matters! Changing the order of arguments will likely result in + * unexpected behavior. *

* Project: envoy-client
* File: SystemCommand.java
* Created: 16.07.2020
* * @author Leon Hofmeister - * @param the type of argument needed * @since Envoy Client v0.1-beta */ -public abstract class SystemCommand { +public final class SystemCommand { /** - * This variable stores the command that should be inputted to execute the given - * action + * This variable stores the amount of arguments that need to be parsed for the + * underlying function. */ - protected final String command; + protected final int numberOfArguments; - protected final Function action; + /** + * This Function takes a {@code String[]} as argument because automatically + * {@code SystemCommand#numberOfArguments} words following the necessary command + * will be put into this array. + * + * @see String#split(String) + */ + protected final Function action; /** * Constructs a new {@code NoArgSystemCommand} that takes no arguments. * - * @param command the string that must be inputted to execute the given action - * @param action the action that should be performed + * @param action the action that should be performed + * @param numberOfArguments the amount of arguments that need to be parsed for + * the underlying function * @since Envoy Client v0.1-beta */ - public SystemCommand(String command, Function action) { - this.command = command; - this.action = action; + public SystemCommand(Function action, int numberOfArguments) { + this.numberOfArguments = numberOfArguments; + this.action = action; } - /** - * @return the command that must be inputted to execute the given action - * @since Envoy Client v0.1-beta - */ - public String getCommand() { return command; } - /** * @return the action that should be performed * @since Envoy Client v0.1-beta */ - public Function getAction() { return action; } + public Function getAction() { return action; } + + /** + * @return the amount of arguments that need to be parsed for + * the underlying function + * @since Envoy Client v0.1-beta + */ + public int getNumberOfArguments() { return numberOfArguments; } } diff --git a/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java b/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java new file mode 100644 index 0000000..abb1295 --- /dev/null +++ b/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java @@ -0,0 +1,159 @@ +package envoy.client.data.commands; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Optional; +import java.util.function.Function; +import java.util.logging.Level; + +import envoy.util.EnvoyLog; + +/** + * This class stores all {@link SystemCommand}s used. + * + *

+ * Project: envoy-client
+ * File: SystemCommandsMap.java
+ * Created: 17.07.2020
+ * + * @author Leon Hofmeister + * @since Envoy Client v0.1-beta + * @apiNote Please refrain from using the "/"-char in keys of this map. + * Unexpected behavior will occur. + */ +public class SystemCommandsMap { + + private final HashMap systemCommands = new HashMap<>(); + private boolean rethrowFailure = true; + + /** + * @param command the string that must be inputted to execute the + * given action + * @param action the action that should be performed + * @param numberOfArguments the amount of arguments that need to be parsed for + * the underlying function + * @since Envoy Client v0.1-beta + */ + public void addCommand(String command, Function action, int numberOfArguments) { + systemCommands.put(command, new SystemCommand(action, numberOfArguments)); + } + + /** + * Adds a new {@link SystemCommand} to the map that does not depend upon + * arguments in the given String + * + * @param command the string that must be inputted to execute the given action + * @param action the action that should be performed. To see why this Function + * takes a {@code String[]}, see {@link SystemCommand} + * @since Envoy Client v0.1-beta + */ + public void addNoArgCommand(String command, Function action) { addCommand(command, action, 0); } + + /** + * @param command the string that must be inputted to execute the + * given action + * @param action the action that should be performed. To see why this + * Function takes a {@code String[]}, see + * {@link SystemCommand} + * @param numberOfArguments the amount of arguments that need to be parsed for + * the underlying function + * @since Envoy Client v0.1-beta + */ + public void add(String command, Function action, int numberOfArguments) { + systemCommands.put(command, new SystemCommand(action, numberOfArguments)); + } + + /** + * This method checks if the input String is a key in the map and returns the + * wrapped System command if present. + * Its intended usage is after a "/" has been detected in the input String. + * It will return an empty optional if the value after the slash is not a key in + * the map, which is a valid case (i.e. input="3/4" and "4" is not a key in the + * map). + *

+ * Usage example:
+ * {@code SystemCommandsMap systemCommands = new SystemCommandsMap();}
+ * {@code systemCommands.add("example", Function.identity, 1);}
+ * {@code ....}
+ * user input: {@code "/example xyz ..."}
+ * {@code systemCommands.checkPresent("example xyz ...")} + * result: {@code SystemCommand[action=Function.identity, numberOfArguments=1]} + * + * @param input the input string given by the user, excluding the "/" + * @return the wrapped system command, if present + * @since Envoy Client v0.1-beta + */ + public Optional checkPresent(String input) { + // TODO: Is String.indexOf inclusive or exclusive? + final var firstWord = input.substring(0, input.indexOf(" ")); + return Optional.ofNullable(systemCommands.get(firstWord)); + } + + /** + * This method checks if the input String is a key in the map and executes the + * wrapped System command if present. + * Its intended usage is after a "/" has been detected in the input String. + * It will do nothing if the value after the slash is not a key in + * the map, which is a valid case (i.e. input="3/4" and "4" is not a key in the + * map). + *

+ * Usage example:
+ * {@code SystemCommandsMap systemCommands = new SystemCommandsMap();}
+ * {@code systemCommands.add("example", (words)-> <Button>.setText(words[0]), 1);}
+ * {@code ....}
+ * user input: {@code "/example xyz ..."}
+ * {@code systemCommands.executeIfPresent("example xyz ...")} + * result: {@code