From 7510afa682106e38c21dd97017cd98cf9ed76467 Mon Sep 17 00:00:00 2001 From: Emmanuel Bigeon Date: Wed, 5 Nov 2014 17:13:36 +0100 Subject: [PATCH] Project in version 1 --- gclc/.gitignore | 4 + gclc/pom.xml | 83 +++++ .../fr/bigeon/gclc/ConsoleApplication.java | 187 ++++++++++ .../java/fr/bigeon/gclc/command/Command.java | 60 ++++ .../bigeon/gclc/command/CommandProvider.java | 78 +++++ .../fr/bigeon/gclc/command/HelpExecutor.java | 84 +++++ .../bigeon/gclc/command/ICommandProvider.java | 59 ++++ .../fr/bigeon/gclc/command/SubedCommand.java | 128 +++++++ .../fr/bigeon/gclc/command/package-info.java | 42 +++ .../fr/bigeon/gclc/prompt/CLIPrompter.java | 323 ++++++++++++++++++ .../gclc/prompt/CLIPrompterMessages.java | 82 +++++ .../fr/bigeon/gclc/prompt/package-info.java | 41 +++ .../gclc/licensing/cecill/CeCILL-header.txt | 32 ++ .../fr/bigeon/gclc/messages.properties | 23 ++ 14 files changed, 1226 insertions(+) create mode 100644 gclc/.gitignore create mode 100644 gclc/pom.xml create mode 100644 gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/command/Command.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/command/CommandProvider.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/command/HelpExecutor.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/command/ICommandProvider.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/command/SubedCommand.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/command/package-info.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompterMessages.java create mode 100644 gclc/src/main/java/fr/bigeon/gclc/prompt/package-info.java create mode 100644 gclc/src/main/resources/fr/bigeon/gclc/licensing/cecill/CeCILL-header.txt create mode 100644 gclc/src/main/resources/fr/bigeon/gclc/messages.properties diff --git a/gclc/.gitignore b/gclc/.gitignore new file mode 100644 index 0000000..8bd3a05 --- /dev/null +++ b/gclc/.gitignore @@ -0,0 +1,4 @@ +/target/ +/.settings/ +/.classpath +/.project diff --git a/gclc/pom.xml b/gclc/pom.xml new file mode 100644 index 0000000..3ddfefa --- /dev/null +++ b/gclc/pom.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 4.0.0 + gclc + 1.0.1 + jar + http://www.bigeon.fr/emmanuel + + UTF-8 + + + + junit + junit + 4.11 + test + + + + fr.bigeon + bigeon-config + 1.2 + + + + + com.mycila + license-maven-plugin + +
fr/bigeon/gclc/licensing/cecill/CeCILL-header.txt
+ + Bigeon Emmanuel + emmanuel@bigeon.fr + +
+ + + + check + + + +
+
+
+ 2014 + Generic Command Ligne console + provide a generic framework for console applications +
diff --git a/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java b/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java new file mode 100644 index 0000000..68a4219 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/ConsoleApplication.java @@ -0,0 +1,187 @@ +/* + * 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.ConsoleApplication.java + * Created on: Sep 6, 2014 */ +package fr.bigeon.gclc; + +import java.util.ArrayList; +import java.util.List; + +import fr.bigeon.gclc.command.Command; +import fr.bigeon.gclc.command.HelpExecutor; +import fr.bigeon.gclc.command.SubedCommand; +import fr.bigeon.gclc.prompt.CLIPrompter; +import fr.bigeon.gclc.prompt.CLIPrompterMessages; + +/**

+ * A {@link ConsoleApplication} is an application that require the user to input + * commands. + *

+ * A typical use case is the following: + * + *

+ * {@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.start();
+ * 
+ *

+ * That will launch in the console application that will display "welcome", + * return a line and prompt the user for the command until he inputs the + * exit command. Then it will print "see you latter" and exit the + * start method. + * + * @author Emmanuel BIGEON */ +public class ConsoleApplication { + + /** 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 container of commands */ + private final SubedCommand root = new SubedCommand( + new UnrecognizedCommand()); + /** The state of this application */ + private boolean running; + + /** @param exit the keyword for the exit command of this application + * @param welcome the header message to display on launch of this + * application + * @param goodbye the message to display on exit */ + public ConsoleApplication(String exit, String welcome, String goodbye) { + super(); + this.header = welcome; + this.footer = goodbye; + root.add(exit, new ExitCommand(this)); + } + + /**

+ * 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); + } + + /** Launches the prompting application */ + public void start() { + if (header != null) System.out.println(header); + running = true; + do { + String cmd = CLIPrompter.prompt(); + List args = new ArrayList<>(); + for (String string : cmd.split(SPACE)) { + if (!string.isEmpty()) args.add(string); + } + if (args.size() > 0) { + root.get(args.get(0)).execute(args.toArray(new String[0])); + } + } while (running); + if (footer != null) System.out.println(footer); + } + + /** Exit this running application before next command prompt */ + public void exit() { + running = false; + } + + /** Adds help command on the given key + * + * @param cmd the handle for help + * @return if the help command was added */ + public boolean addHelpCommand(String cmd) { + return root.add(cmd, new HelpExecutor(root)); + } +} + +/**

+ * A command to exit a {@link ConsoleApplication}. + * + * @author Emmanuel BIGEON */ +class ExitCommand implements Command { + /** The application that will be exited when this command runs */ + private final ConsoleApplication app; + /** The tip of the exit command */ + private final String EXIT = "exit.tip"; //$NON-NLS-1$ + + /** @param app the application to exit */ + public ExitCommand(ConsoleApplication app) { + super(); + this.app = app; + } + + @Override + public String tip() { + return CLIPrompterMessages.getString(EXIT); + } + + @Override + public void help(String[] args) { + System.out.println("\t" + tip()); //$NON-NLS-1$ + } + + @Override + public void execute(String[] args) { + app.exit(); + } +} + +/**

+ * 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])); + } +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/Command.java b/gclc/src/main/java/fr/bigeon/gclc/command/Command.java new file mode 100644 index 0000000..28f3954 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/command/Command.java @@ -0,0 +1,60 @@ +/* + * 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.Command.java + * Created on: Jul 31, 2014 + */ +package fr.bigeon.gclc.command; + +/** + *

+ * A command to execute. + * + * @author Emmanuel BIGEON + */ +public interface Command { + /** + * @param args the arguments of the command (some expect an empty array) + */ + public void execute(String[] args); + + /** This prints the help associated to this command + * + * @param args the arguments called with the help */ + public void help(String[] args); + + /** @return a tip on the command */ + public String tip(); +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/CommandProvider.java b/gclc/src/main/java/fr/bigeon/gclc/command/CommandProvider.java new file mode 100644 index 0000000..7a014e7 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/command/CommandProvider.java @@ -0,0 +1,78 @@ +/* + * 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.CommandProvider.java + * Created on: Aug 6, 2014 */ +package fr.bigeon.gclc.command; + +import java.util.HashMap; +import java.util.Map; + +/**

+ * A command provider is a map of key word to command to execute + * + * @author Emmanuel BIGEON */ +public class CommandProvider implements ICommandProvider { + /** The commands map */ + protected final Map commands; + /** The error command to be executed when the command isn't recognized */ + protected final Command error; + + /** @param error the error command */ + public CommandProvider(Command error) { + super(); + commands = new HashMap<>(); + this.error = error; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ICommandProvider#get(java.lang.String) */ + @Override + public Command get(String command) { + Command cmd = commands.get(command); + if (cmd == null) return error; + return cmd; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.ICommandProvider#add(java.lang.String, + * fr.bigeon.gclc.command.Command) */ + @Override + public boolean add(String key, Command value) { + if (commands.containsKey(key)) return false; + commands.put(key, value); + return true; + } + +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/HelpExecutor.java b/gclc/src/main/java/fr/bigeon/gclc/command/HelpExecutor.java new file mode 100644 index 0000000..09f3bec --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/command/HelpExecutor.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.command.HelpExecutor.java + * Created on: Sep 6, 2014 + */ +package fr.bigeon.gclc.command; + +import fr.bigeon.gclc.prompt.CLIPrompterMessages; + +/** + *

+ * TODO + * + * @author Emmanuel BIGEON + * + */ +public class HelpExecutor implements Command { + + /** The command to execute the help of */ + private final Command cmd; + + /** @param cmd the command to execute the help of */ + public HelpExecutor(Command cmd) { + super(); + this.cmd = cmd; + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#execute(java.lang.String[]) + */ + @Override + public void execute(String[] args) { + cmd.help(args); + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#help() + */ + @Override + public void help(String[] args) { + cmd.help(args); + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#tip() */ + @Override + public String tip() { + return CLIPrompterMessages.getString("help.cmd.tip"); //$NON-NLS-1$ + } + +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/ICommandProvider.java b/gclc/src/main/java/fr/bigeon/gclc/command/ICommandProvider.java new file mode 100644 index 0000000..058d471 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/command/ICommandProvider.java @@ -0,0 +1,59 @@ +/* + * 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.ICommandProvider.java + * Created on: Sep 6, 2014 */ +package fr.bigeon.gclc.command; + +/**

+ * An ICommadProvider is a provider of commands that can register commands under + * some keywords. + * + * @author Emmanuel BIGEON */ +public interface ICommandProvider { + + /** @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 + * 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); + +} \ No newline at end of file diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/SubedCommand.java b/gclc/src/main/java/fr/bigeon/gclc/command/SubedCommand.java new file mode 100644 index 0000000..6783271 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/command/SubedCommand.java @@ -0,0 +1,128 @@ +/* + * 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.SubedCommand.java + * Created on: Sep 6, 2014 */ +package fr.bigeon.gclc.command; + +import java.util.Arrays; + +/**

+ * TODO + * + * @author Emmanuel BIGEON */ +public class SubedCommand extends CommandProvider implements Command { + + /**

+ * The command to execute when this command is called with no sub arguments. + * This may be null, in which case the command should have arguments. */ + private final Command noArgCommand; + /** A tip on this command. */ + private final String tip; + + /** @param error the error to execute when called with wrong usage */ + public SubedCommand(Command error) { + super(error); + noArgCommand = null; + tip = null; + } + + /** @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); + noArgCommand = null; + this.tip = tip; + } + + /** @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); + this.noArgCommand = noArgCommand; + this.tip = tip; + } + + /** @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); + this.noArgCommand = noArgCommand; + tip = null; + } + + /* (non-Javadoc) + * @see fr.bigeon.acide.Command#execute(java.lang.String[]) */ + @Override + public void execute(String[] args) { + if (args.length == 1) { + if (noArgCommand != null) + noArgCommand.execute(args); + else error.execute(args); + } else { + get(args[1]).execute(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) { + // Specific + get(args[1]).help(Arrays.copyOfRange(args, 1, args.length)); + } 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()); + } + } + } + + /* (non-Javadoc) + * @see fr.bigeon.gclc.command.Command#tip() */ + @Override + public String tip() { + return tip; + } +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/command/package-info.java b/gclc/src/main/java/fr/bigeon/gclc/command/package-info.java new file mode 100644 index 0000000..f1dfae2 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/command/package-info.java @@ -0,0 +1,42 @@ +/* + * 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.package-info.java + * Created on: Sep 6, 2014 */ +/**

+ * TODO + * + * @author Emmanuel BIGEON */ +package fr.bigeon.gclc.command; \ No newline at end of file diff --git a/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java b/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java new file mode 100644 index 0000000..8a89326 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompter.java @@ -0,0 +1,323 @@ +/* + * 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.tool.CLIPrompter.java + * 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; + +/**

+ * The {@link CLIPrompter} class is a utility class that provides method to + * prompt the user. + * + * @author Emmanuel BIGEON */ +public class CLIPrompter { + + @SuppressWarnings("javadoc") + private static final String BOOL_CHOICES = "promptbool.choices"; //$NON-NLS-1$ + @SuppressWarnings("javadoc") + 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; + } + + /**

+ * 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 + * + * @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(); + } + return result; + } + + /** @param message the prompting message + * @return the choice */ + public static boolean promptBoolean(String message) { + String result = prompt(message + + CLIPrompterMessages.getString(BOOL_CHOICES)); + boolean first = true; + String choices = CLIPrompterMessages + .getString("promptbool.choices.yes1") + //$NON-NLS-1$ + ", " + //$NON-NLS-1$ + CLIPrompterMessages + .getString("promptbool.choices.no1"); //$NON-NLS-1$ + while (!(result.equalsIgnoreCase(CLIPrompterMessages + .getString("promptbool.choices.yes1")) || //$NON-NLS-1$ + CLIPrompterMessages + .getString("promptbool.choices.no1").equalsIgnoreCase( //$NON-NLS-1$ + result) || + CLIPrompterMessages + .getString("promptbool.choices.no2").equalsIgnoreCase( //$NON-NLS-1$ + result) || CLIPrompterMessages.getString( + "promptbool.choices.yes2").equalsIgnoreCase(result))) { //$NON-NLS-1$ + if (!first) { + + System.out.println(CLIPrompterMessages.getString( + "promptbool.choices.invalid", choices)); //$NON-NLS-1$ + result = prompt(message + + CLIPrompterMessages.getString(BOOL_CHOICES)); + } + first = false; + } + return result.equalsIgnoreCase(CLIPrompterMessages + .getString("promptbool.choices.yes1")) || //$NON-NLS-1$ + result.equalsIgnoreCase(CLIPrompterMessages + .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 keys, List choices, + String message, String cancel) { + Integer index = promptChoice(keys, message, cancel); + if (index == null) return null; + return choices.get(index); + } + + /** @param The choices labels type + * @param The real choices objects + * @param choices the list of labels (in order to be displayed) + * @param choicesMap the map of label to actual objects + * @param message the prompting message + * @param cancel the cancel option if it exists (null otherwise) + * @return the chosen object */ + @SuppressWarnings("boxing") + public static T promptChoice(List choices, Map choicesMap, + 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 choicesMap.get(choices.get(r)); + } + + /** @param The choices labels type + * @param The real choices objects + * @param choicesMap the map of label to actual objects + * @param message the prompting message + * @param cancel the cancel option (or null) + * @return the chosen object */ + public static T promptChoice(Map choicesMap, String message, + String cancel) { + return promptChoice(new ArrayList<>(choicesMap.keySet()), choicesMap, + message, cancel); + } + + /** @param message the prompt message + * @return the integer */ + public static int promptInteger(String message) { + boolean still = true; + int r = 0; + while (still) { + String result = prompt(message); + try { + if (result.isEmpty()) { + still = true; + continue; + } + r = Integer.parseInt(result); + still = false; + } catch (Exception e) { + still = true; + } + } + return r; + } + + /** This methods prompt the user for a list of elements + * + * @param message the message + * @return the list of user inputs */ + public static List promptList(String message) { + return promptList(message, + CLIPrompterMessages.getString("promptlist.exit.defaultkey")); //$NON-NLS-1$ + } + + /** This methods prompt the user for a list of elements + * + * @param message the message + * @param ender the ending sequence for the list + * @return the list of user inputs */ + public static List promptList(String message, String ender) { + List strings = new ArrayList<>(); + System.out.println(message + + CLIPrompterMessages.getString(LIST_DISP_KEY, ender)); + String res = null; + while (!ender.equals(res)) { + res = CLIPrompter.prompt(CLIPrompterMessages.getString(PROMPT)); + if (!res.equals(ender)) strings.add(res); + } + return strings; + } + + /** Prompt for a text with several lines. + * + * @param message the prompting message + * @return the text */ + public static String promptLongText(String message) { + return promptLongText(message, + CLIPrompterMessages.getString("promptlongtext.exit.defaultkey")); //$NON-NLS-1$ + } + + /** Prompt for a text with several lines. + * + * @param message the prompting message + * @param ender the ender character + * @return the text */ + public static String promptLongText(String message, String ender) { + System.out.println(message + + CLIPrompterMessages.getString( + "promptlongtext.exit.dispkey", ender)); //$NON-NLS-1$ + String res = CLIPrompter.prompt(PROMPT); + String line = res; + while (!line.equals(ender)) { + line = CLIPrompter.prompt(PROMPT); + if (!line.equals(ender)) res += System.lineSeparator() + line; + } + return res.equals(ender) ? "" : res; //$NON-NLS-1$ + } + + /** @param prompt the prompting message + * @param reprompt the prompting message after empty input + * @return the non empty input */ + public static String promptNonEmpty(String prompt, String reprompt) { + String res = prompt(prompt); + while (res.isEmpty()) + res = prompt(reprompt); + return res; + } + + /** Utility class hidden constructor */ + private CLIPrompter() {} +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompterMessages.java b/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompterMessages.java new file mode 100644 index 0000000..a4c1072 --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/prompt/CLIPrompterMessages.java @@ -0,0 +1,82 @@ +/* + * 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.tool.CLIPrompterMessages.java + * Created on: Aug 6, 2014 + */ +package fr.bigeon.gclc.prompt; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + *

+ * Utility class for the messages of the CLIPrompter + * + * @author Emmanuel BIGEON + */ +public class CLIPrompterMessages { + /** + * The resource name + */ + private static final String BUNDLE_NAME = "fr.bigeon.gclc.messages"; //$NON-NLS-1$ + + /** + * The resource + */ + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + /** + * Utility class + */ + private CLIPrompterMessages() {} + + /** + * Return the formatted message corresponding to the given key + * + * @param key the message's key + * @param args the arguments + * @return the formatted message + */ + public static String getString(String key, Object... args) { + try { + return MessageFormat.format(RESOURCE_BUNDLE.getString(key), args); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/gclc/src/main/java/fr/bigeon/gclc/prompt/package-info.java b/gclc/src/main/java/fr/bigeon/gclc/prompt/package-info.java new file mode 100644 index 0000000..754630f --- /dev/null +++ b/gclc/src/main/java/fr/bigeon/gclc/prompt/package-info.java @@ -0,0 +1,41 @@ +/* + * 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.prompt.package-info.java + * Created on: Sep 6, 2014 */ +/**

+ * TODO + * + * @author Emmanuel BIGEON */ +package fr.bigeon.gclc.prompt; \ No newline at end of file diff --git a/gclc/src/main/resources/fr/bigeon/gclc/licensing/cecill/CeCILL-header.txt b/gclc/src/main/resources/fr/bigeon/gclc/licensing/cecill/CeCILL-header.txt new file mode 100644 index 0000000..5c442bf --- /dev/null +++ b/gclc/src/main/resources/fr/bigeon/gclc/licensing/cecill/CeCILL-header.txt @@ -0,0 +1,32 @@ +Copyright ${owner} (${project.inceptionYear}) + +${email} + +This software is a computer program whose purpose is to +${project.description}. + +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. \ No newline at end of file diff --git a/gclc/src/main/resources/fr/bigeon/gclc/messages.properties b/gclc/src/main/resources/fr/bigeon/gclc/messages.properties new file mode 100644 index 0000000..072284d --- /dev/null +++ b/gclc/src/main/resources/fr/bigeon/gclc/messages.properties @@ -0,0 +1,23 @@ +exit.tip=Exit the application +help.cmd.tip=Display an help tip + +prompt.lineprompt=> + +promptlist.exit.defaultkey=\\q +promptlist.exit.dispkey=\ (exit with a new line made of "{0}") +promptlist.prompt=>\ + +promptbool.choices=\ (Y/N) +promptbool.choices.invalid=Invalid input. Please input one of {0}. +promptbool.choices.yes1=Y +promptbool.choices.yes2=yes +promptbool.choices.no1=N +promptbool.choices.no2=no + +promptchoice.outofbounds=Please choose something between {0} and {1}. The choices were: +promptchoice.formaterr=The input seems to be something that is not an integer.\nPlease choose something between {0} and {1}. The choices were: + +promptlongtext.exit.defaultkey=\\q +promptlongtext.exit.dispkey=\ (exit with a new line made of "{0}") + +unrecognized.cmd=Unrecognized command "{0}"