+ * Command Request Listeners are listeners that are notified before a command is + * executed by the ConsoleApplication, + * + * @author Emmanuel Bigeon */ +public interface CommandRequestListener { + void commandRequest(String command); +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java b/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java index 68a4219..f42fce7 100644 --- a/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java +++ b/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java @@ -37,13 +37,18 @@ package fr.bigeon.gclc; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import fr.bigeon.gclc.command.Command; import fr.bigeon.gclc.command.HelpExecutor; +import fr.bigeon.gclc.command.ICommandProvider; import fr.bigeon.gclc.command.SubedCommand; -import fr.bigeon.gclc.prompt.CLIPrompter; +import fr.bigeon.gclc.command.UnrecognizedCommand; +import fr.bigeon.gclc.exception.CommandRunException; +import fr.bigeon.gclc.exception.InvalidCommandName; import fr.bigeon.gclc.prompt.CLIPrompterMessages; +import fr.bigeon.gclc.system.SystemConsoleManager; /**
* A {@link ConsoleApplication} is an application that require the user to input @@ -53,7 +58,7 @@ import fr.bigeon.gclc.prompt.CLIPrompterMessages; * *
* {@link ConsoleApplication} app = new {@link ConsoleApplication#ConsoleApplication(String, String, String) ConsoleApplication("exit", "welcome", "see you latter")}; - * app.{@link ConsoleApplication#add(String, Command) add}("my_command", new {@link Command MyCommand()}); + * app.{@link ConsoleApplication#add(Command) add}("my_command", new {@link Command MyCommand()}); * app.start(); **
@@ -63,60 +68,142 @@ import fr.bigeon.gclc.prompt.CLIPrompterMessages;
* start method.
*
* @author Emmanuel BIGEON */
-public class ConsoleApplication {
+public class ConsoleApplication implements ICommandProvider {
- /** A space character */
- private static final String SPACE = " "; //$NON-NLS-1$
/** The welcome message */
private final String header;
/** The good bye message */
private final String footer;
+ /** The console manager */
+ protected final ConsoleManager manager;
/** The container of commands */
- private final SubedCommand root = new SubedCommand(
- new UnrecognizedCommand());
+ private final SubedCommand root;
/** The state of this application */
private boolean running;
+ /** The listeners */
+ private final List
- * Add an executable command to this application
- *
- * @param key the command keyword
- * @param cmd the command
- * @return if the command was added */
- public boolean add(String key, Command cmd) {
- return root.add(key, cmd);
+ @Override
+ public final boolean add(Command cmd) throws InvalidCommandName {
+ return root.add(cmd);
}
/** Launches the prompting application */
- public void start() {
- if (header != null) System.out.println(header);
+ public final void start() {
+ if (header != null) manager.println(header);
running = true;
do {
- String cmd = CLIPrompter.prompt();
- List
- * The error message for unrecognized commands
- *
- * @author Emmanuel BIGEON */
-class UnrecognizedCommand implements Command {
- /** The unrecognized command key */
- private static final String UNRECOGNIZED_CMD = "unrecognized.cmd"; //$NON-NLS-1$
-
- @Override
- public String tip() {
- return null;
- }
-
- @Override
- public void help(String[] args) {
- // Nothing to do (no help provided as this is one (usually)
- }
-
- @Override
- public void execute(String[] args) {
- System.out.println(CLIPrompterMessages.getString(UNRECOGNIZED_CMD,
- args[0]));
+ /** The actions to take before exiting */
+ public void beforeExit() {
+ // Do nothing by default
}
}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/ConsoleManager.java b/gclc/src/main/java/fr/bigeon/gclc/ConsoleManager.java
new file mode 100644
index 0000000..24ce4a1
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/ConsoleManager.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.ConsoleManager.java
+ * Created on: Dec 19, 2014
+ */
+package fr.bigeon.gclc;
+
+/**
+ * A console manager is in charge of the basic prompts and prints on a console.
+ *
+ * Depending on the implementation, some manager may not support the prompt with
+ * a message, in that case, the usual behavior is to prompt normally.
+ *
+ * @author Emmanuel BIGEON */
+public interface ConsoleManager {
+
+ /**
+ * Set a prompting prefix.
+ *
+ * @param prompt the prompt */
+ void setPrompt(String prompt);
+
+ /** @return the prompt prefix */
+ String getPrompt();
+
+ /** @return the user inputed string */
+ String prompt();
+
+ /** @param message the message to prompt the user
+ * @return the user inputed string */
+ String prompt(String message);
+
+ /** @param message the message to print */
+ void println(String message);
+
+ /** Prints an end of line */
+ void println();
+
+ /** @param text the message to print (without line break at the end). */
+ void print(String text);
+}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/Command.java b/gclc/src/main/java/fr/bigeon/gclc/command/Command.java
index 28f3954..012f75d 100644
--- a/gclc/src/main/java/fr/bigeon/gclc/command/Command.java
+++ b/gclc/src/main/java/fr/bigeon/gclc/command/Command.java
@@ -38,23 +38,62 @@
*/
package fr.bigeon.gclc.command;
-/**
- *
- * A command to execute.
+import fr.bigeon.gclc.ConsoleManager;
+
+/**
+ * A command to execute. It is mandatory that it has a name and that name cannot
+ * start with minus character or contain space
*
- * @author Emmanuel BIGEON
- */
-public interface Command {
- /**
- * @param args the arguments of the command (some expect an empty array)
- */
- public void execute(String[] args);
+ * @author Emmanuel BIGEON */
+public abstract class Command {
+
+ /** The name of the command */
+ protected final String name;
+
+ /** @param name the command name */
+ public Command(String name) {
+ super();
+ this.name = name;
+ }
+
+ /** @return the command's name */
+ public final String getCommandName() {
+ return name;
+ }
+
+ /** @param args the arguments of the command (some expect an empty array) */
+ public abstract void execute(String... args);
/** This prints the help associated to this command
*
+ * @param manager the manager to print the data
* @param args the arguments called with the help */
- public void help(String[] args);
+ public void help(ConsoleManager manager, String... args) {
+ manager.println(getCommandName());
+ manager.println(brief());
+ manager.println();
+ manager.println("Usage:"); //$NON-NLS-1$
+ manager.println(usagePattern());
+ manager.println();
+ manager.print(usageDetail());
+ }
+
+ /** @return the detailed help (should end with end of line or be empty) */
+ @SuppressWarnings("static-method")
+ protected String usageDetail() {
+ return new String();
+ }
+
+ /** @return the usage pattern */
+ protected String usagePattern() {
+ return getCommandName();
+ }
+
+ /** @return a brief description of the command */
+ protected String brief() {
+ return " " + tip(); //$NON-NLS-1$
+ }
/** @return a tip on the command */
- public String tip();
+ public abstract String tip();
}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/CommandParameters.java b/gclc/src/main/java/fr/bigeon/gclc/command/CommandParameters.java
new file mode 100644
index 0000000..4e79e68
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/command/CommandParameters.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.command.CommandParameters.java
+ * Created on: Dec 24, 2014
+ */
+package fr.bigeon.gclc.command;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * TODO
+ *
+ * @author Emmanuel BIGEON */
+public class CommandParameters {
+ private final HashMap
* A command provider is a map of key word to command to execute
@@ -45,34 +47,49 @@ import java.util.Map;
* @author Emmanuel BIGEON */
public class CommandProvider implements ICommandProvider {
/** The commands map */
- protected final Map
+/**
* TODO
*
- * @author Emmanuel BIGEON
- *
- */
-public class HelpExecutor implements Command {
+ * @author Emmanuel BIGEON */
+public class HelpExecutor extends Command {
/** The command to execute the help of */
private final Command cmd;
+ /** The console manager */
+ private final ConsoleManager consoleManager;
- /** @param cmd the command to execute the help of */
- public HelpExecutor(Command cmd) {
- super();
+ /** @param cmdName the command name
+ * @param consoleManager the manager for the console
+ * @param cmd the command to execute the help of
+ * @throws InvalidCommandName if the name is invalid */
+ public HelpExecutor(String cmdName, ConsoleManager consoleManager,
+ Command cmd) throws InvalidCommandName {
+ super(cmdName);
this.cmd = cmd;
+ if (consoleManager == null)
+ throw new NullPointerException(
+ "Argument cannot be null: ConsoleManager"); //$NON-NLS-1$
+ this.consoleManager = consoleManager;
}
/* (non-Javadoc)
- * @see fr.bigeon.gclc.command.Command#execute(java.lang.String[])
- */
+ * @see fr.bigeon.gclc.command.Command#execute(java.lang.String[]) */
@Override
- public void execute(String[] args) {
- cmd.help(args);
+ public void execute(String... args) {
+ cmd.help(consoleManager, args);
}
/* (non-Javadoc)
- * @see fr.bigeon.gclc.command.Command#help()
- */
+ * @see fr.bigeon.gclc.command.Command#help() */
@Override
- public void help(String[] args) {
- cmd.help(args);
+ public void help(ConsoleManager manager, String... args) {
+ manager.println(getCommandName());
+ manager.println(" A command to get help for other commands"); //$NON-NLS-1$
+ manager.println();
+ manager.println("Usage"); //$NON-NLS-1$
+ manager.println(" " + getCommandName() + "
* An ICommadProvider is a provider of commands that can register commands under
* some keywords.
@@ -43,17 +45,35 @@ package fr.bigeon.gclc.command;
* @author Emmanuel BIGEON */
public interface ICommandProvider {
- /** @param command the name of the command the user wishes to execute
+ /**
+ * This method provide the command with the given name found. If no command
+ * with this name is found, an error command is usually returned. If there
+ * are several commands with the same name, the behavior is unspecified.
+ * Depending on the implementation, it may return an error command or the
+ * first command with this name found.
+ *
+ * @param command the name of the command the user wishes to execute
* @return the command to execute */
public Command get(String command);
/**
- * Adds a command to this provider, if ne command was associated with the
+ * Adds a command to this provider, if no command was associated with the
* given key
*
- * @param key the command key
* @param value the command to execute
- * @return if the command was added */
- public boolean add(String key, Command value);
+ * @return if the command was added
+ * @throws InvalidCommandName if the command name is invalid */
+ public boolean add(Command value) throws InvalidCommandName;
+
+ /**
+ * This method executes the command with the given name found. If no command
+ * with this name is found, an error command is usually executed. If there
+ * are several commands with the same name, the behavior is unspecified.
+ * Depending on the implementation, it may run an error command or prompt
+ * the user for a choice.
+ *
+ * @param command the name of the command the user wishes to execute
+ * @param args the arguments for the command */
+ public void executeSub(String command, String... args);
}
\ No newline at end of file
diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/ParametrizedCommand.java b/gclc/src/main/java/fr/bigeon/gclc/command/ParametrizedCommand.java
new file mode 100644
index 0000000..2bb862e
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/command/ParametrizedCommand.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.command.ParametrizedCommand.java
+ * Created on: Dec 24, 2014
+ */
+package fr.bigeon.gclc.command;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import fr.bigeon.gclc.ConsoleManager;
+
+/**
+ * TODO
+ *
+ * @author Emmanuel BIGEON */
+public abstract class ParametrizedCommand extends Command {
+
+ private boolean interactive = true;
+ protected final ConsoleManager manager;
+ private final Map
+ * Add a parameter to the defined parameters
+ *
+ * @param param the parameter identification
+ * @param stringOrBool if the parameter is a parameter with an argument
+ * @param needed if the parameter is required */
+ @SuppressWarnings("boxing")
+ protected void addParameter(String param, boolean stringOrBool,
+ boolean needed) {
+ if (params.containsKey(param)) {
+ return;
+ }
+ params.put(param, needed);
+ if (stringOrBool) {
+ stringParams.put(param, needed);
+ } else {
+ if (needed) {
+ // ERROR the boolean parameters cannot be needed
+ }
+ boolParams.put(param, needed);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see fr.bigeon.gclc.command.Command#execute(java.lang.String[]) */
+ @SuppressWarnings("boxing")
+ @Override
+ public final void execute(String... args) {
+ CommandParameters parameters = new CommandParameters(
+ boolParams.keySet(), stringParams.keySet(), strict);
+ if (!parameters.parseArgs(args)) {
+ // ERROR the parameters could not be correctly parsed
+ manager.println("Unable to read arguments"); //$NON-NLS-1$
+ return;
+ }
+ List
- * TODO
+ * A subed command is a command that can execute sub commands depending on the
+ * first argument.
*
* @author Emmanuel BIGEON */
-public class SubedCommand extends CommandProvider implements Command {
+public class SubedCommand extends Command implements ICommandProvider {
/**
* The command to execute when this command is called with no sub arguments.
@@ -50,36 +54,47 @@ public class SubedCommand extends CommandProvider implements Command {
private final Command noArgCommand;
/** A tip on this command. */
private final String tip;
+ /** The provider */
+ private final CommandProvider provider;
- /** @param error the error to execute when called with wrong usage */
- public SubedCommand(Command error) {
- super(error);
+ /** @param name the name of the command
+ * @param error the error to execute when called with wrong usage */
+ public SubedCommand(String name, Command error) {
+ super(name);
+ provider = new CommandProvider(error);
noArgCommand = null;
tip = null;
}
- /** @param error the error to execute when called with wrong usage
+ /** @param name the name of the command
+ * @param error the error to execute when called with wrong usage
* @param tip the help tip associated */
- public SubedCommand(Command error, String tip) {
- super(error);
+ public SubedCommand(String name, Command error, String tip) {
+ super(name);
+ provider = new CommandProvider(error);
noArgCommand = null;
this.tip = tip;
}
- /** @param noArgCommand the command to execute
+ /** @param name the name of the command
+ * @param noArgCommand the command to execute
* @param error the error to execute when called with wrong usage
* @param tip the help tip associated */
- public SubedCommand(Command error, Command noArgCommand, String tip) {
- super(error);
+ public SubedCommand(String name, Command error, Command noArgCommand,
+ String tip) {
+ super(name);
+ provider = new CommandProvider(error);
this.noArgCommand = noArgCommand;
this.tip = tip;
}
- /** @param noArgCommand the command to execute when no extra parameter are
+ /** @param name the name of the command
+ * @param noArgCommand the command to execute when no extra parameter are
* provided
* @param error the error to execute when called with wrong usage */
- public SubedCommand(Command error, Command noArgCommand) {
- super(error);
+ public SubedCommand(String name, Command error, Command noArgCommand) {
+ super(name);
+ provider = new CommandProvider(error);
this.noArgCommand = noArgCommand;
tip = null;
}
@@ -87,34 +102,38 @@ public class SubedCommand extends CommandProvider implements Command {
/* (non-Javadoc)
* @see fr.bigeon.acide.Command#execute(java.lang.String[]) */
@Override
- public void execute(String[] args) {
- if (args.length == 1) {
+ public void execute(String... args) {
+ if (args.length == 0 || args[0].startsWith("-")) { //$NON-NLS-1$
if (noArgCommand != null)
noArgCommand.execute(args);
- else error.execute(args);
+ else provider.error.execute(args);
} else {
- get(args[1]).execute(Arrays.copyOfRange(args, 1, args.length));
+ executeSub(args[0], Arrays.copyOfRange(args, 1, args.length));
}
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.Command#help() */
@Override
- public void help(String[] args) {
- // TODO Auto-generated method stub
- if (args.length != 1) {
+ public void help(ConsoleManager manager, String... args) {
+ if (args.length != 0 && !args[0].startsWith("-")) { //$NON-NLS-1$
// Specific
- get(args[1]).help(Arrays.copyOfRange(args, 1, args.length));
+ Command c = get(args[0]);
+ if (c != null)
+ c.help(manager, Arrays.copyOfRange(args, 1, args.length));
+ else {
+ provider.error.execute(args);
+ }
} else {
// Generic
if (noArgCommand != null)
if (noArgCommand.tip() != null)
- System.out.println("\t" + noArgCommand.tip()); //$NON-NLS-1$
- for (String string : commands.keySet()) {
- if (commands.get(string).tip() == null)
- System.out.println("\t" + string); //$NON-NLS-1$
- else System.out.println("\t" + string + ": " + //$NON-NLS-1$ //$NON-NLS-2$
- commands.get(string).tip());
+ manager.println("\t" + noArgCommand.tip()); //$NON-NLS-1$
+ for (Command cmd : provider.commands) {
+ if (cmd.tip() == null)
+ manager.println("\t" + cmd.getCommandName()); //$NON-NLS-1$
+ else manager.println("\t" + cmd.getCommandName() + ": " + //$NON-NLS-1$ //$NON-NLS-2$
+ cmd.tip());
}
}
}
@@ -125,4 +144,31 @@ public class SubedCommand extends CommandProvider implements Command {
public String tip() {
return tip;
}
+
+ @Override
+ public Command get(String commandName) {
+ return provider.get(commandName);
+ }
+
+ @Override
+ public boolean add(Command value) throws InvalidCommandName {
+ return provider.add(value);
+ }
+
+ /* (non-Javadoc)
+ * @see
+ * fr.bigeon.gclc.command.ICommandProvider#executeSub(java.lang.String,
+ * java.lang.String[]) */
+ @Override
+ public void executeSub(String command, String... args) {
+ provider.executeSub(command, args);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString() */
+ @Override
+ public String toString() {
+ return "SubedCommand " + provider; //$NON-NLS-1$
+ }
+
}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/UnrecognizedCommand.java b/gclc/src/main/java/fr/bigeon/gclc/command/UnrecognizedCommand.java
new file mode 100644
index 0000000..c9222f2
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/command/UnrecognizedCommand.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.UnrecognizedCommand.java
+ * Created on: Dec 23, 2014
+ */
+package fr.bigeon.gclc.command;
+
+import fr.bigeon.gclc.ConsoleManager;
+import fr.bigeon.gclc.prompt.CLIPrompterMessages;
+
+/**
+ * The error message for unrecognized commands
+ *
+ * @author Emmanuel BIGEON */
+public final class UnrecognizedCommand extends Command {
+ /** The unrecognized command key */
+ private static final String UNRECOGNIZED_CMD = "unrecognized.cmd"; //$NON-NLS-1$
+ /** The unrecognized command key */
+ private static final String EXPECTED_CMD = "expected.cmd"; //$NON-NLS-1$
+ /** The manager */
+ private final ConsoleManager manager;
+
+ /** @param manager the console manager to use */
+ public UnrecognizedCommand(ConsoleManager manager) {
+ super(new String());
+ if (manager == null) {
+ throw new NullPointerException("The argument cannot be null"); //$NON-NLS-1$
+ }
+ this.manager = manager;
+ }
+
+ @Override
+ public String tip() {
+ return null;
+ }
+
+ @Override
+ public void help(@SuppressWarnings("hiding") ConsoleManager manager,
+ String... args) {
+ // Nothing to do (no help provided as this is not a user command
+ // (usually)
+ }
+
+ @Override
+ public void execute(String... args) {
+ if (args.length > 0)
+ manager.println(CLIPrompterMessages.getString(UNRECOGNIZED_CMD,
+ (Object[]) args));
+ else manager.println(CLIPrompterMessages.getString(EXPECTED_CMD));
+ }
+}
\ No newline at end of file
diff --git a/gclc/src/main/java/fr/bigeon/gclc/exception/CommandRunException.java b/gclc/src/main/java/fr/bigeon/gclc/exception/CommandRunException.java
new file mode 100644
index 0000000..8a31ae5
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/exception/CommandRunException.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.exception.CommandRunException.java
+ * Created on: Feb 10, 2015
+ */
+package fr.bigeon.gclc.exception;
+
+/**
+ * An exception thrown when a command failed to run correctly.
+ *
+ * @author Emmanuel BIGEON */
+public class CommandRunException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /** @param message a message
+ * @param cause the cause */
+ public CommandRunException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /** @param message a message */
+ public CommandRunException(String message) {
+ super(message);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Throwable#getLocalizedMessage() */
+ @Override
+ public String getLocalizedMessage() {
+ if (getCause() != null) {
+ return super.getLocalizedMessage() + ": " + //$NON-NLS-1$
+ getCause().getLocalizedMessage();
+ }
+ return super.getLocalizedMessage();
+ }
+
+}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/exception/InvalidCommandName.java b/gclc/src/main/java/fr/bigeon/gclc/exception/InvalidCommandName.java
new file mode 100644
index 0000000..7e4d27d
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/exception/InvalidCommandName.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.exception.InvalidCommandName.java
+ * Created on: Dec 23, 2014
+ */
+package fr.bigeon.gclc.exception;
+
+/**
+ *
+ * TODO
+ *
+ * @author Emmanuel BIGEON
+ *
+ */
+public class InvalidCommandName extends Exception {
+
+}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java b/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java
index 8a89326..a5dc533 100644
--- a/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java
+++ b/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java
@@ -36,11 +36,12 @@
* Created on: Jul 31, 2014 */
package fr.bigeon.gclc.prompt;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import fr.bigeon.gclc.ConsoleManager;
+
/**
* The {@link CLIPrompter} class is a utility class that provides method to
* prompt the user.
@@ -54,56 +55,76 @@ public class CLIPrompter {
private static final String LIST_DISP_KEY = "promptlist.exit.dispkey"; //$NON-NLS-1$
@SuppressWarnings("javadoc")
private static final String PROMPT = "prompt.lineprompt"; //$NON-NLS-1$
- /** @param choices the choices
- * @param cancel the cancel option if it exists
- * @return the number of choices plus one */
- private static int listChoices(List choices, String cancel) {
- int index = 0;
- for (U u : choices) {
- System.out.println((index++) + ") " + u); //$NON-NLS-1$
- }
- if (cancel != null) {
- System.out.println((index++) + ") " + cancel); //$NON-NLS-1$
- }
- return --index;
+
+ /** @param manager the manager
+ * @param prompt the prompting message
+ * @param reprompt the prompting message after empty input
+ * @return the non empty input */
+ public static String promptNonEmpty(ConsoleManager manager, String prompt,
+ String reprompt) {
+ String res = manager.prompt(prompt);
+ while (res.isEmpty())
+ res = manager.prompt(reprompt);
+ return res;
}
- /**
- * Prompts the user for an input
- *
- * @return the user input */
- public static String prompt() {
-
- // TODO Auto-generated method stub
- return prompt(CLIPrompterMessages.getString(PROMPT) + " "); //$NON-NLS-1$
- }
-
- /** This method prompts for a user input
+ /** Prompt for a text with several lines.
*
+ * @param manager the manager
* @param message the prompting message
- * @return the user entered line */
- public static String prompt(String message) {
- String result = ""; //$NON-NLS-1$
- System.out.print(message + " "); //$NON-NLS-1$
- char c;
- try {
- c = (char) System.in.read();
- while (c != System.lineSeparator().charAt(0)) {
- result += c;
- c = (char) System.in.read();
- }
- while (System.in.available() != 0)
- System.in.read();
- } catch (IOException e) {
- e.printStackTrace();
+ * @param ender the ender character
+ * @return the text */
+ public static String promptLongText(ConsoleManager manager, String message,
+ String ender) {
+ manager.println(message +
+ CLIPrompterMessages.getString(
+ "promptlongtext.exit.dispkey", ender)); //$NON-NLS-1$
+ String res = manager.prompt(PROMPT);
+ String line = res;
+ while (!line.equals(ender)) {
+ line = manager.prompt(PROMPT);
+ if (!line.equals(ender)) res += System.lineSeparator() + line;
}
- return result;
+ return res.equals(ender) ? "" : res; //$NON-NLS-1$
}
- /** @param message the prompting message
+ /** Prompt for a text with several lines.
+ *
+ * @param manager the manager
+ * @param message the prompting message
+ * @return the text */
+ public static String promptLongText(ConsoleManager manager, String message) {
+ return promptLongText(manager, message,
+ CLIPrompterMessages.getString("promptlongtext.exit.defaultkey")); //$NON-NLS-1$
+ }
+
+ /** @param manager the manager
+ * @param message the prompt message
+ * @return the integer */
+ public static int promptInteger(ConsoleManager manager, String message) {
+ boolean still = true;
+ int r = 0;
+ while (still) {
+ String result = manager.prompt(message);
+ try {
+ if (result.isEmpty()) {
+ still = true;
+ continue;
+ }
+ r = Integer.parseInt(result);
+ still = false;
+ } catch (Exception e) {
+ still = true;
+ }
+ }
+ return r;
+ }
+
+ /** @param manager the manager
+ * @param message the prompting message
* @return the choice */
- public static boolean promptBoolean(String message) {
- String result = prompt(message +
+ public static boolean promptBoolean(ConsoleManager manager, String message) {
+ String result = manager.prompt(message +
CLIPrompterMessages.getString(BOOL_CHOICES));
boolean first = true;
String choices = CLIPrompterMessages
@@ -121,10 +142,10 @@ public class CLIPrompter {
result) || CLIPrompterMessages.getString(
"promptbool.choices.yes2").equalsIgnoreCase(result))) { //$NON-NLS-1$
if (!first) {
-
- System.out.println(CLIPrompterMessages.getString(
+
+ manager.println(CLIPrompterMessages.getString(
"promptbool.choices.invalid", choices)); //$NON-NLS-1$
- result = prompt(message +
+ result = manager.prompt(message +
CLIPrompterMessages.getString(BOOL_CHOICES));
}
first = false;
@@ -135,56 +156,8 @@ public class CLIPrompter {
.getString("promptbool.choices.yes2")); //$NON-NLS-1$
}
- /** @param the type of choices
- * @param choices the list of choices
- * @param message the prompting message
- * @param cancel the cancel option, or null
- * @return the index of the choice */
- @SuppressWarnings("boxing")
- public static Integer promptChoice(List choices, String message,
- String cancel) {
- System.out.println(message);
- int index = listChoices(choices, cancel);
- String result = ""; //$NON-NLS-1$
- boolean keepOn = true;
- int r = -1;
- while (keepOn) {
- result = prompt(CLIPrompterMessages.getString(PROMPT));
- try {
- r = Integer.parseInt(result);
- if (r >= 0 && r <= index)
- keepOn = false;
- else {
- System.out.println(CLIPrompterMessages.getString(
- "promptchoice.outofbounds", 0, index)); //$NON-NLS-1$
- listChoices(choices, cancel);
- }
-
- } catch (NumberFormatException e) {
- keepOn = true;
- System.out.println(CLIPrompterMessages.getString(
- "promptchoice.formaterr", 0, index)); //$NON-NLS-1$
- listChoices(choices, cancel);
- }
- }
- if (r == index && cancel != null) return null;
- return r;
- }
-
- /** @param keys the keys to be printed
- * @param choices the real choices
- * @param message the message
- * @param cancel the cancel option, or null
- * @return the choice */
- @SuppressWarnings("boxing")
- public static U promptChoice(List
+ * TODO
+ *
+ * @author Emmanuel BIGEON
+ *
+ */
+public class SystemConsoleManager implements ConsoleManager {
+
+ /** The default prompt */
+ public static final String DEFAULT_PROMPT = ">"; //$NON-NLS-1$
+
+ /** The command prompt. It can be changed. */
+ private String prompt = DEFAULT_PROMPT;
+
+ /** @return the prompt */
+ @Override
+ public String getPrompt() {
+ return prompt;
+ }
+
+ /** @param prompt the prompt to set */
+ @Override
+ public void setPrompt(String prompt) {
+ this.prompt = prompt;
+ }
+
+ /* (non-Javadoc)
+ * @see fr.bigeon.gclc.ConsoleManager#prompt()
+ */
+ @Override
+ public String prompt() {
+ return prompt(new String() + prompt);
+ }
+
+ /* (non-Javadoc)
+ * @see fr.bigeon.gclc.ConsoleManager#prompt(java.lang.String)
+ */
+ @Override
+ public String prompt(String message) {
+ String result = new String();
+ System.out.print(message + ' ');
+ char c;
+ try {
+ c = (char) System.in.read();
+ while (c != System.lineSeparator().charAt(0)) {
+ result += c;
+ c = (char) System.in.read();
+ }
+ while (System.in.available() != 0)
+ System.in.read();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see fr.bigeon.gclc.ConsoleManager#println(java.lang.Object)
+ */
+ @Override
+ public void println(String object) {
+ System.out.println(object);
+ }
+
+ /* (non-Javadoc)
+ * @see fr.bigeon.gclc.ConsoleManager#print(java.lang.Object)
+ */
+ @Override
+ public void print(String object) {
+ System.out.print(object);
+ }
+
+ /* (non-Javadoc)
+ * @see fr.bigeon.gclc.ConsoleManager#println() */
+ @Override
+ public void println() {
+ System.out.println();
+ }
+
+}
diff --git a/gclc/src/main/java/fr/bigeon/gclc/system/package-info.java b/gclc/src/main/java/fr/bigeon/gclc/system/package-info.java
new file mode 100644
index 0000000..445b10f
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/system/package-info.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * gclc:fr.bigeon.gclc.system.package-info.java
+ * Created on: Dec 19, 2014
+ */
+/**
+ *
+ * The basic system based console manager elements
+ *
+ * @author Emmanuel BIGEON
+ *
+ */
+package fr.bigeon.gclc.system;
\ No newline at end of file
diff --git a/gclc/src/main/java/fr/bigeon/gclc/tools/PrintUtils.java b/gclc/src/main/java/fr/bigeon/gclc/tools/PrintUtils.java
new file mode 100644
index 0000000..50533a1
--- /dev/null
+++ b/gclc/src/main/java/fr/bigeon/gclc/tools/PrintUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright Bigeon Emmanuel (2014)
+ *
+ * emmanuel@bigeon.fr
+ *
+ * This software is a computer program whose purpose is to
+ * provide a generic framework for console applications.
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the software's author, the holder of the
+ * economic rights, and the successive licensors have only limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also
+ * therefore means that it is reserved for developers and experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and, more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ */
+/**
+ * acide:fr.bigeon.acide.tools.PrintUtils.java
+ * Created on: Jan 20, 2015
+ */
+package fr.bigeon.gclc.tools;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * TODO
+ *
+ * @author Emmanuel BIGEON
+ *
+ */
+public class PrintUtils {
+ /** @param text the text to print
+ * @param nbCharacters the number of characters of the resulting text
+ * @param indicateTooLong if an indication shell be given that the text
+ * didn't fit
+ * @return the text to print (will be of exactly nbCharacters). */
+ public static String print(String text, int nbCharacters,
+ boolean indicateTooLong) {
+ String res = text;
+ if (res.length() > nbCharacters) {
+ // Cut
+ if (indicateTooLong) {
+ // With suspension dots
+ res = res.substring(0, nbCharacters - 3) + "..."; //$NON-NLS-1$
+ } else {
+ res = res.substring(0, nbCharacters);
+ }
+ }
+ while (res.length() < nbCharacters) {
+ // Add trailing space
+ res = res + ' ';
+ }
+ return res;
+ }
+
+ /** @param description the element to wrap in lines
+ * @param i the length of the wrap
+ * @return the list of resulting strings */
+ public static List