Added System command description and added recommendation ability

Additionally removed ability to decide whether exceptions thrown by
SystemCommands should be rethrown as a mentally superior team member
intervened that it would be useless.
This commit is contained in:
delvh 2020-07-18 11:25:41 +02:00
parent da77afdc32
commit 5ce62c10ca
2 changed files with 73 additions and 29 deletions

View File

@ -37,17 +37,21 @@ public final class SystemCommand {
*/
protected final Function<String[], Void> action;
protected final String description;
/**
* Constructs a new {@code NoArgSystemCommand} that takes no arguments.
*
* @param action the action that should be performed
* @param numberOfArguments the amount of arguments that need to be parsed for
* the underlying function
* @param description the description of this {@code SystemCommand}
* @since Envoy Client v0.1-beta
*/
public SystemCommand(Function<String[], Void> action, int numberOfArguments) {
public SystemCommand(Function<String[], Void> action, int numberOfArguments, String description) {
this.numberOfArguments = numberOfArguments;
this.action = action;
this.description = description;
}
/**
@ -62,4 +66,10 @@ public final class SystemCommand {
* @since Envoy Client v0.1-beta
*/
public int getNumberOfArguments() { return numberOfArguments; }
/**
* @return the description
* @since Envoy Client v0.1-beta
*/
public String getDescription() { return description; }
}

View File

@ -1,16 +1,14 @@
package envoy.client.data.commands;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Optional;
import java.util.*;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import envoy.util.EnvoyLog;
/**
* This class stores all {@link SystemCommand}s used.
*
* <p>
* Project: <strong>envoy-client</strong><br>
* File: <strong>SystemCommandsMap.java</strong><br>
@ -23,8 +21,7 @@ import envoy.util.EnvoyLog;
*/
public class SystemCommandsMap {
private final HashMap<String, SystemCommand> systemCommands = new HashMap<>();
private boolean rethrowFailure = true;
private final HashMap<String, SystemCommand> systemCommands = new HashMap<>();
/**
* @param command the string that must be inputted to execute the
@ -35,7 +32,20 @@ public class SystemCommandsMap {
* @since Envoy Client v0.1-beta
*/
public void addCommand(String command, Function<String[], Void> action, int numberOfArguments) {
systemCommands.put(command, new SystemCommand(action, numberOfArguments));
systemCommands.put(command, new SystemCommand(action, numberOfArguments, ""));
}
/**
* @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
* @param description the description of this {@link SystemCommand}
* @since Envoy Client v0.1-beta
*/
public void addCommand(String command, Function<String[], Void> action, int numberOfArguments, String description) {
systemCommands.put(command, new SystemCommand(action, numberOfArguments, description));
}
/**
@ -49,6 +59,20 @@ public class SystemCommandsMap {
*/
public void addNoArgCommand(String command, Function<String[], Void> action) { addCommand(command, action, 0); }
/**
* 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}
* @param description the description of this {@link SystemCommand}
* @since Envoy Client v0.1-beta
*/
public void addNoArgCommand(String command, Function<String[], Void> action, String description) { addCommand(command, action, 0); }
/**
* @param command the string that must be inputted to execute the
* given action
@ -60,7 +84,7 @@ public class SystemCommandsMap {
* @since Envoy Client v0.1-beta
*/
public void add(String command, Function<String[], Void> action, int numberOfArguments) {
systemCommands.put(command, new SystemCommand(action, numberOfArguments));
systemCommands.put(command, new SystemCommand(action, numberOfArguments, ""));
}
/**
@ -84,7 +108,6 @@ public class SystemCommandsMap {
* @since Envoy Client v0.1-beta
*/
public Optional<SystemCommand> checkPresent(String input) {
// TODO: Is String.indexOf inclusive or exclusive?
final var firstWord = input.substring(0, input.indexOf(" "));
return Optional.ofNullable(systemCommands.get(firstWord));
}
@ -113,14 +136,9 @@ public class SystemCommandsMap {
// Splitting the String so that the leading command including the first " " is
// removed and only as many following words as allowed by the system command
// persist
// TODO: Is String.indexOf inclusive or exclusive?
final var remainingString = input.substring(input.indexOf(" ") + 1);
// TODO: Is Arrays.copyOfRange inclusive or exclusive in the "to" parameter?
// TODO: Current implementation will fail in certain cases, i.e. two characters
// behind each other (" "), not enough words, ...
// TODO: Another way of failure is the fact that in the current implementation,
// it is assumed that a String is already present in finished form and not that
// it will be finished later on, or does it?
final var arguments = Arrays.copyOfRange(remainingString.split(" "), 0, systemCommand.getNumberOfArguments());
// Executing the function
try {
@ -129,30 +147,46 @@ public class SystemCommandsMap {
EnvoyLog.getLogger(SystemCommandsMap.class).log(Level.WARNING, "The system command " +
// detected command
input.substring(0, input.indexOf(" ")) + " threw an exception: ", e);
if (rethrowFailure) throw e;
}
});
}
/**
* @return whether failures of {@link SystemCommand}s should be rethrown
* Retrieves the recommendations based on the current command entered (i.e the
* String "/exam" should be entered as "exam"). If none are present, nothing
* will be done.
* Otherwise the given function will be executed on the recommendations.
*
* @param input the String between "/" and " "
* @param action the action that should be taken for the recommendations, if any
* are present
* @since Envoy Client v0.1-beta
*/
public boolean isRethrowFailure() { return rethrowFailure; }
/**
* @param rethrowFailure whether failures of {@link SystemCommand}s should be
* rethrown
* @return this instance of a {@code SystemCommandsMap}
* @since Envoy Client v0.1-beta
*/
public SystemCommandsMap setRethrowFailure(boolean rethrowFailure) {
this.rethrowFailure = rethrowFailure;
return this;
public void requestRecommendations(String input, Function<Set<String>, Void> action) {
final var partialCommand = input.substring(0, input.indexOf(" "));
// Get the expected commands
final var recommendations = recommendCommands(partialCommand);
if (recommendations.isEmpty()) return;
// Execute the given action
else action.apply(recommendations);
}
/**
* @return the systemCommands
* Recommends commands based upon the currently entered input.<br>
* In the current implementation, all we check is whether a key contains this
* input. This might be updated later on.
*
* @param partialCommand the partially entered command
* @return a set of all commands that match this input
*/
private Set<String> recommendCommands(String partialCommand) {
// current implementation only looks if input is contained within a command,
// might be updated
return systemCommands.keySet().stream().filter(command -> command.contains(partialCommand)).collect(Collectors.toSet());
}
/**
* @return all {@link SystemCommand}s used with the underlying command as key
* @since Envoy Client v0.1-beta
*/
public HashMap<String, SystemCommand> getSystemCommands() { return systemCommands; }