Added consistent and safer way to get the currently requested command

This commit is contained in:
delvh 2020-07-23 15:50:45 +02:00
parent 74aa00235e
commit 83852b9e09
No known key found for this signature in database
GPG Key ID: 42B77E634CE94D82

View File

@ -128,8 +128,9 @@ public class SystemCommandsMap {
final boolean valid = commandBounds.matcher(command).matches(); final boolean valid = commandBounds.matcher(command).matches();
if (!valid) EnvoyLog.getLogger(SystemCommandsMap.class) if (!valid) EnvoyLog.getLogger(SystemCommandsMap.class)
.log(Level.WARNING, .log(Level.WARNING,
"The command \"" + command + "\" is not valid. It will cause problems in execution: Only the characters " + commandBounds "The command \"" + command
+ "are allowed"); + "\" 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; return valid;
} }
@ -153,10 +154,7 @@ public class SystemCommandsMap {
* @return the wrapped system command, if present * @return the wrapped system command, if present
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
public Optional<SystemCommand> checkPresent(String input) { public Optional<SystemCommand> checkPresent(String input) { return Optional.ofNullable(systemCommands.get(getCommand(input))); }
final var firstWord = input.substring(0, input.indexOf(" "));
return Optional.ofNullable(systemCommands.get(firstWord));
}
/** /**
* Takes a 'raw' string (the whole input) and checks if a command is present * 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++) for (int i = fromIndex; i < raw.length() - 2; i++)
// possibly a command was detected // possibly a command was detected
if (raw.charAt(i) == '/') { if (raw.charAt(i) == '/') {
// executeIfPresent(getCommand(raw, i));
executeIfPresent(raw.substring(i + 1));
// the command was executed successfully - no further checking needed // the command was executed successfully - no further checking needed
if (commandExecuted) { if (commandExecuted) {
commandExecuted = false; commandExecuted = false;
logger.log(Level.FINE, "executed system command " + getCommand(raw, i));
break; break;
} }
} }
} }
/**
* This method ensures that the "/" of a {@link SystemCommand} is stripped.<br>
* It returns the command as (most likely) entered as key in the map starting
* from {@code fromIndex}.<br>
* 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.<br>
* It returns the command as (most likely) entered as key in the map for the
* first word of the text.<br>
* 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 * This method checks if the input String is a key in the map and executes the
* wrapped System command if present. * 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 // removed and only as many following words as allowed by the system command
// persist // persist
final var remainingString = input.substring(input.indexOf(" ") + 1); 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, ... // behind each other (" "), not enough words, ...
final var arguments = Arrays.copyOfRange(remainingString.split(" "), 0, systemCommand.getNumberOfArguments()); final var arguments = Arrays.copyOfRange(remainingString.split(" "), 0, systemCommand.getNumberOfArguments());
// Executing the function // Executing the function
@ -232,9 +266,7 @@ public class SystemCommandsMap {
systemCommand.getAction().apply(arguments); systemCommand.getAction().apply(arguments);
commandExecuted = true; commandExecuted = true;
} catch (final Exception e) { } catch (final Exception e) {
logger.log(Level.WARNING, "The system command " + logger.log(Level.WARNING, "The system command " + getCommand(input) + " threw an exception: ", e);
// detected command
input.substring(0, input.indexOf(" ")) + " threw an exception: ", e);
} }
}); });
} }
@ -267,7 +299,7 @@ public class SystemCommandsMap {
* @since Envoy Client v0.2-beta * @since Envoy Client v0.2-beta
*/ */
private void requestRecommendations(String input, int fromIndex, Function<Set<String>, Void> action) { private void requestRecommendations(String input, int fromIndex, Function<Set<String>, 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 // Get the expected commands
final var recommendations = recommendCommands(partialCommand); final var recommendations = recommendCommands(partialCommand);
if (recommendations.isEmpty()) return; if (recommendations.isEmpty()) return;