Code compliance huge changes.

* Fixed issues
CliPrompter:
------------
- print list size
- long text line prompt is in CliPromptMessages
- multi chhoice prompt from map gets the currect choice

CommandParameters:
------------------
- Get boolean null pointer exception fixed
- Access to arguments keys.

CommandProvider:
----------------
- Check command name on addition

ConsoleApplication
------------------
- run status update when exiting start()

HelpExecutor
------------
- help content depends on whether the element is a subed command or not

ParametrizedCommand
-------------------
- Check parameter for modification when adding already existing
parameter
- Remove need status for boolean arguments
- Added invalid command exception
- Fail if not interactive and missing needed parameter
- Added getters

PrintUtils
----------
- Remove last empty line in wrap

SystemConsoleManager
--------------------
- Added charset for streams
- Removal of NULL characters from stream

* Added test elements. Use test console manager rather that system one.

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
2016-11-19 17:28:25 -05:00
parent 1a207c8100
commit 5280ee98bd
38 changed files with 4124 additions and 185 deletions

View File

@@ -100,7 +100,7 @@ public class ConsoleApplication implements ICommandProvider {
this.header = welcome;
this.footer = goodbye;
this.manager = manager;
root = new SubedCommand(new String());
root = new SubedCommand(""); //$NON-NLS-1$
}
/** @param manager the manager
@@ -245,6 +245,7 @@ public class ConsoleApplication implements ICommandProvider {
if (footer != null) {
manager.println(footer);
}
running = false;
LOGGER.fine("Exiting application."); //$NON-NLS-1$
} catch (IOException e) {
// The manager was closed
@@ -264,4 +265,14 @@ public class ConsoleApplication implements ICommandProvider {
public SubedCommand getRoot() {
return root;
}
/** @return the header */
public String getHeader() {
return header;
}
/** @return the footer */
public String getFooter() {
return footer;
}
}

View File

@@ -69,6 +69,8 @@ public abstract class Command implements ICommand {
*
*/
private static final String EOL_LINUX = "\n"; //$NON-NLS-1$
/** The empty string constant */
private static final String EMPTY = ""; //$NON-NLS-1$
/** The name of the command */
protected final String name;
@@ -119,7 +121,7 @@ public abstract class Command implements ICommand {
* @return the detailed help (should end with end of line or be empty) */
@SuppressWarnings("static-method")
protected String usageDetail() {
return new String();
return EMPTY;
}
/** <p>

View File

@@ -56,9 +56,9 @@ public class CommandParameters {
*/
private static final int STRINGARG_NUMBER_OF_ELEMENTS = 2;
/** Boolean arguments */
private final Map<String, Boolean> boolArgs = new HashMap<>();
private final Map<String, Boolean> booleanArguments = new HashMap<>();
/** String arguments */
private final Map<String, String> stringArgs = new HashMap<>();
private final Map<String, String> stringArguments = new HashMap<>();
/** Arguments restriction on the named ones */
private final boolean strict;
/** additional (unnamed) parameters */
@@ -71,10 +71,10 @@ public class CommandParameters {
public CommandParameters(Set<String> bools, Set<String> strings,
boolean strict) {
for (final String string : bools) {
boolArgs.put(string, false);
booleanArguments.put(string, false);
}
for (final String string : strings) {
stringArgs.put(string, null);
stringArguments.put(string, null);
}
this.strict = strict;
}
@@ -82,7 +82,7 @@ public class CommandParameters {
/** @param key the key
* @return the associated value, null if it was not specified */
public String get(String key) {
return stringArgs.get(key);
return stringArguments.get(key);
}
/** @return additional non parsed parameters */
@@ -92,9 +92,9 @@ public class CommandParameters {
/** @param key the key
* @return if the key was specified */
@SuppressWarnings("boxing")
public boolean getBool(String key) {
return boolArgs.get(key);
return booleanArguments.containsKey(key) &&
booleanArguments.get(key).booleanValue();
}
/** @param args the arguments to parse
@@ -129,11 +129,11 @@ public class CommandParameters {
return 1;
}
String name = arg.substring(1);
if (boolArgs.containsKey(name)) {
boolArgs.put(name, Boolean.TRUE);
if (booleanArguments.containsKey(name)) {
booleanArguments.put(name, Boolean.TRUE);
return 1;
}
if (stringArgs.containsKey(name)) {
if (stringArguments.containsKey(name)) {
return parseStringArg(name, next);
}
if (strict) {
@@ -152,7 +152,7 @@ public class CommandParameters {
if (next == null) {
return 0;
}
stringArgs.put(name, next);
stringArguments.put(name, next);
return STRINGARG_NUMBER_OF_ELEMENTS;
}
@@ -160,16 +160,26 @@ public class CommandParameters {
* @param value the value */
@SuppressWarnings("boxing")
public void set(String string, boolean value) {
if (boolArgs.containsKey(string)) {
boolArgs.put(string, value);
if (booleanArguments.containsKey(string)) {
booleanArguments.put(string, value);
}
}
/** @param string the key
* @param value the value */
public void set(String string, String value) {
if (stringArgs.containsKey(string)) {
stringArgs.put(string, value);
if (stringArguments.containsKey(string)) {
stringArguments.put(string, value);
}
}
/** @return the boolean arguments */
public Set<String> getBooleanArgumentKeys() {
return booleanArguments.keySet();
}
/** @return the boolean arguments */
public Set<String> getStringArgumentKeys() {
return stringArguments.keySet();
}
}

View File

@@ -67,15 +67,28 @@ public class CommandProvider implements ICommandProvider {
@Override
public boolean add(ICommand value) throws InvalidCommandName {
final String name = value.getCommandName();
if (name == null || name.startsWith(MINUS) || name.contains(SPACE)) {
throw new InvalidCommandName();
}
testCommandName(name);
if (commands.contains(value)) {
return true;
}
for (ICommand iCommand : commands) {
if (iCommand.getCommandName().equals(value.getCommandName())) {
throw new InvalidCommandName(
"Name already used: " + value.getCommandName()); //$NON-NLS-1$
}
}
return commands.add(value);
}
/** @param name the command name
* @throws InvalidCommandName if the name is invalid */
private static void testCommandName(String name) throws InvalidCommandName {
if (name == null || name.isEmpty() || name.startsWith(MINUS) ||
name.contains(SPACE)) {
throw new InvalidCommandName();
}
}
@Override
public void executeSub(String cmd,
String... args) throws CommandRunException {

View File

@@ -87,14 +87,20 @@ public class HelpExecutor extends Command {
* @see fr.bigeon.gclc.command.Command#brief() */
@Override
protected String brief() {
return " A command to get help for other commands"; //$NON-NLS-1$
if (cmd instanceof SubedCommand) {
return " A command to get help for other commands"; //$NON-NLS-1$
}
return " A command to retrieve help for " + cmd.getCommandName(); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.Command#usagePattern() */
@Override
protected String usagePattern() {
return getCommandName() + " <otherCommand>"; //$NON-NLS-1$
if (cmd instanceof SubedCommand) {
return getCommandName() + " <otherCommand>"; //$NON-NLS-1$
}
return getCommandName();
}
/* (non-Javadoc)

View File

@@ -0,0 +1,91 @@
/*
* 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.MockCommand.java
* Created on: Nov 18, 2016
*/
package fr.bigeon.gclc.command;
import java.io.IOException;
import fr.bigeon.gclc.exception.CommandRunException;
import fr.bigeon.gclc.manager.ConsoleManager;
/** This implement a command that does nothing.
* <p>
* This class is intended for testing purpose only.
*
* @author Emmanuel Bigeon */
public final class MockCommand implements ICommand {
/** The command name */
private final String name;
/** @param name the command name */
public MockCommand(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.ICommand#execute(java.lang.String[]) */
@Override
public void execute(String... args) throws CommandRunException {
//
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.ICommand#tip() */
@Override
public String tip() {
return null;
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.ICommand#getCommandName() */
@Override
public String getCommandName() {
return name;
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.ICommand#help(fr.bigeon.gclc.manager.
* ConsoleManager, java.lang.String[]) */
@Override
public void help(ConsoleManager manager,
String... args) throws IOException {
//
}
}

View File

@@ -40,12 +40,17 @@ package fr.bigeon.gclc.command;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import fr.bigeon.gclc.exception.CommandRunException;
import fr.bigeon.gclc.exception.CommandRunExceptionType;
import fr.bigeon.gclc.exception.InvalidParameterException;
import fr.bigeon.gclc.manager.ConsoleManager;
/** <p>
@@ -61,7 +66,7 @@ public abstract class ParametrizedCommand extends Command {
/** The manager */
protected final ConsoleManager manager;
/** The boolean parameters mandatory status */
private final Map<String, Boolean> boolParams = new HashMap<>();
private final Set<String> boolParams = new HashSet<>();
/** The string parameters mandatory status */
private final Map<String, Boolean> stringParams = new HashMap<>();
/** The parameters mandatory status */
@@ -77,6 +82,11 @@ public abstract class ParametrizedCommand extends Command {
this(manager, name, true);
}
/** @param name the name */
public ParametrizedCommand(String name) {
this(null, name, true);
}
/** @param manager the manager
* @param name the name
* @param strict if the arguments are restricted to the declared ones */
@@ -88,26 +98,59 @@ public abstract class ParametrizedCommand extends Command {
this.strict = strict;
}
/** @param name the name
* @param strict if the arguments are restricted to the declared ones */
public ParametrizedCommand(String name, boolean strict) {
this(null, name, strict);
}
/** <p>
* 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) {
* @param stringParameter if the parameter is a parameter with an argument
* @param needed if the parameter is required
* @throws InvalidParameterException if the parameter was invalid */
protected void addParameter(String param, boolean stringParameter,
boolean needed) throws InvalidParameterException {
if (params.containsKey(param)) {
checkParam(param, stringParameter, needed);
return;
}
params.put(param, needed);
if (stringOrBool) {
stringParams.put(param, needed);
if (stringParameter) {
stringParams.put(param, Boolean.valueOf(needed));
params.put(param, Boolean.valueOf(needed));
} else {
if (needed) {
// ERROR the boolean parameters cannot be needed
throw new InvalidParameterException(
"Boolean parameter are present by their very nature. They should not be defined as needed"); //$NON-NLS-1$
}
boolParams.put(param, needed);
boolParams.add(param);
params.put(param, Boolean.valueOf(false));
}
}
/** @param param the parameter
* @param stringParameter the string parameter type
* @param needed if the parameter is needed
* @throws InvalidParameterException if the new definition is invalid */
private void checkParam(String param, boolean stringParameter,
boolean needed) throws InvalidParameterException {
if (stringParameter) {
if (stringParams.containsKey(param)) {
Boolean need = Boolean.valueOf(
needed || stringParams.get(param).booleanValue());
stringParams.put(param, need);
params.put(param, need);
return;
}
throw new InvalidParameterException(
"Parameter is already defined as boolean"); //$NON-NLS-1$
}
if (stringParams.containsKey(param) || needed) {
throw new InvalidParameterException(
"Parameter is already defined as string"); //$NON-NLS-1$
}
}
@@ -120,19 +163,22 @@ public abstract class ParametrizedCommand extends Command {
@Override
public final void execute(String... args) throws CommandRunException {
final CommandParameters parameters = new CommandParameters(
boolParams.keySet(), stringParams.keySet(), strict);
boolParams, stringParams.keySet(), strict);
if (!parameters.parseArgs(args)) {
// ERROR the parameters could not be correctly parsed
// the parameters could not be correctly parsed
throw new CommandRunException(CommandRunExceptionType.USAGE,
"Unable to read arguments", this); //$NON-NLS-1$
}
final List<String> toProvide = new ArrayList<>();
for (final String string : params.keySet()) {
if (params.get(string) && parameters.get(string) == null) {
for (final Entry<String, Boolean> string : params.entrySet()) {
if (string.getValue() && parameters.get(string.getKey()) == null) {
if (!interactive) {
return;
throw new CommandRunException(
CommandRunExceptionType.INTERACTION,
"Missing required parameter " + string.getKey(), //$NON-NLS-1$
this);
}
toProvide.add(string);
toProvide.add(string.getKey());
}
}
// for each needed parameters that is missing, prompt the user.
@@ -160,4 +206,35 @@ public abstract class ParametrizedCommand extends Command {
parameters.set(string, value);
}
}
/** @return the set of boolean parameters */
public Set<String> getBooleanParameters() {
return Collections.unmodifiableSet(boolParams);
}
/** @return the stringParams */
public Set<String> getStringParameters() {
return stringParams.keySet();
}
/** @return the stringParams */
public Set<String> getParameters() {
return params.keySet();
}
/** @param param the parameter name
* @return if the parameter is needed */
public boolean isNeeded(String param) {
return params.containsKey(param) && params.get(param).booleanValue();
}
/** @return the strict */
public boolean isStrict() {
return strict;
}
/** @return the interactive */
public boolean isInteractive() {
return interactive;
}
}

View File

@@ -39,9 +39,10 @@
package fr.bigeon.gclc.command;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
@@ -60,65 +61,50 @@ import fr.bigeon.gclc.exception.CommandRunExceptionType;
* @author Emmanuel Bigeon */
public class ScriptExecution extends Command {
/** The tab character */
private static final String TAB = "\t"; //$NON-NLS-1$
/** the space character */
private static final String SPACE = " "; //$NON-NLS-1$
/** The application */
private final ConsoleApplication application;
/** The commenting prefix */
private final String commentPrefix;
/** The charset for files */
private final Charset charset;
/** @param name the name of the command
* @param application the application
* @param commentPrefix the comment prefix in the script files */
* @param commentPrefix the comment prefix in the script files
* @param charset the charset to use for files */
public ScriptExecution(String name, ConsoleApplication application,
String commentPrefix) {
String commentPrefix, Charset charset) {
super(name);
this.application = application;
this.commentPrefix = commentPrefix;
this.charset = charset;
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.ICommand#execute(java.lang.String[]) */
@SuppressWarnings("resource")
@Override
public void execute(String... args) throws CommandRunException {
if (args.length == 0) {
throw new CommandRunException(CommandRunExceptionType.USAGE,
"Expecting a file", this); //$NON-NLS-1$
}
checkArgs(args);
String scriptFile = args[0];
Object[] params = Arrays.copyOfRange(args, 1, args.length);
try (FileReader fReader = new FileReader(new File(scriptFile));
String[] params = Arrays.copyOfRange(args, 1, args.length);
String cmd;
int lineNo = -1;
try (InputStreamReader fReader = new InputStreamReader(
new FileInputStream(scriptFile), charset);
BufferedReader reader = new BufferedReader(fReader)) {
String cmd;
for (int i = 1; i < args.length; i++) {
params[i - 1] = args[i];
}
int lineNo = -1;
while ((cmd = reader.readLine()) != null) {
lineNo++;
if (cmd.startsWith(" ") || cmd.startsWith("\t")) { //$NON-NLS-1$ //$NON-NLS-2$
reader.close();
fReader.close();
throw new CommandRunException(
"Invalid command in script (line starts with space character)", //$NON-NLS-1$
this);
}
if (cmd.isEmpty() || cmd.startsWith(commentPrefix)) {
String cmdLine = readCommandLine(cmd, params);
if (cmdLine == null) {
continue;
}
String cmdLine = MessageFormat.format(cmd, params);
List<String> ps = GCLCConstants.splitCommand(cmdLine);
String command = ps.remove(0);
try {
application.executeSub(command, ps.toArray(new String[0]));
} catch (CommandRunException e) {
// TODO: handle exception
throw new CommandRunException(
CommandRunExceptionType.EXECUTION,
MessageFormat.format(
"The script could not complete due to command failure at line {0} ({1})",
lineNo, e.getLocalizedMessage()),
e, this);
}
}
} catch (CommandParsingException e) {
throw new CommandRunException("Invalid command in script (" + //$NON-NLS-1$
@@ -127,9 +113,57 @@ public class ScriptExecution extends Command {
} catch (IOException e) {
throw new CommandRunException("Unable to read script", //$NON-NLS-1$
e, this);
} catch (CommandRunException e) {
throw manageRunException(e, lineNo);
}
}
/** @param args the arguments
* @throws CommandRunException if the arguments were not the ones
* expected */
private void checkArgs(String[] args) throws CommandRunException {
if (args.length == 0) {
throw new CommandRunException(CommandRunExceptionType.USAGE,
"Expecting a file", this); //$NON-NLS-1$
}
}
/** This method will create the correct exception. The exception source must
* be this command.
*
* @param e the exception
* @param lineNo the line nu;ber
* @return the exception to actually throw */
private CommandRunException manageRunException(CommandRunException e,
int lineNo) {
if (e.getSource() == this) {
// ensure closing?
return e;
}
return new CommandRunException(CommandRunExceptionType.EXECUTION,
MessageFormat.format(
"The script could not complete due to command failure at line {0} ({1})", //$NON-NLS-1$
Integer.valueOf(lineNo), e.getLocalizedMessage()),
e, this);
}
/** @param cmd the line
* @param params the formatting parameters
* @return the command if it is indeed one, null otherwise
* @throws CommandRunException if the line stqrted with a space character */
private String readCommandLine(String cmd,
Object[] params) throws CommandRunException {
if (cmd.startsWith(SPACE) || cmd.startsWith(TAB)) {
throw new CommandRunException(
"Invalid command in script (line starts with space character)", //$NON-NLS-1$
this);
}
if (cmd.isEmpty() || cmd.startsWith(commentPrefix)) {
return null;
}
return MessageFormat.format(cmd, params);
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.command.Command#usageDetail() */
@Override

View File

@@ -38,13 +38,9 @@
*/
package fr.bigeon.gclc.exception;
/**
* <p>
* TODO
/** The command run exception possible types
*
* @author Emmanuel Bigeon
*
*/
* @author Emmanuel Bigeon */
public enum CommandRunExceptionType {
/** Type of exception due to a wrong usage */
USAGE,

View File

@@ -40,7 +40,7 @@ package fr.bigeon.gclc.exception;
/** <p>
* Exception sent from the application when a command is added but the name of
* the command
* the command is already used
*
* @author Emmanuel BIGEON */
public class InvalidCommandName extends Exception {
@@ -50,4 +50,25 @@ public class InvalidCommandName extends Exception {
*/
private static final long serialVersionUID = 1L;
/** Default constructor */
public InvalidCommandName() {
super();
}
/** @param message the message
* @param cause the cause */
public InvalidCommandName(String message, Throwable cause) {
super(message, cause);
}
/** @param message the message */
public InvalidCommandName(String message) {
super(message);
}
/** @param cause the cause */
public InvalidCommandName(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.InvalidParameterException.java
* Created on: Nov 19, 2016
*/
package fr.bigeon.gclc.exception;
/** This exception is thrown during command definitions to indicate a wrong
* parameter definition.
* <p>
* This class is particularly used by
* {@link fr.bigeon.gclc.command.ParametrizedCommand parameterized commands}.
*
* @author Emmanuel Bigeon */
public class InvalidParameterException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
/** @param message the message
* @param cause the cause */
public InvalidParameterException(String message, Throwable cause) {
super(message, cause);
}
/** @param message the message */
public InvalidParameterException(String message) {
super(message);
}
/** @param cause the cause */
public InvalidParameterException(Throwable cause) {
super(cause);
}
}

View File

@@ -43,6 +43,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -54,12 +55,15 @@ import java.util.logging.Logger;
public class SystemConsoleManager implements ConsoleManager { // NOSONAR
/** The default prompt */
public static final String DEFAULT_PROMPT = ">"; //$NON-NLS-1$
public static final String DEFAULT_PROMPT = "> "; //$NON-NLS-1$
/** The logger */
private static final Logger LOGGER = Logger
.getLogger(SystemConsoleManager.class.getName());
/** The empty string constant */
private static final String EMPTY = ""; //$NON-NLS-1$
/** The command prompt. It can be changed. */
private String prompt = DEFAULT_PROMPT;
@@ -74,15 +78,17 @@ public class SystemConsoleManager implements ConsoleManager { // NOSONAR
/** This default constructor relies on the system defined standart output
* and input stream. */
public SystemConsoleManager() {
this(System.out, System.in);
this(System.out, System.in, Charset.defaultCharset());
}
/** @param out the output stream
* @param in the input stream */
public SystemConsoleManager(PrintStream out, InputStream in) {
* @param in the input stream
* @param charset the charset for the input */
public SystemConsoleManager(PrintStream out, InputStream in,
Charset charset) {
super();
this.out = out;
this.in = new BufferedReader(new InputStreamReader(in));
this.in = new BufferedReader(new InputStreamReader(in, charset));
}
/** @return the prompt */
@@ -95,19 +101,22 @@ public class SystemConsoleManager implements ConsoleManager { // NOSONAR
* @see fr.bigeon.gclc.ConsoleManager#print(java.lang.Object) */
@Override
public void print(String object) throws IOException {
checkOpen();
out.print(object);
}
/** @throws IOException if the stream was closed */
private void checkOpen() throws IOException {
if (closed) {
throw new IOException();
}
out.print(object);
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.ConsoleManager#println() */
@Override
public void println() throws IOException {
if (closed) {
throw new IOException();
}
checkOpen();
out.println();
}
@@ -115,9 +124,7 @@ public class SystemConsoleManager implements ConsoleManager { // NOSONAR
* @see fr.bigeon.gclc.ConsoleManager#println(java.lang.Object) */
@Override
public void println(String object) throws IOException {
if (closed) {
throw new IOException();
}
checkOpen();
out.println(object);
}
@@ -125,20 +132,22 @@ public class SystemConsoleManager implements ConsoleManager { // NOSONAR
* @see fr.bigeon.gclc.ConsoleManager#prompt() */
@Override
public String prompt() throws IOException {
return prompt(new String() + prompt);
return prompt(prompt);
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.ConsoleManager#prompt(java.lang.String) */
@Override
public String prompt(String message) throws IOException {
if (closed) {
throw new IOException();
}
String result = new String();
out.print(message + ' ');
checkOpen();
String result = EMPTY;
out.print(message);
try {
result = in.readLine();
while (result != null && result.length() > 0 &&
result.charAt(0) == 0) {
result = result.substring(1);
}
} catch (final IOException e) {
LOGGER.log(Level.SEVERE, "Unable to read prompt", e); //$NON-NLS-1$
}

View File

@@ -90,9 +90,9 @@ public class CLIPrompter {
manager.println(index++ + ") " + u); //$NON-NLS-1$
}
if (cancel != null) {
manager.println(index + ") " + cancel); //$NON-NLS-1$
manager.println(index++ + ") " + cancel); //$NON-NLS-1$
}
return index;
return index - 1;
}
/** @param manager the manager
@@ -311,10 +311,10 @@ public class CLIPrompter {
String ender) throws IOException {
manager.println(message + CLIPrompterMessages
.getString("promptlongtext.exit.dispkey", ender)); //$NON-NLS-1$
String res = manager.prompt(PROMPT);
String res = manager.prompt(CLIPrompterMessages.getString(PROMPT));
String line = res;
while (!line.equals(ender)) {
line = manager.prompt(PROMPT);
line = manager.prompt(CLIPrompterMessages.getString(PROMPT));
if (!line.equals(ender)) {
res += System.lineSeparator() + line;
}
@@ -356,7 +356,7 @@ public class CLIPrompter {
final List<Integer> chs = promptMultiChoice(manager, choices, message);
final List<T> userChoices = new ArrayList<>();
for (final Integer integer : chs) {
userChoices.add(choicesMap.get(integer));
userChoices.add(choicesMap.get(choices.get(integer.intValue())));
}
return userChoices;
}
@@ -416,7 +416,7 @@ public class CLIPrompter {
}
final int r;
r = Integer.parseInt(val);
if (r >= 0 && r < index) {
if (r >= 0 && r <= index) {
chs.add(Integer.valueOf(r));
return true;
}

View File

@@ -50,6 +50,8 @@ public class PrintUtils {
private static final String CONT_DOT = "..."; //$NON-NLS-1$
/** The continuation dot string length */
private static final int CONT_DOT_LENGTH = CONT_DOT.length();
/** The empty string constant */
private static final String EMPTY = ""; //$NON-NLS-1$
/** Utility class */
private PrintUtils() {
@@ -101,8 +103,9 @@ public class PrintUtils {
toCut = toCut.substring(index + 1);
}
result.add(toCut);
result.add(new String());
result.add(EMPTY);
}
result.remove(result.size() - 1);
return result;
}
}

View File

@@ -1,11 +1,12 @@
exit.tip=Exit the application
help.cmd.tip=Display an help tip
prompt.lineprompt=>
prompt.lineprompt=>\
promptlist.exit.defaultkey=\\q
promptlist.exit.dispkey=\ (exit with a new line made of "{0}")
promptlist.prompt=>\
promptlist.multi.sepkey=\
promptbool.choices=\ (Y/N)
promptbool.choices.invalid=Invalid input. Please input one of {0}.