summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorCédric Beust <cedric@color.com>2011-10-03 06:53:22 -0700
committerCédric Beust <cedric@color.com>2011-10-03 06:53:22 -0700
commitc709e6db81d11fe4aa6c573775ba5577902aa35c (patch)
tree79edb819f861be7f0da6cc04f5d4e772689cb928 /src/main
parentd2a567ff013254ee00b600d0eb298770d35b089f (diff)
downloadjcommander-c709e6db81d11fe4aa6c573775ba5577902aa35c.tar.gz
Implemented variable arities.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/beust/jcommander/IVariableArity.java16
-rw-r--r--src/main/java/com/beust/jcommander/JCommander.java103
-rw-r--r--src/main/java/com/beust/jcommander/Parameter.java5
3 files changed, 89 insertions, 35 deletions
diff --git a/src/main/java/com/beust/jcommander/IVariableArity.java b/src/main/java/com/beust/jcommander/IVariableArity.java
new file mode 100644
index 0000000..e7499c9
--- /dev/null
+++ b/src/main/java/com/beust/jcommander/IVariableArity.java
@@ -0,0 +1,16 @@
+package com.beust.jcommander;
+
+/**
+ * Must be implemented by argument classes that contain at least one
+ * @Parameter with "variableArity = true".
+ */
+public interface IVariableArity {
+
+ /**
+ * @param optionName the name of the option to process.
+ * @param options the entire list of options.
+ *
+ * @return how many options were processed.
+ */
+ int processVariableArity(String optionName, String[] options);
+}
diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
index 0ae4e85..5735814 100644
--- a/src/main/java/com/beust/jcommander/JCommander.java
+++ b/src/main/java/com/beust/jcommander/JCommander.java
@@ -526,48 +526,28 @@ public class JCommander {
char[] password = readPassword(pd.getDescription());
pd.addValue(new String(password));
} else {
- //
- // Regular option
- //
- Class<?> fieldType = pd.getField().getType();
-
- // Boolean, set to true as soon as we see it, unless it specified
- // an arity of 1, in which case we need to read the next value
- if ((fieldType == boolean.class || fieldType == Boolean.class)
- && pd.getParameter().arity() == -1) {
- pd.addValue("true");
- m_requiredFields.remove(pd.getField());
+ if (pd.getParameter().variableArity()) {
+ //
+ // Variable arity?
+ //
+ i = processVariableArity(args, i, pd);
} else {
- // Regular parameter, use the arity to tell use how many values
- // we need to consume
- int arity = pd.getParameter().arity();
- int n = (arity != -1 ? arity : 1);
-
- // Special case for boolean parameters of arity 0
- if (n == 0 &&
- (Boolean.class.isAssignableFrom(fieldType)
- || boolean.class.isAssignableFrom(fieldType))) {
+ //
+ // Regular option
+ //
+ Class<?> fieldType = pd.getField().getType();
+
+ // Boolean, set to true as soon as we see it, unless it specified
+ // an arity of 1, in which case we need to read the next value
+ if ((fieldType == boolean.class || fieldType == Boolean.class)
+ && pd.getParameter().arity() == -1) {
pd.addValue("true");
m_requiredFields.remove(pd.getField());
- } else if (i < args.length - 1) {
- int offset = "--".equals(args[i + 1]) ? 1 : 0;
-
- if (i + n < args.length) {
- for (int j = 1; j <= n; j++) {
- pd.addValue(trim(args[i + j + offset]));
- m_requiredFields.remove(pd.getField());
- }
- i += n + offset;
- } else {
- throw new ParameterException("Expected " + n + " values after " + arg);
- }
} else {
- throw new ParameterException("Expected a value after parameter " + arg);
+ i = processFixedArity(args, i, pd, fieldType);
}
}
}
- } else {
- throw new ParameterException("Unknown option: " + a);
}
}
else {
@@ -624,6 +604,59 @@ public class JCommander {
}
/**
+ * @return the number of options that were processed.
+ */
+ private int processVariableArity(String[] args, int index, ParameterDescription pd) {
+ Object arg = pd.getObject();
+ if (! (arg instanceof IVariableArity)) {
+ throw new ParameterException("Arg class " + arg.getClass()
+ + " should implement IVariableArity");
+ }
+
+ IVariableArity va = (IVariableArity) arg;
+ List<String> currentArgs = Lists.newArrayList();
+ for (int j = index + 1; j < args.length; j++) {
+ currentArgs.add(args[j]);
+ }
+ int result = va.processVariableArity(pd.getParameter().names()[0],
+ currentArgs.toArray(new String[0]));
+ return result;
+ }
+
+ private int processFixedArity(String[] args, int index, ParameterDescription pd,
+ Class<?> fieldType) {
+ // Regular parameter, use the arity to tell use how many values
+ // we need to consume
+ String arg = args[index];
+ int arity = pd.getParameter().arity();
+ int n = (arity != -1 ? arity : 1);
+
+ // Special case for boolean parameters of arity 0
+ if (n == 0 &&
+ (Boolean.class.isAssignableFrom(fieldType)
+ || boolean.class.isAssignableFrom(fieldType))) {
+ pd.addValue("true");
+ m_requiredFields.remove(pd.getField());
+ } else if (index < args.length - 1) {
+ int offset = "--".equals(args[index + 1]) ? 1 : 0;
+
+ if (index + n < args.length) {
+ for (int j = 1; j <= n; j++) {
+ pd.addValue(trim(args[index + j + offset]));
+ m_requiredFields.remove(pd.getField());
+ }
+ index += n + offset;
+ } else {
+ throw new ParameterException("Expected " + n + " values after " + arg);
+ }
+ } else {
+ throw new ParameterException("Expected a value after parameter " + arg);
+ }
+
+ return index;
+ }
+
+ /**
* Invoke Console.readPassword through reflection to avoid depending
* on Java 6.
*/
diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java
index 7003f5d..c697d2e 100644
--- a/src/main/java/com/beust/jcommander/Parameter.java
+++ b/src/main/java/com/beust/jcommander/Parameter.java
@@ -78,4 +78,9 @@ public @interface Parameter {
* The validation class to use.
*/
Class<? extends IParameterValidator> validateWith() default NoValidator.class;
+
+ /**
+ * @return true if this parameter has a variable arity. See @{IVariableArity}
+ */
+ boolean variableArity() default false;
}