summaryrefslogtreecommitdiff
path: root/src/main/java/com/beust/jcommander/JCommander.java
diff options
context:
space:
mode:
authorjeremysolarz <jeremy.solarz@gmail.com>2017-03-05 16:58:46 +0100
committerjeremysolarz <jeremy.solarz@gmail.com>2017-03-05 16:58:46 +0100
commit8c25c4b2e63cf09f677813c22b380f480d416dbe (patch)
treeda6f76c0862a20a9b8ff4d1ee7b70ddc793a2174 /src/main/java/com/beust/jcommander/JCommander.java
parent277dfcbcf823cc658654e04e7e7fec8ab3808fd1 (diff)
parent4b75f129a2247c8259d2129aa08d8a662af8ca9b (diff)
downloadjcommander-8c25c4b2e63cf09f677813c22b380f480d416dbe.tar.gz
Merge remote-tracking branch 'upstream/master' into dash-dash-dash-dash-dash-dash
Diffstat (limited to 'src/main/java/com/beust/jcommander/JCommander.java')
-rw-r--r--src/main/java/com/beust/jcommander/JCommander.java583
1 files changed, 360 insertions, 223 deletions
diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
index c9c326c..ac28cca 100644
--- a/src/main/java/com/beust/jcommander/JCommander.java
+++ b/src/main/java/com/beust/jcommander/JCommander.java
@@ -18,42 +18,20 @@
package com.beust.jcommander;
+import com.beust.jcommander.FuzzyMap.IKey;
+import com.beust.jcommander.converters.*;
+import com.beust.jcommander.internal.*;
+
import java.io.BufferedReader;
import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
+import java.lang.reflect.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
import java.util.ResourceBundle;
import java.util.concurrent.CopyOnWriteArrayList;
-import com.beust.jcommander.FuzzyMap.IKey;
-import com.beust.jcommander.converters.DefaultListConverter;
-import com.beust.jcommander.converters.EnumConverter;
-import com.beust.jcommander.converters.IParameterSplitter;
-import com.beust.jcommander.converters.NoConverter;
-import com.beust.jcommander.converters.StringConverter;
-import com.beust.jcommander.internal.Console;
-import com.beust.jcommander.internal.DefaultConsole;
-import com.beust.jcommander.internal.DefaultConverterFactory;
-import com.beust.jcommander.internal.JDK6Console;
-import com.beust.jcommander.internal.Lists;
-import com.beust.jcommander.internal.Maps;
-import com.beust.jcommander.internal.Nullable;
-
/**
* The main class for JCommander. It's responsible for parsing the object that contains
* all the annotated fields, parse the command line and assign the fields with the correct
@@ -72,32 +50,32 @@ public class JCommander {
/**
* A map to look up parameter description per option name.
*/
- private Map<IKey, ParameterDescription> m_descriptions;
+ private Map<IKey, ParameterDescription> descriptions;
/**
* The objects that contain fields annotated with @Parameter.
*/
- private List<Object> m_objects = Lists.newArrayList();
+ private List<Object> objects = Lists.newArrayList();
- private boolean m_firstTimeMainParameter = true;
+ private boolean firstTimeMainParameter = true;
/**
* This field/method will contain whatever command line parameter is not an option.
* It is expected to be a List<String>.
*/
- private Parameterized m_mainParameter = null;
+ private Parameterized mainParameter = null;
/**
* The object on which we found the main parameter field.
*/
- private Object m_mainParameterObject;
+ private Object mainParameterObject;
/**
* The annotation found on the main parameter field.
*/
- private Parameter m_mainParameterAnnotation;
+ private Parameter mainParameterAnnotation;
- private ParameterDescription m_mainParameterDescription;
+ private ParameterDescription mainParameterDescription;
/**
* A set of all the parameterizeds that are required. During the reflection phase,
@@ -107,17 +85,17 @@ public class JCommander {
* then some required fields did not receive a value and an exception is
* thrown.
*/
- private Map<Parameterized, ParameterDescription> m_requiredFields = Maps.newHashMap();
+ private Map<Parameterized, ParameterDescription> requiredFields = Maps.newHashMap();
/**
* A map of all the parameterized fields/methods.
*/
- private Map<Parameterized, ParameterDescription> m_fields = Maps.newHashMap();
+ private Map<Parameterized, ParameterDescription> fields = Maps.newHashMap();
/**
* List of commands and their instance.
*/
- private Map<ProgramName, JCommander> m_commands = Maps.newLinkedHashMap();
+ private Map<ProgramName, JCommander> commands = Maps.newLinkedHashMap();
/**
* Alias database for reverse lookup
@@ -127,21 +105,21 @@ public class JCommander {
/**
* The name of the command after the parsing has run.
*/
- private String m_parsedCommand;
+ private String parsedCommand;
/**
* The name of command or alias as it was passed to the
* command line
*/
- private String m_parsedAlias;
+ private String parsedAlias;
- private ProgramName m_programName;
+ private ProgramName programName;
- private boolean m_helpWasSpecified;
+ private boolean helpWasSpecified;
- private List<String> m_unknownArgs = Lists.newArrayList();
+ private List<String> unknownArgs = Lists.newArrayList();
- private static Console m_console;
+ private static Console console;
private final Options options;
@@ -150,32 +128,42 @@ public class JCommander {
*/
private static class Options {
- private ResourceBundle m_bundle;
+ private ResourceBundle bundle;
/**
* A default provider returns default values for the parameters.
*/
- private IDefaultProvider m_defaultProvider;
+ private IDefaultProvider defaultProvider;
- private Comparator<? super ParameterDescription> m_parameterDescriptionComparator
+ private Comparator<? super ParameterDescription> parameterDescriptionComparator
= new Comparator<ParameterDescription>() {
@Override
public int compare(ParameterDescription p0, ParameterDescription p1) {
- return p0.getLongestName().compareTo(p1.getLongestName());
+ Parameter a0 = p0.getParameterAnnotation();
+ Parameter a1 = p1.getParameterAnnotation();
+ if (a0 != null && a0.order() != -1 && a1 != null && a1.order() != -1) {
+ return Integer.compare(a0.order(), a1.order());
+ } else if (a0 != null && a0.order() != -1) {
+ return -1;
+ } else if (a1 != null && a1.order() != -1) {
+ return 1;
+ } else {
+ return p0.getLongestName().compareTo(p1.getLongestName());
+ }
}
};
- private int m_columnSize = 79;
- private boolean m_acceptUnknownOptions = false;
- private boolean m_allowParameterOverwriting = false;
+ private int columnSize = 79;
+ private boolean acceptUnknownOptions = false;
+ private boolean allowParameterOverwriting = false;
private boolean expandAtSign = true;
- private int m_verbose = 0;
- private boolean m_caseSensitiveOptions = true;
- private boolean m_allowAbbreviatedOptions = false;
+ private int verbose = 0;
+ private boolean caseSensitiveOptions = true;
+ private boolean allowAbbreviatedOptions = false;
/**
* The factories used to look up string converters.
*/
- private final List<IStringConverterInstanceFactory> m_converterInstanceFactories = new CopyOnWriteArrayList<>();
- private Charset m_atFileCharset = Charset.defaultCharset();
+ private final List<IStringConverterInstanceFactory> converterInstanceFactories = new CopyOnWriteArrayList<>();
+ private Charset atFileCharset = Charset.defaultCharset();
}
private JCommander(Options options) {
@@ -237,24 +225,24 @@ public class JCommander {
/**
* Disables expanding {@code @file}.
*
- * JCommander supports the {@code @file} syntax, which allows you to put all your options into a file and pass this file as parameter
- * @param expandAtSign whether to expand {@code @file}.
+ * JCommander supports the {@code @file} syntax, which allows you to put all your options
+ * into a file and pass this file as parameter @param expandAtSign whether to expand {@code @file}.
*/
public void setExpandAtSign(boolean expandAtSign) {
options.expandAtSign = expandAtSign;
}
public static Console getConsole() {
- if (m_console == null) {
+ if (console == null) {
try {
Method consoleMethod = System.class.getDeclaredMethod("console");
Object console = consoleMethod.invoke(null);
- m_console = new JDK6Console(console);
+ JCommander.console = new JDK6Console(console);
} catch (Throwable t) {
- m_console = new DefaultConsole();
+ console = new DefaultConsole();
}
}
- return m_console;
+ return console;
}
/**
@@ -270,16 +258,16 @@ public class JCommander {
if (object instanceof Iterable) {
// Iterable
for (Object o : (Iterable<?>) object) {
- m_objects.add(o);
+ objects.add(o);
}
} else if (object.getClass().isArray()) {
// Array
for (Object o : (Object[]) object) {
- m_objects.add(o);
+ objects.add(o);
}
} else {
// Single object
- m_objects.add(object);
+ objects.add(object);
}
}
@@ -289,7 +277,7 @@ public class JCommander {
*/
// declared final since this is invoked from constructors
public final void setDescriptionsBundle(ResourceBundle bundle) {
- options.m_bundle = bundle;
+ options.bundle = bundle;
}
/**
@@ -308,10 +296,10 @@ public class JCommander {
private void parse(boolean validate, String... args) {
StringBuilder sb = new StringBuilder("Parsing \"");
- sb.append(join(args).append("\"\n with:").append(join(m_objects.toArray())));
+ sb.append(join(args).append("\"\n with:").append(join(objects.toArray())));
p(sb.toString());
- if (m_descriptions == null) createDescriptions();
+ if (descriptions == null) createDescriptions();
initializeDefaultValues();
parseValues(expandArgs(args), validate);
if (validate) validateOptions();
@@ -327,12 +315,12 @@ public class JCommander {
}
private void initializeDefaultValues() {
- if (options.m_defaultProvider != null) {
- for (ParameterDescription pd : m_descriptions.values()) {
+ if (options.defaultProvider != null) {
+ for (ParameterDescription pd : descriptions.values()) {
initializeDefaultValue(pd);
}
- for (Map.Entry<ProgramName, JCommander> entry : m_commands.entrySet()) {
+ for (Map.Entry<ProgramName, JCommander> entry : commands.entrySet()) {
entry.getValue().initializeDefaultValues();
}
}
@@ -343,25 +331,25 @@ public class JCommander {
*/
private void validateOptions() {
// No validation if we found a help parameter
- if (m_helpWasSpecified) {
+ if (helpWasSpecified) {
return;
}
- if (!m_requiredFields.isEmpty()) {
+ if (!requiredFields.isEmpty()) {
StringBuilder missingFields = new StringBuilder();
- for (ParameterDescription pd : m_requiredFields.values()) {
+ for (ParameterDescription pd : requiredFields.values()) {
missingFields.append(pd.getNames()).append(" ");
}
throw new ParameterException("The following "
- + pluralize(m_requiredFields.size(), "option is required: ", "options are required: ")
+ + pluralize(requiredFields.size(), "option is required: ", "options are required: ")
+ missingFields);
}
- if (m_mainParameterDescription != null) {
- if (m_mainParameterDescription.getParameter().required() &&
- !m_mainParameterDescription.isAssigned()) {
+ if (mainParameterDescription != null) {
+ if (mainParameterDescription.getParameter().required() &&
+ !mainParameterDescription.isAssigned()) {
throw new ParameterException("Main parameters are required (\""
- + m_mainParameterDescription.getDescription() + "\")");
+ + mainParameterDescription.getDescription() + "\")");
}
}
}
@@ -418,7 +406,7 @@ public class JCommander {
}
private List<String> expandDynamicArg(String arg) {
- for (ParameterDescription pd : m_descriptions.values()) {
+ for (ParameterDescription pd : descriptions.values()) {
if (pd.isDynamicParameter()) {
for (String name : pd.getParameter().names()) {
if (arg.startsWith(name) && !arg.equals(name)) {
@@ -431,13 +419,48 @@ public class JCommander {
return Arrays.asList(arg);
}
- private boolean isOption(String arg) {
- String prefixes = getOptionPrefixes(arg);
- return arg.length() > 0 && prefixes.indexOf(arg.charAt(0)) >= 0;
+ private boolean matchArg(String arg, IKey key) {
+ String kn = options.caseSensitiveOptions
+ ? key.getName()
+ : key.getName().toLowerCase();
+ if (options.allowAbbreviatedOptions) {
+ if (kn.startsWith(arg)) return true;
+ } else {
+ ParameterDescription pd = descriptions.get(key);
+ if (pd != null) {
+ // It's an option. If the option has a separator (e.g. -author==foo) then
+ // we only do a beginsWith match
+ String separator = getSeparatorFor(arg);
+ if (! " ".equals(separator)) {
+ if (arg.startsWith(kn)) return true;
+ } else {
+ if (kn.equals(arg)) return true;
+ }
+ } else {
+ // It's a command do a strict equality check
+ if (kn.equals(arg)) return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isOption(String passedArg) {
+ if (options.acceptUnknownOptions) return true;
+
+ String arg = options.caseSensitiveOptions ? passedArg : passedArg.toLowerCase();
+
+ for (IKey key : descriptions.keySet()) {
+ if (matchArg(arg, key)) return true;
+ }
+ for (IKey key : commands.keySet()) {
+ if (matchArg(arg, key)) return true;
+ }
+
+ return false;
}
private ParameterDescription getPrefixDescriptionFor(String arg) {
- for (Map.Entry<IKey, ParameterDescription> es : m_descriptions.entrySet()) {
+ for (Map.Entry<IKey, ParameterDescription> es : descriptions.entrySet()) {
if (arg.startsWith(es.getKey().getName())) return es.getValue();
}
@@ -464,33 +487,6 @@ public class JCommander {
return " ";
}
- private String getOptionPrefixes(String arg) {
- ParameterDescription pd = getDescriptionFor(arg);
-
- // Could be null if only main parameters were passed
- if (pd != null) {
- Parameters p = pd.getObject().getClass()
- .getAnnotation(Parameters.class);
- if (p != null) return p.optionPrefixes();
- }
- String result = Parameters.DEFAULT_OPTION_PREFIXES;
-
- // See if any of the objects contains a @Parameters(optionPrefixes)
- StringBuilder sb = new StringBuilder();
- for (Object o : m_objects) {
- Parameters p = o.getClass().getAnnotation(Parameters.class);
- if (p != null && !Parameters.DEFAULT_OPTION_PREFIXES.equals(p.optionPrefixes())) {
- sb.append(p.optionPrefixes());
- }
- }
-
- if (!Strings.isStringEmpty(sb.toString())) {
- result = sb.toString();
- }
-
- return result;
- }
-
/**
* Reads the file specified by filename and returns the file content as a string.
* End of lines are replaced by a space.
@@ -501,7 +497,7 @@ public class JCommander {
private List<String> readFile(String fileName) {
List<String> result = Lists.newArrayList();
- try (BufferedReader bufRead = Files.newBufferedReader(Paths.get(fileName), options.m_atFileCharset)) {
+ try (BufferedReader bufRead = Files.newBufferedReader(Paths.get(fileName), options.atFileCharset)) {
String line;
// Read through file one line at time. Print line # and line
while ((line = bufRead.readLine()) != null) {
@@ -532,9 +528,9 @@ public class JCommander {
* Create the ParameterDescriptions for all the \@Parameter found.
*/
private void createDescriptions() {
- m_descriptions = Maps.newHashMap();
+ descriptions = Maps.newHashMap();
- for (Object object : m_objects) {
+ for (Object object : objects) {
addDescription(object);
}
}
@@ -553,27 +549,27 @@ public class JCommander {
Parameter p = annotation;
if (p.names().length == 0) {
p("Found main parameter:" + parameterized);
- if (m_mainParameter != null) {
+ if (mainParameter != null) {
throw new ParameterException("Only one @Parameter with no names attribute is"
- + " allowed, found:" + m_mainParameter + " and " + parameterized);
+ + " allowed, found:" + mainParameter + " and " + parameterized);
}
- m_mainParameter = parameterized;
- m_mainParameterObject = object;
- m_mainParameterAnnotation = p;
- m_mainParameterDescription =
- new ParameterDescription(object, p, parameterized, options.m_bundle, this);
+ mainParameter = parameterized;
+ mainParameterObject = object;
+ mainParameterAnnotation = p;
+ mainParameterDescription =
+ new ParameterDescription(object, p, parameterized, options.bundle, this);
} else {
ParameterDescription pd =
- new ParameterDescription(object, p, parameterized, options.m_bundle, this);
+ new ParameterDescription(object, p, parameterized, options.bundle, this);
for (String name : p.names()) {
- if (m_descriptions.containsKey(new StringKey(name))) {
+ if (descriptions.containsKey(new StringKey(name))) {
throw new ParameterException("Found the option " + name + " multiple times");
}
p("Adding description for " + name);
- m_fields.put(parameterized, pd);
- m_descriptions.put(new StringKey(name), pd);
+ fields.put(parameterized, pd);
+ descriptions.put(new StringKey(name), pd);
- if (p.required()) m_requiredFields.put(parameterized, pd);
+ if (p.required()) requiredFields.put(parameterized, pd);
}
}
} else if (parameterized.getDelegateAnnotation() != null) {
@@ -592,16 +588,16 @@ public class JCommander {
//
DynamicParameter dp = wp.getDynamicParameter();
for (String name : dp.names()) {
- if (m_descriptions.containsKey(name)) {
+ if (descriptions.containsKey(name)) {
throw new ParameterException("Found the option " + name + " multiple times");
}
p("Adding description for " + name);
ParameterDescription pd =
- new ParameterDescription(object, dp, parameterized, options.m_bundle, this);
- m_fields.put(parameterized, pd);
- m_descriptions.put(new StringKey(name), pd);
+ new ParameterDescription(object, dp, parameterized, options.bundle, this);
+ fields.put(parameterized, pd);
+ descriptions.put(new StringKey(name), pd);
- if (dp.required()) m_requiredFields.put(parameterized, pd);
+ if (dp.required()) requiredFields.put(parameterized, pd);
}
}
}
@@ -609,12 +605,12 @@ public class JCommander {
private void initializeDefaultValue(ParameterDescription pd) {
for (String optionName : pd.getParameter().names()) {
- String def = options.m_defaultProvider.getDefaultValueFor(optionName);
+ String def = options.defaultProvider.getDefaultValueFor(optionName);
if (def != null) {
p("Initializing " + optionName + " with default value:" + def);
pd.addValue(def, true /* default */);
// remove the parameter from the list of fields to be required
- m_requiredFields.remove(pd.getParameterized());
+ requiredFields.remove(pd.getParameterized());
return;
}
}
@@ -623,7 +619,7 @@ public class JCommander {
/**
* Main method that parses the values and initializes the fields accordingly.
*/
- private void parseValues(final String[] args, final boolean validate) {
+ private void parseValues(String[] args, boolean validate) {
// This boolean becomes true if we encounter a command, which indicates we need
// to stop parsing (the parsing of the command will be done in a sub JCommander
// object)
@@ -651,7 +647,7 @@ public class JCommander {
//
char[] password = readPassword(pd.getDescription(), pd.getParameter().echoInput());
pd.addValue(new String(password));
- m_requiredFields.remove(pd.getParameterized());
+ requiredFields.remove(pd.getParameterized());
} else {
if (pd.getParameter().variableArity()) {
//
@@ -669,22 +665,22 @@ public class JCommander {
if ((fieldType == boolean.class || fieldType == Boolean.class)
&& pd.getParameter().arity() == -1) {
pd.addValue("true");
- m_requiredFields.remove(pd.getParameterized());
+ requiredFields.remove(pd.getParameterized());
} else {
increment = processFixedArity(args, i, pd, validate, fieldType);
}
// If it's a help option, remember for later
if (pd.isHelp()) {
- m_helpWasSpecified = true;
+ helpWasSpecified = true;
}
}
}
} else {
- if (options.m_acceptUnknownOptions) {
- m_unknownArgs.add(arg);
+ if (options.acceptUnknownOptions) {
+ unknownArgs.add(arg);
i++;
while (i < args.length && !isOption(args[i])) {
- m_unknownArgs.add(args[i++]);
+ unknownArgs.add(args[i++]);
}
increment = 0;
} else {
@@ -698,7 +694,7 @@ public class JCommander {
if ("--".equals(arg) && !isDashDash) {
isDashDash = true;
}
- else if (m_commands.isEmpty()) {
+ else if (commands.isEmpty()) {
//
// Regular (non-command) parsing
//
@@ -706,19 +702,19 @@ public class JCommander {
String value = a; // If there's a non-quoted version, prefer that one
Object convertedValue = value;
- if (m_mainParameter.getGenericType() instanceof ParameterizedType) {
- ParameterizedType p = (ParameterizedType) m_mainParameter.getGenericType();
+ if (mainParameter.getGenericType() instanceof ParameterizedType) {
+ ParameterizedType p = (ParameterizedType) mainParameter.getGenericType();
Type cls = p.getActualTypeArguments()[0];
if (cls instanceof Class) {
- convertedValue = convertValue(m_mainParameter, (Class) cls, null, value);
+ convertedValue = convertValue(mainParameter, (Class) cls, null, value);
}
}
- ParameterDescription.validateParameter(m_mainParameterDescription,
- m_mainParameterAnnotation.validateWith(),
+ ParameterDescription.validateParameter(mainParameterDescription,
+ mainParameterAnnotation.validateWith(),
"Default", value);
- m_mainParameterDescription.setAssigned(true);
+ mainParameterDescription.setAssigned(true);
mp.add(convertedValue);
} else {
//
@@ -727,8 +723,8 @@ public class JCommander {
if (jc == null && validate) {
throw new MissingCommandException("Expected a command, got " + arg, arg);
} else if (jc != null) {
- m_parsedCommand = jc.m_programName.m_name;
- m_parsedAlias = arg; //preserve the original form
+ parsedCommand = jc.programName.name;
+ parsedAlias = arg; //preserve the original form
// Found a valid command, ask it to parse the remainder of the arguments.
// Setting the boolean commandParsed to true will force the current
@@ -741,10 +737,10 @@ public class JCommander {
i += increment;
}
- // Mark the parameter descriptions held in m_fields as assigned
- for (ParameterDescription parameterDescription : m_descriptions.values()) {
+ // Mark the parameter descriptions held in fields as assigned
+ for (ParameterDescription parameterDescription : descriptions.values()) {
if (parameterDescription.isAssigned()) {
- m_fields.get(parameterDescription.getParameterized()).setAssigned(true);
+ fields.get(parameterDescription.getParameterized()).setAssigned(true);
}
}
@@ -806,15 +802,20 @@ public class JCommander {
(Boolean.class.isAssignableFrom(fieldType)
|| boolean.class.isAssignableFrom(fieldType))) {
pd.addValue("true");
- m_requiredFields.remove(pd.getParameterized());
+ requiredFields.remove(pd.getParameterized());
} else if (index < args.length - 1) {
int offset = "--".equals(args[index + 1]) ? 1 : 0;
+ Object finalValue = null;
if (index + arity < args.length) {
for (int j = 1; j <= arity; j++) {
String value = trim(args[index + j + offset]);
- pd.addValue(arg, value, false, validate);
- m_requiredFields.remove(pd.getParameterized());
+ finalValue = pd.addValue(arg, value, false, validate, j - 1);
+ requiredFields.remove(pd.getParameterized());
+ }
+
+ if (finalValue != null && validate) {
+ pd.validateValueParameter(arg, finalValue);
}
index += arity + offset;
} else {
@@ -851,30 +852,30 @@ public class JCommander {
* error message).
*/
private List<?> getMainParameter(String arg) {
- if (m_mainParameter == null) {
+ if (mainParameter == null) {
throw new ParameterException(
- "Was passed main parameter '" + arg + "' but no main parameter was defined");
+ "Was passed main parameter '" + arg + "' but no main parameter was defined in your arg class");
}
- List<?> result = (List<?>) m_mainParameter.get(m_mainParameterObject);
+ List<?> result = (List<?>) mainParameter.get(mainParameterObject);
if (result == null) {
result = Lists.newArrayList();
- if (!List.class.isAssignableFrom(m_mainParameter.getType())) {
- throw new ParameterException("Main parameter field " + m_mainParameter
- + " needs to be of type List, not " + m_mainParameter.getType());
+ if (!List.class.isAssignableFrom(mainParameter.getType())) {
+ throw new ParameterException("Main parameter field " + mainParameter
+ + " needs to be of type List, not " + mainParameter.getType());
}
- m_mainParameter.set(m_mainParameterObject, result);
+ mainParameter.set(mainParameterObject, result);
}
- if (m_firstTimeMainParameter) {
+ if (firstTimeMainParameter) {
result.clear();
- m_firstTimeMainParameter = false;
+ firstTimeMainParameter = false;
}
return result;
}
public String getMainParameterDescription() {
- if (m_descriptions == null) createDescriptions();
- return m_mainParameterAnnotation != null ? m_mainParameterAnnotation.description()
+ if (descriptions == null) createDescriptions();
+ return mainParameterAnnotation != null ? mainParameterAnnotation.description()
: null;
}
@@ -886,13 +887,20 @@ public class JCommander {
}
/**
+ * Get the program name (used only in the usage).
+ */
+ public String getProgramName(){
+ return programName == null ? null : programName.getName();
+ }
+
+ /**
* Set the program name
*
* @param name program name
* @param aliases aliases to the program name
*/
public void setProgramName(String name, String... aliases) {
- m_programName = new ProgramName(name, Arrays.asList(aliases));
+ programName = new ProgramName(name, Arrays.asList(aliases));
}
/**
@@ -944,7 +952,7 @@ public class JCommander {
if (!"".equals(bundleName)) {
bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
} else {
- bundle = options.m_bundle;
+ bundle = options.bundle;
}
if (bundle != null) {
@@ -976,6 +984,134 @@ public class JCommander {
getConsole().println(sb.toString());
}
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ static class Builder {
+ private JCommander jCommander = new JCommander();
+ private String[] args = null;
+
+ public Builder() {
+ }
+
+ /**
+ * Adds the provided arg object to the set of objects that this commander
+ * will parse arguments into.
+ *
+ * @param o The arg object expected to contain {@link Parameter}
+ * annotations. If <code>object</code> is an array or is {@link Iterable},
+ * the child objects will be added instead.
+ */
+ public Builder addObject(Object o) {
+ jCommander.addObject(o);
+ return this;
+ }
+
+ /**
+ * Sets the {@link ResourceBundle} to use for looking up descriptions.
+ * Set this to <code>null</code> to use description text directly.
+ */
+ public Builder resourceBundle(ResourceBundle bundle) {
+ jCommander.setDescriptionsBundle(bundle);
+ return this;
+ }
+
+ public Builder args(String[] args) {
+ this.args = args;
+ return this;
+ }
+
+ /**
+ * Disables expanding {@code @file}.
+ *
+ * JCommander supports the {@code @file} syntax, which allows you to put all your options
+ * into a file and pass this file as parameter @param expandAtSign whether to expand {@code @file}.
+ */
+ public Builder expandAtSign(Boolean expand) {
+ jCommander.setExpandAtSign(expand);
+ return this;
+ }
+
+ /**
+ * Set the program name (used only in the usage).
+ */
+ public Builder programName(String name) {
+ jCommander.setProgramName(name);
+ return this;
+ }
+
+ public Builder columnSize(int columnSize) {
+ jCommander.setColumnSize(columnSize);
+ return this;
+ }
+
+ /**
+ * Define the default provider for this instance.
+ */
+ public Builder defaultProvider(IDefaultProvider provider) {
+ jCommander.setDefaultProvider(provider);
+ return this;
+ }
+
+ /**
+ * Adds a factory to lookup string converters. The added factory is used prior to previously added factories.
+ * @param factory the factory determining string converters
+ */
+ public Builder addConverterFactory(IStringConverterFactory factory) {
+ jCommander.addConverterFactory(factory);
+ return this;
+ }
+
+ public Builder verbose(int verbose) {
+ jCommander.setVerbose(verbose);
+ return this;
+ }
+
+ public Builder allowAbbreviatedOptions(boolean b) {
+ jCommander.setAllowAbbreviatedOptions(b);
+ return this;
+ }
+
+ public Builder acceptUnknownOptions(boolean b) {
+ jCommander.setAcceptUnknownOptions(b);
+ return this;
+ }
+
+ public Builder allowParameterOverwriting(boolean b) {
+ jCommander.setAllowParameterOverwriting(b);
+ return this;
+ }
+
+ public Builder atFileCharset(Charset charset) {
+ jCommander.setAtFileCharset(charset);
+ return this;
+ }
+
+ public Builder addConverterInstanceFactory(IStringConverterInstanceFactory factory) {
+ jCommander.addConverterInstanceFactory(factory);
+ return this;
+ }
+
+ public Builder addCommand(Object command) {
+ jCommander.addCommand(command);
+ return this;
+ }
+
+ public Builder addCommand(String name, Object command, String... aliases) {
+ jCommander.addCommand(name, command, aliases);
+ return this;
+ }
+
+ public JCommander build() {
+ if (args != null) {
+ jCommander.parse(args);
+ }
+ return jCommander;
+ }
+ }
+
+
/**
* Store the help in the passed string builder.
*/
@@ -984,8 +1120,9 @@ public class JCommander {
}
public void usage(StringBuilder out, String indent) {
- if (m_descriptions == null) createDescriptions();
- boolean hasCommands = !m_commands.isEmpty();
+ if (descriptions == null) createDescriptions();
+ boolean hasCommands = !commands.isEmpty();
+ boolean hasOptions = !descriptions.isEmpty();
//indenting
int descriptionIndent = 6;
@@ -994,12 +1131,13 @@ public class JCommander {
//
// First line of the usage
//
- String programName = m_programName != null ? m_programName.getDisplayName() : "<main class>";
+ String programName = this.programName != null ? this.programName.getDisplayName() : "<main class>";
StringBuilder mainLine = new StringBuilder();
- mainLine.append(indent).append("Usage: ").append(programName).append(" [options]");
+ mainLine.append(indent).append("Usage: ").append(programName);
+ if (hasOptions) mainLine.append(" [options]");
if (hasCommands) mainLine.append(indent).append(" [command] [command options]");
- if (m_mainParameterDescription != null) {
- mainLine.append(" ").append(m_mainParameterDescription.getDescription());
+ if (mainParameterDescription != null) {
+ mainLine.append(" ").append(mainParameterDescription.getDescription());
}
wrapDescription(out, indentCount, mainLine.toString());
out.append("\n");
@@ -1009,7 +1147,7 @@ public class JCommander {
//
int longestName = 0;
List<ParameterDescription> sorted = Lists.newArrayList();
- for (ParameterDescription pd : m_fields.values()) {
+ for (ParameterDescription pd : fields.values()) {
if (!pd.getParameter().hidden()) {
sorted.add(pd);
// + to have an extra space between the name and the description
@@ -1062,10 +1200,10 @@ public class JCommander {
// If commands were specified, show them as well
//
if (hasCommands) {
- out.append(" Commands:\n");
+ out.append(indent + " Commands:\n");
// The magic value 3 is the number of spaces between the name of the option
// and its description
- for (Map.Entry<ProgramName, JCommander> commands : m_commands.entrySet()) {
+ for (Map.Entry<ProgramName, JCommander> commands : this.commands.entrySet()) {
Object arg = commands.getValue().getObjects().get(0);
Parameters p = arg.getClass().getAnnotation(Parameters.class);
if (p == null || !p.hidden()) {
@@ -1078,7 +1216,7 @@ public class JCommander {
// Options for this command
JCommander jc = findCommandByAlias(progName.getName());
- jc.usage(out, " ");
+ jc.usage(out, indent + " ");
out.append("\n");
}
}
@@ -1086,19 +1224,19 @@ public class JCommander {
}
private Comparator<? super ParameterDescription> getParameterDescriptionComparator() {
- return options.m_parameterDescriptionComparator;
+ return options.parameterDescriptionComparator;
}
public void setParameterDescriptionComparator(Comparator<? super ParameterDescription> c) {
- options.m_parameterDescriptionComparator = c;
+ options.parameterDescriptionComparator = c;
}
public void setColumnSize(int columnSize) {
- options.m_columnSize = columnSize;
+ options.columnSize = columnSize;
}
public int getColumnSize() {
- return options.m_columnSize;
+ return options.columnSize;
}
/**
@@ -1138,18 +1276,18 @@ public class JCommander {
* format (e.g. HTML).
*/
public List<ParameterDescription> getParameters() {
- return new ArrayList<>(m_fields.values());
+ return new ArrayList<>(fields.values());
}
/**
* @return the main parameter description or null if none is defined.
*/
public ParameterDescription getMainParameter() {
- return m_mainParameterDescription;
+ return mainParameterDescription;
}
private void p(String string) {
- if (options.m_verbose > 0 || System.getProperty(JCommander.DEBUG_PROPERTY) != null) {
+ if (options.verbose > 0 || System.getProperty(JCommander.DEBUG_PROPERTY) != null) {
getConsole().println("[JCommander] " + string);
}
}
@@ -1158,7 +1296,7 @@ public class JCommander {
* Define the default provider for this instance.
*/
public void setDefaultProvider(IDefaultProvider defaultProvider) {
- options.m_defaultProvider = defaultProvider;
+ options.defaultProvider = defaultProvider;
}
/**
@@ -1187,12 +1325,12 @@ public class JCommander {
* Adds a factory to lookup string converters. The added factory is used prior to previously added factories.
* @param converterInstanceFactory the factory generating string converter instances
*/
- public void addConverterInstanceFactory(final IStringConverterInstanceFactory converterInstanceFactory) {
- options.m_converterInstanceFactories.add(0, converterInstanceFactory);
+ public void addConverterInstanceFactory(IStringConverterInstanceFactory converterInstanceFactory) {
+ options.converterInstanceFactories.add(0, converterInstanceFactory);
}
private IStringConverter<?> findConverterInstance(Parameter parameter, Class<?> forType, String optionName) {
- for (IStringConverterInstanceFactory f : options.m_converterInstanceFactories) {
+ for (IStringConverterInstanceFactory f : options.converterInstanceFactories) {
IStringConverter<?> result = f.getConverterInstance(parameter, forType, optionName);
if (result != null) return result;
}
@@ -1307,8 +1445,8 @@ public class JCommander {
jc.addObject(object);
jc.createDescriptions();
jc.setProgramName(name, aliases);
- ProgramName progName = jc.m_programName;
- m_commands.put(progName, jc);
+ ProgramName progName = jc.programName;
+ commands.put(progName, jc);
/*
* Register aliases
@@ -1327,7 +1465,7 @@ public class JCommander {
throw new ParameterException("Cannot set alias " + alias
+ " for " + name
+ " command because it has already been defined for "
- + mappedName.m_name + " command");
+ + mappedName.name + " command");
}
aliasMap.put(alias, progName);
}
@@ -1336,14 +1474,14 @@ public class JCommander {
public Map<String, JCommander> getCommands() {
Map<String, JCommander> res = Maps.newLinkedHashMap();
- for (Map.Entry<ProgramName, JCommander> entry : m_commands.entrySet()) {
- res.put(entry.getKey().m_name, entry.getValue());
+ for (Map.Entry<ProgramName, JCommander> entry : commands.entrySet()) {
+ res.put(entry.getKey().name, entry.getValue());
}
return res;
}
public String getParsedCommand() {
- return m_parsedCommand;
+ return parsedCommand;
}
/**
@@ -1354,7 +1492,7 @@ public class JCommander {
* @return Name of command or alias passed to command line. If none passed: <code>null</code>.
*/
public String getParsedAlias() {
- return m_parsedAlias;
+ return parsedAlias;
}
/**
@@ -1374,22 +1512,22 @@ public class JCommander {
* parsing the command line.
*/
public List<Object> getObjects() {
- return m_objects;
+ return objects;
}
private ParameterDescription findParameterDescription(String arg) {
- return FuzzyMap.findInMap(m_descriptions, new StringKey(arg),
- options.m_caseSensitiveOptions, options.m_allowAbbreviatedOptions);
+ return FuzzyMap.findInMap(descriptions, new StringKey(arg),
+ options.caseSensitiveOptions, options.allowAbbreviatedOptions);
}
private JCommander findCommand(ProgramName name) {
- return FuzzyMap.findInMap(m_commands, name,
- options.m_caseSensitiveOptions, options.m_allowAbbreviatedOptions);
+ return FuzzyMap.findInMap(commands, name,
+ options.caseSensitiveOptions, options.allowAbbreviatedOptions);
}
private ProgramName findProgramName(String name) {
return FuzzyMap.findInMap(aliasMap, new StringKey(name),
- options.m_caseSensitiveOptions, options.m_allowAbbreviatedOptions);
+ options.caseSensitiveOptions, options.allowAbbreviatedOptions);
}
/*
@@ -1413,25 +1551,25 @@ public class JCommander {
* Encapsulation of either a main application or an individual command.
*/
private static final class ProgramName implements IKey {
- private final String m_name;
- private final List<String> m_aliases;
+ private final String name;
+ private final List<String> aliases;
ProgramName(String name, List<String> aliases) {
- m_name = name;
- m_aliases = aliases;
+ this.name = name;
+ this.aliases = aliases;
}
@Override
public String getName() {
- return m_name;
+ return name;
}
private String getDisplayName() {
StringBuilder sb = new StringBuilder();
- sb.append(m_name);
- if (!m_aliases.isEmpty()) {
+ sb.append(name);
+ if (!aliases.isEmpty()) {
sb.append("(");
- Iterator<String> aliasesIt = m_aliases.iterator();
+ Iterator<String> aliasesIt = aliases.iterator();
while (aliasesIt.hasNext()) {
sb.append(aliasesIt.next());
if (aliasesIt.hasNext()) {
@@ -1447,7 +1585,7 @@ public class JCommander {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@@ -1460,10 +1598,10 @@ public class JCommander {
if (getClass() != obj.getClass())
return false;
ProgramName other = (ProgramName) obj;
- if (m_name == null) {
- if (other.m_name != null)
+ if (name == null) {
+ if (other.name != null)
return false;
- } else if (!m_name.equals(other.m_name))
+ } else if (!name.equals(other.name))
return false;
return true;
}
@@ -1480,31 +1618,31 @@ public class JCommander {
}
public void setVerbose(int verbose) {
- options.m_verbose = verbose;
+ options.verbose = verbose;
}
public void setCaseSensitiveOptions(boolean b) {
- options.m_caseSensitiveOptions = b;
+ options.caseSensitiveOptions = b;
}
public void setAllowAbbreviatedOptions(boolean b) {
- options.m_allowAbbreviatedOptions = b;
+ options.allowAbbreviatedOptions = b;
}
public void setAcceptUnknownOptions(boolean b) {
- options.m_acceptUnknownOptions = b;
+ options.acceptUnknownOptions = b;
}
public List<String> getUnknownOptions() {
- return m_unknownArgs;
+ return unknownArgs;
}
public void setAllowParameterOverwriting(boolean b) {
- options.m_allowParameterOverwriting = b;
+ options.allowParameterOverwriting = b;
}
public boolean isParameterOverwritingAllowed() {
- return options.m_allowParameterOverwriting;
+ return options.allowParameterOverwriting;
}
/**
@@ -1512,8 +1650,7 @@ public class JCommander {
* @param charset the charset
*/
public void setAtFileCharset(Charset charset) {
- options.m_atFileCharset = charset;
+ options.atFileCharset = charset;
}
}
-