From 83852b9e092eae7ef30c67854996160bbbd287fd Mon Sep 17 00:00:00 2001 From: delvh Date: Thu, 23 Jul 2020 15:50:45 +0200 Subject: [PATCH] Added consistent and safer way to get the currently requested command --- .../data/commands/SystemCommandsMap.java | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java b/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java index 5dedfd3..2eb45f2 100644 --- a/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java +++ b/client/src/main/java/envoy/client/data/commands/SystemCommandsMap.java @@ -128,8 +128,9 @@ public class SystemCommandsMap { final boolean valid = commandBounds.matcher(command).matches(); if (!valid) EnvoyLog.getLogger(SystemCommandsMap.class) .log(Level.WARNING, - "The command \"" + command + "\" is not valid. It will cause problems in execution: Only the characters " + commandBounds - + "are allowed"); + "The command \"" + command + + "\" is not valid. As it will cause problems in execution, it will not be entered into the map. Only the characters " + + commandBounds + "are allowed"); return valid; } @@ -153,10 +154,7 @@ public class SystemCommandsMap { * @return the wrapped system command, if present * @since Envoy Client v0.2-beta */ - public Optional checkPresent(String input) { - final var firstWord = input.substring(0, input.indexOf(" ")); - return Optional.ofNullable(systemCommands.get(firstWord)); - } + public Optional checkPresent(String input) { return Optional.ofNullable(systemCommands.get(getCommand(input))); } /** * Takes a 'raw' string (the whole input) and checks if a command is present @@ -188,16 +186,52 @@ public class SystemCommandsMap { for (int i = fromIndex; i < raw.length() - 2; i++) // possibly a command was detected if (raw.charAt(i) == '/') { - // - executeIfPresent(raw.substring(i + 1)); + executeIfPresent(getCommand(raw, i)); // the command was executed successfully - no further checking needed if (commandExecuted) { commandExecuted = false; + logger.log(Level.FINE, "executed system command " + getCommand(raw, i)); break; } } } + /** + * This method ensures that the "/" of a {@link SystemCommand} is stripped.
+ * It returns the command as (most likely) entered as key in the map starting + * from {@code fromIndex}.
+ * It should only be called on strings that contain a "/" . + * + * @param raw the input + * @param fromIndex the index from which to expect the system command - + * regardless of whether the slash is still present at this + * index + * @return the command as entered in the map + * @since Envoy Client v0.2-beta + * @apiNote this method will (most likely) not return anything useful if + * whatever is entered after the slash is not a system command. Only + * exception: for recommendation purposes. + */ + public String getCommand(String raw, int fromIndex) { + final var index = raw.indexOf(' '); + return raw.substring(fromIndex + raw.charAt(0) == '/' ? 1 : 0, index < 1 ? raw.length() : index); + } + + /** + * This method ensures that the "/" of a {@link SystemCommand} is stripped.
+ * It returns the command as (most likely) entered as key in the map for the + * first word of the text.
+ * It should only be called on strings that contain a "/" at position 0/-1. + * + * @param raw the input + * @return the command as entered in the map + * @since Envoy Client v0.2-beta + * @apiNote this method will (most likely) not return anything useful if + * whatever is entered after the slash is not a system command. Only + * exception: for recommendation purposes. + */ + public String getCommand(String raw) { return getCommand(raw, 0); } + /** * This method checks if the input String is a key in the map and executes the * wrapped System command if present. @@ -224,7 +258,7 @@ public class SystemCommandsMap { // removed and only as many following words as allowed by the system command // persist final var remainingString = input.substring(input.indexOf(" ") + 1); - // TODO: Current implementation will fail in certain cases, i.e. two characters + // TODO: Current implementation will fail in certain cases, i.e. two spaces // behind each other (" "), not enough words, ... final var arguments = Arrays.copyOfRange(remainingString.split(" "), 0, systemCommand.getNumberOfArguments()); // Executing the function @@ -232,9 +266,7 @@ public class SystemCommandsMap { systemCommand.getAction().apply(arguments); commandExecuted = true; } catch (final Exception e) { - logger.log(Level.WARNING, "The system command " + - // detected command - input.substring(0, input.indexOf(" ")) + " threw an exception: ", e); + logger.log(Level.WARNING, "The system command " + getCommand(input) + " threw an exception: ", e); } }); } @@ -267,7 +299,7 @@ public class SystemCommandsMap { * @since Envoy Client v0.2-beta */ private void requestRecommendations(String input, int fromIndex, Function, Void> action) { - final var partialCommand = input.substring(fromIndex + (input.charAt(fromIndex) == '/' ? 1 : 0), input.indexOf(" ")); + final var partialCommand = getCommand(input, fromIndex); // Get the expected commands final var recommendations = recommendCommands(partialCommand); if (recommendations.isEmpty()) return;