Update command parameterization mechanics
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
*/
|
||||
package fr.bigeon.gclc;
|
||||
|
||||
import fr.bigeon.gclc.command.ICommandProvider;
|
||||
import fr.bigeon.gclc.exception.InvalidCommandName;
|
||||
|
||||
/** Represent a functionnality set that can be added to a console application.
|
||||
@@ -54,5 +55,5 @@ public interface ApplicationAttachement {
|
||||
* @param application the application
|
||||
* @throws InvalidCommandName if a command name is invalid for the
|
||||
* application. */
|
||||
void attach(ConsoleApplication application) throws InvalidCommandName;
|
||||
void attach(ICommandProvider application) throws InvalidCommandName;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,11 @@ public final class CommandParameters {
|
||||
* @return the number of element read */
|
||||
private int parseArg(final String arg, final String next) {
|
||||
if (!arg.startsWith("-")) { //$NON-NLS-1$
|
||||
return strict ? 0 : 1;
|
||||
if (strict) {
|
||||
return 0;
|
||||
}
|
||||
additional.add(arg);
|
||||
return 1;
|
||||
}
|
||||
final String name = arg.substring(1);
|
||||
if (booleanArguments.containsKey(name)) {
|
||||
|
||||
@@ -39,23 +39,12 @@
|
||||
package fr.bigeon.gclc.command;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
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.CommandParsingException;
|
||||
import fr.bigeon.gclc.exception.CommandRunException;
|
||||
import fr.bigeon.gclc.exception.CommandRunExceptionType;
|
||||
import fr.bigeon.gclc.exception.InvalidParameterException;
|
||||
import fr.bigeon.gclc.manager.ConsoleInput;
|
||||
import fr.bigeon.gclc.manager.ConsoleOutput;
|
||||
import fr.bigeon.gclc.manager.EmptyInput;
|
||||
|
||||
/** A command relying on the {@link CommandParameters} to store parameters
|
||||
* values.
|
||||
@@ -63,15 +52,7 @@ import fr.bigeon.gclc.manager.EmptyInput;
|
||||
* @author Emmanuel BIGEON */
|
||||
public abstract class ParametrizedCommand extends Command {
|
||||
|
||||
/** The boolean parameters mandatory status. */
|
||||
private final Set<String> boolParams = new HashSet<>();
|
||||
/** The string parameters mandatory status. */
|
||||
private final Map<String, Boolean> stringParams = new HashMap<>();
|
||||
/** The parameters mandatory status. */
|
||||
private final Map<String, Boolean> params = new HashMap<>();
|
||||
/** The restriction of provided parameters on execution to declared
|
||||
* paramters in the status maps. */
|
||||
private final boolean strict;
|
||||
private final ParametrizedCommandData data;
|
||||
|
||||
/** Create a parametrized command.
|
||||
* <p>
|
||||
@@ -96,7 +77,7 @@ public abstract class ParametrizedCommand extends Command {
|
||||
* @param strict if the arguments are restricted to the declared ones */
|
||||
public ParametrizedCommand(final String name, final boolean strict) {
|
||||
super(name);
|
||||
this.strict = strict;
|
||||
data = new ParametrizedCommandData(strict);
|
||||
}
|
||||
|
||||
/** Add a boolean parameter to defined parmaters.
|
||||
@@ -105,12 +86,7 @@ public abstract class ParametrizedCommand extends Command {
|
||||
* @throws InvalidParameterException if the parameter is already defined as
|
||||
* a string parameter */
|
||||
protected final void addBooleanParameter(final String flag) throws InvalidParameterException {
|
||||
if (params.containsKey(flag) && stringParams.containsKey(flag)) {
|
||||
throw new InvalidParameterException(
|
||||
"Parameter is already defined as string"); //$NON-NLS-1$
|
||||
}
|
||||
boolParams.add(flag);
|
||||
params.put(flag, Boolean.FALSE);
|
||||
data.addBooleanParameter(flag);
|
||||
}
|
||||
|
||||
/** Add a string parameter to defined parmaters.
|
||||
@@ -121,30 +97,7 @@ public abstract class ParametrizedCommand extends Command {
|
||||
* a boolean parameter */
|
||||
protected final void addStringParameter(final String flag,
|
||||
final boolean needed) throws InvalidParameterException {
|
||||
if (params.containsKey(flag)) {
|
||||
checkParam(flag, needed);
|
||||
return;
|
||||
}
|
||||
stringParams.put(flag, Boolean.valueOf(needed));
|
||||
params.put(flag, Boolean.valueOf(needed));
|
||||
}
|
||||
|
||||
/** Check a parameter.
|
||||
*
|
||||
* @param param the string parameter
|
||||
* @param needed if the parameter is needed
|
||||
* @throws InvalidParameterException if the new definition is invalid */
|
||||
private void checkParam(final String param,
|
||||
final boolean needed) throws InvalidParameterException {
|
||||
if (stringParams.containsKey(param)) {
|
||||
final 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$
|
||||
data.addStringParameter(flag, needed);
|
||||
}
|
||||
|
||||
/** Actually performs the execution after parsing the parameters.
|
||||
@@ -162,59 +115,10 @@ public abstract class ParametrizedCommand extends Command {
|
||||
public final void execute(final ConsoleOutput output,
|
||||
final ConsoleInput input,
|
||||
final String... args) throws CommandRunException {
|
||||
final CommandParameters parameters = new CommandParameters(boolParams,
|
||||
stringParams.keySet(), strict);
|
||||
try {
|
||||
parameters.parseArgs(args);
|
||||
} catch (final CommandParsingException e) {
|
||||
throw new CommandRunException(CommandRunExceptionType.USAGE,
|
||||
"Unable to read arguments", e, this); //$NON-NLS-1$
|
||||
}
|
||||
final List<String> toProvide = new ArrayList<>();
|
||||
for (final Entry<String, Boolean> string : params.entrySet()) {
|
||||
if (string.getValue().booleanValue() &&
|
||||
parameters.get(string.getKey()) == null) {
|
||||
if (input == null || input == EmptyInput.INSTANCE) {
|
||||
throw new CommandRunException(
|
||||
CommandRunExceptionType.INTERACTION,
|
||||
"Missing required parameter " + string.getKey(), //$NON-NLS-1$
|
||||
this);
|
||||
}
|
||||
toProvide.add(string.getKey());
|
||||
}
|
||||
}
|
||||
// for each needed parameters that is missing, prompt the user.
|
||||
fillParameters(input, toProvide, parameters);
|
||||
doExecute(output, input, parameters);
|
||||
}
|
||||
|
||||
/** Fill the undefined parameters.
|
||||
* <p>
|
||||
* This method prompts the user to fill the needed parameters.
|
||||
*
|
||||
* @param input the input to prompt through
|
||||
* @param parameters the parameter list to complete
|
||||
* @param toProvide the parameters to ask for
|
||||
* @throws CommandRunException if the manager was closed */
|
||||
private final void fillParameters(final ConsoleInput input,
|
||||
final List<String> toProvide,
|
||||
final CommandParameters parameters) throws CommandRunException {
|
||||
for (final String string : toProvide) {
|
||||
String value;
|
||||
try {
|
||||
value = input
|
||||
.prompt(MessageFormat.format("value of {0}? ", string)); //$NON-NLS-1$
|
||||
while (value.isEmpty()) {
|
||||
value = input.prompt(MessageFormat.format(
|
||||
"value of {0}? (cannot be empty) ", //$NON-NLS-1$
|
||||
string));
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw new CommandRunException(
|
||||
CommandRunExceptionType.INTERACTION,
|
||||
"Interactive command but manager closed...", e, this); //$NON-NLS-1$
|
||||
}
|
||||
parameters.set(string, value);
|
||||
doExecute(output, input, data.getParameters(input, args));
|
||||
} catch (final IOException e) {
|
||||
throw new CommandRunException("Unable to get parameters", e, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,21 +126,21 @@ public abstract class ParametrizedCommand extends Command {
|
||||
*
|
||||
* @return the set of boolean parameters */
|
||||
public final Set<String> getBooleanParameters() {
|
||||
return Collections.unmodifiableSet(boolParams);
|
||||
return data.getBooleanParameters();
|
||||
}
|
||||
|
||||
/** Retrieve the parameter names.
|
||||
*
|
||||
* @return the stringParams */
|
||||
public final Set<String> getParameters() {
|
||||
return params.keySet();
|
||||
return data.getParameters();
|
||||
}
|
||||
|
||||
/** Get the string parameters names.
|
||||
*
|
||||
* @return the stringParams */
|
||||
public final Set<String> getStringParameters() {
|
||||
return stringParams.keySet();
|
||||
return data.getStringParameters();
|
||||
}
|
||||
|
||||
/** Test if a parameter is needed.
|
||||
@@ -244,13 +148,13 @@ public abstract class ParametrizedCommand extends Command {
|
||||
* @param param the parameter name
|
||||
* @return if the parameter is needed */
|
||||
public final boolean isNeeded(final String param) {
|
||||
return params.containsKey(param) && params.get(param).booleanValue();
|
||||
return data.isNeeded(param);
|
||||
}
|
||||
|
||||
/** If the command refuse unrecognized parameters.
|
||||
*
|
||||
* @return the strict */
|
||||
public final boolean isStrict() {
|
||||
return strict;
|
||||
return data.isStrict();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 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.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
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.CommandParsingException;
|
||||
import fr.bigeon.gclc.exception.InvalidParameterException;
|
||||
import fr.bigeon.gclc.manager.ConsoleInput;
|
||||
import fr.bigeon.gclc.manager.EmptyInput;
|
||||
|
||||
/** An object to handle standardized command parameters.
|
||||
*
|
||||
* @author Emmanuel BIGEON */
|
||||
public final class ParametrizedCommandData {
|
||||
|
||||
/** The boolean parameters mandatory status. */
|
||||
private final Set<String> boolParams = new HashSet<>();
|
||||
/** The string parameters mandatory status. */
|
||||
private final Map<String, Boolean> stringParams = new HashMap<>();
|
||||
/** The parameters mandatory status. */
|
||||
private final Map<String, Boolean> params = new HashMap<>();
|
||||
/** The restriction of provided parameters on execution to declared paramters in
|
||||
* the status maps. */
|
||||
private final boolean strict;
|
||||
|
||||
public ParametrizedCommandData() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public ParametrizedCommandData(final boolean strict) {
|
||||
this.strict = strict;
|
||||
}
|
||||
|
||||
/** Add a boolean parameter to defined parmaters.
|
||||
*
|
||||
* @param flag the boolean flag
|
||||
* @throws InvalidParameterException if the parameter is already defined as a
|
||||
* string parameter */
|
||||
public final void addBooleanParameter(final String flag)
|
||||
throws InvalidParameterException {
|
||||
if (params.containsKey(flag) && stringParams.containsKey(flag)) {
|
||||
throw new InvalidParameterException("Parameter is already defined as string"); //$NON-NLS-1$
|
||||
}
|
||||
boolParams.add(flag);
|
||||
params.put(flag, Boolean.FALSE);
|
||||
}
|
||||
|
||||
/** Add a string parameter to defined parmaters.
|
||||
*
|
||||
* @param flag the parameter flag
|
||||
* @param needed if the parameter's absence should cause an exception
|
||||
* @throws InvalidParameterException if the parameter is already defined as a
|
||||
* boolean parameter */
|
||||
public final void addStringParameter(final String flag, final boolean needed)
|
||||
throws InvalidParameterException {
|
||||
if (params.containsKey(flag)) {
|
||||
checkParam(flag, needed);
|
||||
return;
|
||||
}
|
||||
stringParams.put(flag, Boolean.valueOf(needed));
|
||||
params.put(flag, Boolean.valueOf(needed));
|
||||
}
|
||||
|
||||
/** Check a parameter.
|
||||
*
|
||||
* @param param the string parameter
|
||||
* @param needed if the parameter is needed
|
||||
* @throws InvalidParameterException if the new definition is invalid */
|
||||
private void checkParam(final String param, final boolean needed)
|
||||
throws InvalidParameterException {
|
||||
if (stringParams.containsKey(param)) {
|
||||
final 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$
|
||||
}
|
||||
|
||||
public final CommandParameters getParameters(final ConsoleInput input,
|
||||
final String... args)
|
||||
throws IOException {
|
||||
final CommandParameters parameters = new CommandParameters(boolParams,
|
||||
stringParams.keySet(), strict);
|
||||
try {
|
||||
parameters.parseArgs(args);
|
||||
} catch (final CommandParsingException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
final List<String> toProvide = new ArrayList<>();
|
||||
for (final Entry<String, Boolean> string : params.entrySet()) {
|
||||
if (string.getValue().booleanValue()
|
||||
&& parameters.get(string.getKey()) == null) {
|
||||
if (input == null || input == EmptyInput.INSTANCE) {
|
||||
throw new IOException();
|
||||
}
|
||||
toProvide.add(string.getKey());
|
||||
}
|
||||
}
|
||||
// for each needed parameters that is missing, prompt the user.
|
||||
fillParameters(input, toProvide, parameters);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/** Fill the undefined parameters.
|
||||
* <p>
|
||||
* This method prompts the user to fill the needed parameters.
|
||||
*
|
||||
* @param input the input to prompt through
|
||||
* @param parameters the parameter list to complete
|
||||
* @param toProvide the parameters to ask for
|
||||
* @throws IOException if the manager was closed */
|
||||
private final static void fillParameters(final ConsoleInput input,
|
||||
final List<String> toProvide, final CommandParameters parameters)
|
||||
throws IOException {
|
||||
for (final String string : toProvide) {
|
||||
String value;
|
||||
value = input.prompt(MessageFormat.format("value of {0}? ", string)); //$NON-NLS-1$
|
||||
while (value.isEmpty()) {
|
||||
value = input
|
||||
.prompt(MessageFormat.format("value of {0}? (cannot be empty) ", //$NON-NLS-1$
|
||||
string));
|
||||
}
|
||||
parameters.set(string, value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Retrieve the boolean parameters (aka flags).
|
||||
*
|
||||
* @return the set of boolean parameters */
|
||||
public final Set<String> getBooleanParameters() {
|
||||
return Collections.unmodifiableSet(boolParams);
|
||||
}
|
||||
|
||||
/** Retrieve the parameter names.
|
||||
*
|
||||
* @return the stringParams */
|
||||
public final Set<String> getParameters() {
|
||||
return params.keySet();
|
||||
}
|
||||
|
||||
/** Get the string parameters names.
|
||||
*
|
||||
* @return the stringParams */
|
||||
public final Set<String> getStringParameters() {
|
||||
return stringParams.keySet();
|
||||
}
|
||||
|
||||
/** Test if a parameter is needed.
|
||||
*
|
||||
* @param param the parameter name
|
||||
* @return if the parameter is needed */
|
||||
public final boolean isNeeded(final String param) {
|
||||
return params.containsKey(param) && params.get(param).booleanValue();
|
||||
}
|
||||
|
||||
/** If the command refuse unrecognized parameters.
|
||||
*
|
||||
* @return the strict */
|
||||
public final boolean isStrict() {
|
||||
return strict;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user