From c82e3b3b2de0633317ec8fc85925e91422820597 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Sun, 8 Oct 2017 22:39:59 -0300 Subject: Start splitting into maven modules --- base/src/main/java/bjc/utils/cli/CLICommander.java | 134 +++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 base/src/main/java/bjc/utils/cli/CLICommander.java (limited to 'base/src/main/java/bjc/utils/cli/CLICommander.java') diff --git a/base/src/main/java/bjc/utils/cli/CLICommander.java b/base/src/main/java/bjc/utils/cli/CLICommander.java new file mode 100644 index 0000000..cccb255 --- /dev/null +++ b/base/src/main/java/bjc/utils/cli/CLICommander.java @@ -0,0 +1,134 @@ +package bjc.utils.cli; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Scanner; + +/** + * Runs a CLI interface from the provided set of streams. + * + * @author ben + * + */ +public class CLICommander { + /* + * The streams used for input and normal/error output. + */ + private final InputStream input; + private final OutputStream output; + private final OutputStream error; + + /* + * The command mode to start execution in. + */ + private CommandMode initialMode; + + /** + * Create a new CLI interface powered by streams. + * + * @param input + * The stream to get user input from. + * @param output + * The stream to send normal output to. + * @param error + * The stream to send error output to. + */ + public CLICommander(final InputStream input, final OutputStream output, final OutputStream error) { + if (input == null) + throw new NullPointerException("Input stream must not be null"); + else if (output == null) + throw new NullPointerException("Output stream must not be null"); + else if (error == null) throw new NullPointerException("Error stream must not be null"); + + this.input = input; + this.output = output; + this.error = error; + } + + /** + * Start handling commands from the given input stream. + */ + public void runCommands() { + /* + * Setup output streams. + */ + final PrintStream normalOutput = new PrintStream(output); + final PrintStream errorOutput = new PrintStream(error); + + /* + * Set up input streams. + * + * We're suppressing the warning because we might use the input + * stream multiple times. + */ + @SuppressWarnings("resource") + final Scanner inputSource = new Scanner(input); + + /* + * The mode currently being used to handle commands. + * + * Used to preserve the initial mode. + */ + CommandMode currentMode = initialMode; + + /* + * Process commands until we're told to stop. + */ + while (currentMode != null) { + /* + * Print out the command prompt, using a custom prompt + * if one is specified. + */ + if (currentMode.isCustomPromptEnabled()) { + normalOutput.print(currentMode.getCustomPrompt()); + } else { + normalOutput.print(currentMode.getName() + ">> "); + } + + /* + * Read in a command. + */ + final String currentLine = inputSource.nextLine(); + + /* + * Handle commands we can handle. + */ + if (currentMode.canHandle(currentLine)) { + final String[] commandTokens = currentLine.split(" "); + String[] commandArgs = null; + + final int argCount = commandTokens.length; + + /* + * Parse args if they are present. + */ + if (argCount > 1) { + commandArgs = Arrays.copyOfRange(commandTokens, 1, argCount); + } + + /* + * Process command. + */ + currentMode = currentMode.process(commandTokens[0], commandArgs); + } else { + errorOutput.print("Error: Unrecognized command " + currentLine); + } + } + + normalOutput.print("Exiting now."); + } + + /** + * Set the initial command mode to use. + * + * @param initialMode + * The initial command mode to use. + */ + public void setInitialCommandMode(final CommandMode initialMode) { + if (initialMode == null) throw new NullPointerException("Initial mode must be non-zero"); + + this.initialMode = initialMode; + } +} -- cgit v1.2.3