From e9229f961b3a5799f6798369afe26dec7960249c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Jul 2010 22:42:25 -0700 Subject: Initial commit --- pom.xml | 33 ++++ src/main/java/com/beust/jcommander/JCommander.java | 194 +++++++++++++++++++++ src/main/java/com/beust/jcommander/Lists.java | 20 +++ src/main/java/com/beust/jcommander/Maps.java | 11 ++ src/main/java/com/beust/jcommander/Parameter.java | 15 ++ .../com/beust/jcommander/ParameterDescription.java | 69 ++++++++ .../com/beust/jcommander/ParameterException.java | 9 + src/main/java/com/beust/jcommander/Sets.java | 12 ++ .../java/com/beust/jcommander/JCommanderTest.java | 34 ++++ 9 files changed, 397 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/com/beust/jcommander/JCommander.java create mode 100644 src/main/java/com/beust/jcommander/Lists.java create mode 100644 src/main/java/com/beust/jcommander/Maps.java create mode 100644 src/main/java/com/beust/jcommander/Parameter.java create mode 100644 src/main/java/com/beust/jcommander/ParameterDescription.java create mode 100644 src/main/java/com/beust/jcommander/ParameterException.java create mode 100644 src/main/java/com/beust/jcommander/Sets.java create mode 100644 src/test/java/com/beust/jcommander/JCommanderTest.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9dee1b7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + com.beust + jcommander + jar + 1.0-SNAPSHOT + jcommander + http://maven.apache.org + + [...] + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.1 + + 1.5 + + + + + + + + org.testng + testng + 5.12.1 + test + + + diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java new file mode 100644 index 0000000..9355749 --- /dev/null +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -0,0 +1,194 @@ +package com.beust.jcommander; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +public class JCommander { + private Map m_descriptions; + private Object m_object; + + /** This field will contain whatever command line parameter is not an option. + * It is expected to be a List. + */ + private Field m_mainParameterField; + + public JCommander(Object object) { + m_object = object; + } + + public JCommander(Object object, String[] args) { + m_object = object; + parse(args); + } + + /** + * Parse the command line parameters. + */ + public void parse(String[] args) { + createDescriptions(); + parseValues(expandArgs(args)); + } + + /** + * Expand the command line parameters to take @ parameters into account. + * When @ is encountered, the content of the file that follows is inserted + * in the command line + * @param originalArgv the original command line parameters + * @return the new and enriched command line parameters + */ + private static String[] expandArgs(String[] originalArgv) { + List vResult = Lists.newArrayList(); + + for (String arg : originalArgv) { + + if (arg.startsWith("@")) { + String fileName = arg.substring(1); + vResult.addAll(readFile(fileName)); + } + else { + vResult.add(arg); + } + } + + return vResult.toArray(new String[vResult.size()]); + } + + /** + * Reads the file specified by filename and returns the file content as a string. + * End of lines are replaced by a space + * + * @param fileName the command line filename + * @return the file content as a string. + */ + public static List readFile(String fileName) { + List result = Lists.newArrayList(); + + try { + BufferedReader bufRead = new BufferedReader(new FileReader(fileName)); + + String line; + + // Read through file one line at time. Print line # and line + while ((line = bufRead.readLine()) != null) { + result.add(line); + } + + bufRead.close(); + } + catch (IOException e) { + throw new ParameterException("Could not read file " + fileName + ": " + e); + } + + return result; + } + + /** + * @param string + * @return + */ + private static String trim(String string) { + String result = string.trim(); + if (result.startsWith("\"")) { + if (result.endsWith("\"")) { + return result.substring(1, result.length() - 1); + } else { + return result.substring(1); + } + } else { + return result; + } + } + + private void createDescriptions() { + m_descriptions = Maps.newHashMap(); + Class cls = m_object.getClass(); + for (Field f : cls.getDeclaredFields()) { + p("Field:" + f.getName()); + f.setAccessible(true); + Annotation annotation = f.getAnnotation(Parameter.class); + if (annotation != null) { + Parameter p = (Parameter) annotation; + if (p.names().length == 0) { + p("Found main parameter:" + f); + m_mainParameterField = f; + } else { + for (String name : p.names()) { + p("Adding description for " + name); + ParameterDescription pd = new ParameterDescription(m_object, p, f); + m_descriptions.put(name, pd); + } + } + } + } + } + + private void p(String string) { + if (false) { + System.out.println("[JCommander] " + string); + } + } + + private void parseValues(String[] args) { + for (int i = 0; i < args.length; i++) { + String a = trim(args[i]); + if (a.startsWith("-")) { + ParameterDescription pd = m_descriptions.get(a); + if (pd != null) { + Class fieldType = pd.getField().getType(); + if (fieldType == boolean.class || fieldType == Boolean.class) { + pd.addValue(Boolean.TRUE); + } else if (i + 1 < args.length) { + pd.addValue(trim(args[i + 1])); + i++; + } else { + throw new ParameterException("Parameter expected after " + args[i]); + } + } else { + throw new ParameterException("Unknown option: " + a); + } + } + else { + if (! isStringEmpty(args[i])) getMainParameter().add(args[i]); + } + } + } + + private static boolean isStringEmpty(String s) { + return s == null || "".equals(s); + } + + private List getMainParameter() { + if (m_mainParameterField == null) { + throw new ParameterException( + "Non option parameters were found but no main parameter was defined"); + } + + try { + List result = (List) m_mainParameterField.get(m_object); + if (result == null) { + result = Lists.newArrayList(); + m_mainParameterField.set(m_object, result); + } + return result; + } + catch(IllegalAccessException ex) { + throw new ParameterException("Couldn't access main parameter: " + ex.getMessage()); + } + } + + public void usage() { + System.out.println("Usage:"); + for (ParameterDescription pd : m_descriptions.values()) { + StringBuilder sb = new StringBuilder(); + for (String n : pd.getNames()) { + sb.append(n).append(" "); + } + System.out.println("\t" + sb.toString() + "\t" + pd.getDescription()); + } + } +} diff --git a/src/main/java/com/beust/jcommander/Lists.java b/src/main/java/com/beust/jcommander/Lists.java new file mode 100644 index 0000000..5794beb --- /dev/null +++ b/src/main/java/com/beust/jcommander/Lists.java @@ -0,0 +1,20 @@ +package com.beust.jcommander; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Lists { + + public static List newArrayList() { + return new ArrayList(); + } + + public static List newArrayList(Collection c) { + return new ArrayList(c); + } + + public static List newArrayList(int size) { + return new ArrayList(size); + } +} diff --git a/src/main/java/com/beust/jcommander/Maps.java b/src/main/java/com/beust/jcommander/Maps.java new file mode 100644 index 0000000..1442e85 --- /dev/null +++ b/src/main/java/com/beust/jcommander/Maps.java @@ -0,0 +1,11 @@ +package com.beust.jcommander; + +import java.util.HashMap; +import java.util.Map; + +public class Maps { + + public static Map newHashMap() { + return new HashMap(); + } +} diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java new file mode 100644 index 0000000..9e6bc6a --- /dev/null +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -0,0 +1,15 @@ +package com.beust.jcommander; + +import static java.lang.annotation.ElementType.FIELD; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@Target({ FIELD }) +public @interface Parameter { + + String[] names() default {}; + + String description() default ""; +} diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java new file mode 100644 index 0000000..e44c0cb --- /dev/null +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -0,0 +1,69 @@ +package com.beust.jcommander; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Set; + +public class ParameterDescription { + private Object m_object; + private Parameter m_parameterAnnotation; + private Field m_field; + /** Keep track of whether a value was added to flag an error */ + private boolean m_added = false; + + public ParameterDescription(Object object, Parameter annotation, Field field) { + m_object = object; + m_parameterAnnotation = annotation; + m_field = field; + } + + public String[] getNames() { + return m_parameterAnnotation.names(); + } + + public String getDescription() { + return m_parameterAnnotation.description(); + } + + public Field getField() { + return m_field; + } + + private boolean isMultiOption() { + Class fieldType = m_field.getType(); + return fieldType.equals(List.class) || fieldType.equals(Set.class); + } + + public void addValue(Object value) { + if (m_added && ! isMultiOption()) { + throw new ParameterException("Can only specify option " + getNames()[0] + " once."); + } + + m_added = true; + try { + Class fieldType = m_field.getType(); + if (fieldType.equals(String.class)) { + m_field.set(m_object, value); + } else if (fieldType.equals(int.class) || fieldType.equals(Integer.class)) { + m_field.set(m_object, Integer.parseInt(value.toString())); + } else if (fieldType.equals(long.class) || fieldType.equals(Long.class)) { + m_field.set(m_object, Long.parseLong(value.toString())); + } else if (fieldType.equals(float.class) || fieldType.equals(Float.class)) { + m_field.set(m_object, Float.parseFloat(value.toString())); + } else if (fieldType.equals(Boolean.class) || fieldType.equals(boolean.class)) { + m_field.set(m_object, value); + } else if (isMultiOption()) { + List l = (List) m_field.get(m_object); + if (l == null) { + l = Lists.newArrayList(); + m_field.set(m_object, l); + } + l.add(value); + } + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/beust/jcommander/ParameterException.java b/src/main/java/com/beust/jcommander/ParameterException.java new file mode 100644 index 0000000..5004cd0 --- /dev/null +++ b/src/main/java/com/beust/jcommander/ParameterException.java @@ -0,0 +1,9 @@ +package com.beust.jcommander; + +public class ParameterException extends RuntimeException { + + public ParameterException(String string) { + super(string); + } + +} diff --git a/src/main/java/com/beust/jcommander/Sets.java b/src/main/java/com/beust/jcommander/Sets.java new file mode 100644 index 0000000..5e7c3ef --- /dev/null +++ b/src/main/java/com/beust/jcommander/Sets.java @@ -0,0 +1,12 @@ +package com.beust.jcommander; + +import java.util.HashSet; +import java.util.Set; + +public class Sets { + + public static Set newHashSet() { + return new HashSet(); + } + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java new file mode 100644 index 0000000..b525d98 --- /dev/null +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -0,0 +1,34 @@ +package com.beust.jcommander; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.testng.collections.Lists; + +import java.util.Arrays; +import java.util.List; + +public class JCommanderTest { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + + @Test + public void simpleArgs() { + JCommanderTest jct = new JCommanderTest(); + String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; + new JCommander(jct, argv); + + System.out.println("Verbose:" + verbose); + Assert.assertEquals(jct.verbose.intValue(), 2); + Assert.assertEquals(jct.groups, "unit"); + Assert.assertEquals(jct.parameters, Arrays.asList("a", "b", "c")); + } +} -- cgit v1.2.3 From 2cc20ebc6936088320419f24f4dc0c9b27703232 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Jul 2010 22:45:52 -0700 Subject: README --- README | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000..6c9457b --- /dev/null +++ b/README @@ -0,0 +1,6 @@ +JCommander +========== + +This is an annotation based parameter parsing framework for Java. + +The doc will soon be available at http://beust.com/jcommander -- cgit v1.2.3 From 2af17241e2c6c6ba67dcd0e79bee54db686b234c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Jul 2010 22:47:14 -0700 Subject: Markup --- README | 6 ------ README.markup | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 README create mode 100644 README.markup diff --git a/README b/README deleted file mode 100644 index 6c9457b..0000000 --- a/README +++ /dev/null @@ -1,6 +0,0 @@ -JCommander -========== - -This is an annotation based parameter parsing framework for Java. - -The doc will soon be available at http://beust.com/jcommander diff --git a/README.markup b/README.markup new file mode 100644 index 0000000..6c9457b --- /dev/null +++ b/README.markup @@ -0,0 +1,6 @@ +JCommander +========== + +This is an annotation based parameter parsing framework for Java. + +The doc will soon be available at http://beust.com/jcommander -- cgit v1.2.3 From b17e7bd20e319f37707467ada8bc3422aadb0980 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Jul 2010 22:47:42 -0700 Subject: Markdown --- README.markdown | 6 ++++++ README.markup | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 README.markdown delete mode 100644 README.markup diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..6c9457b --- /dev/null +++ b/README.markdown @@ -0,0 +1,6 @@ +JCommander +========== + +This is an annotation based parameter parsing framework for Java. + +The doc will soon be available at http://beust.com/jcommander diff --git a/README.markup b/README.markup deleted file mode 100644 index 6c9457b..0000000 --- a/README.markup +++ /dev/null @@ -1,6 +0,0 @@ -JCommander -========== - -This is an annotation based parameter parsing framework for Java. - -The doc will soon be available at http://beust.com/jcommander -- cgit v1.2.3 From 01b687efba6b24edbfdd038a683fda500e0295da Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Jul 2010 22:52:28 -0700 Subject: README with example --- README.markdown | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 6c9457b..0395a87 100644 --- a/README.markdown +++ b/README.markdown @@ -3,4 +3,29 @@ JCommander This is an annotation based parameter parsing framework for Java. -The doc will soon be available at http://beust.com/jcommander +Here is a quick example: + + public class JCommanderTest { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + } + +and how you use it: + + JCommanderTest jct = new JCommanderTest(); + String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; + new JCommander(jct, argv); + + Assert.assertEquals(jct.verbose.intValue(), 2); +} + +The full doc will soon be available at http://beust.com/jcommander -- cgit v1.2.3 From b3fb6bd0620fea19a7462d1dd748f79d9238d6f3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Jul 2010 22:52:54 -0700 Subject: README with example --- README.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/README.markdown b/README.markdown index 0395a87..2ca37ce 100644 --- a/README.markdown +++ b/README.markdown @@ -26,6 +26,5 @@ and how you use it: new JCommander(jct, argv); Assert.assertEquals(jct.verbose.intValue(), 2); -} The full doc will soon be available at http://beust.com/jcommander -- cgit v1.2.3 From 159a3074eff6581d9192a812915c042e551e3785 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 07:06:22 -0700 Subject: Documentation --- doc/index.html | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 doc/index.html diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..f619eff --- /dev/null +++ b/doc/index.html @@ -0,0 +1,214 @@ + + +JCommander + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

JCommander

+

Because life is too short to parse command line parameters

+
+ Created: July 13th, 2010 +
Cédric Beust
+ +

+Overview +

+ +JCommander is a very small Java framework that makes it trivial to parse command line parameters. +

+You annotate fields with descriptions of your options: + +

+import com.beust.jcommander.Parameter;
+
+public class JCommanderTest {
+  @Parameter
+  public List<String> parameters = Lists.newArrayList();
+
+  @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
+  public Integer verbose = 1;
+
+  @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
+  public String groups;
+
+  @Parameter(names = "-debug", description = "Debug mode")
+  public boolean debug = false;
+}
+
+ +and then you simply ask JCommander to parse: + +
+JCommanderTest jct = new JCommanderTest();
+String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" };
+new JCommander(jct, argv);
+
+Assert.assertEquals(jct.verbose.intValue(), 2);
+
+ +

+Types of options +

+ +JCommander supports many types of options. + +

Boolean

+ +When a Parameter annotation is found on a field of type boolean or Boolean, JCommander interprets it as an option with an arity of 0: + +
+@Parameter(names = "-debug", description = "Debug mode")
+public boolean debug = false;
+
+ +Such a parameter does not require any additional parameter on the command line and if it's detected during parsing, the corresponding field will be set to true. + +

String, Integer, Long

+ +When a Parameter annotation is found on a field of type String, Integer, int, Long or long, JCommander will parse the following parameter and it will attempt to cast it to the right type: + + +
+@Parameter(names = "-log", description = "Level of verbosity")
+public Integer verbose = 1;
+
+ +
+java Main -log 3
+
+ +will cause the field verbose to receive the value 3, however: + +
+java Main -log test
+
+ +will cause an exception to be thrown. + +

Lists

+ +When a Parameter annotation is found on a field of type List, JCommander will interpret it as an option that can happen multiple times: + +
+@Parameter(names = "-hosts", description = "Level of verbosity")
+public List<String> hosts = new ArrayList<String>();
+
+ +will allow you to parse the following command line: + +
+java Mail -host host1 -verbose -host host2
+
+ +When JCommander is done parsing the line above, the field hosts will contain the strings "host1" and "host2". + +

Main parameter

+So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a List<String> and it will contain all the parameters that are not options: + +
+@Parameter(description = "Files")
+public List<String> files = new ArrayList<String>();
+
+@Parameter(names = "-debug", description = "Debugging level")
+public Integer verbose = 1;
+
+ +will allow you to parse: + +
+java Main -debug file1 file2
+
+ +and the field files will receive the strings "file1" and "file2". + +

@ syntax

+ +JCommander supports the @ syntax, which allows you to put all your options into a file and pass this file as parameter: + +

+ +

/tmp/parameters

+
+-verbose
+file1
+file2
+file3
+
+
+java Main @/tmp/parameters
+
+ +

Multiple option names

+ +You can specify more than one option name: + +
+
+  @Parameter(names = { "-d", "--outputDirectory" }, description = "Directory")
+  public String outputDirectory;
+
+
+ +will allow both following syntaxes: + +
+java Main -d /tmp
+java Main --outputDirectory /tmp
+
+ + + +

More examples

+ +TestNG uses JCommander to parse its command line, here is its definition file. + +

Download

+ +You can download JCommander from the following locations: + + + +

TODO

+ +Some of the features I am considering adding: + +
    +
  • Support for arities >= 2 (syntaxes such as java Main -pair pair1 pair2)
  • . +
  • Type converters, to enable fields to have any type. +
+ + + + + -- cgit v1.2.3 From bb96cc8b3a254eb26d0f2a3fc582cf1d1b42c2aa Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 07:12:41 -0700 Subject: More doc --- README.markdown | 2 +- doc/index.html | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 2ca37ce..ade1ab9 100644 --- a/README.markdown +++ b/README.markdown @@ -27,4 +27,4 @@ and how you use it: Assert.assertEquals(jct.verbose.intValue(), 2); -The full doc will soon be available at http://beust.com/jcommander +The full doc is available at http://beust.com/jcommander diff --git a/doc/index.html b/doc/index.html index f619eff..6cce47c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -125,7 +125,7 @@ public List<String> hosts = new ArrayList<String>(); will allow you to parse the following command line:
-java Mail -host host1 -verbose -host host2
+java Main -host host1 -verbose -host host2
 
When JCommander is done parsing the line above, the field hosts will contain the strings "host1" and "host2". @@ -184,6 +184,17 @@ java Main -d /tmp java Main --outputDirectory /tmp +

Usage

+ +You can invoke usage() on the JCommander instance that you used to parse your command line in order to generate a summary of all the options that your program understands: + +
+Usage:
+	-port			The port number
+	-debug			Debug mode
+	-src, --sources The source directory
+	-testclass		List of classes
+

More examples

@@ -206,6 +217,7 @@ Some of the features I am considering adding:
  • Support for arities >= 2 (syntaxes such as java Main -pair pair1 pair2)
  • .
  • Type converters, to enable fields to have any type. +
  • HTML generation for usage().
-- cgit v1.2.3 From 91cfc8dee74b900cb2e5434307bdc911790d86df Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 07:14:44 -0700 Subject: Doc --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 6cce47c..d08a06b 100644 --- a/doc/index.html +++ b/doc/index.html @@ -206,7 +206,7 @@ TestNG uses JCommander to parse its command line, here is Binary +
  • Binary
  • Source on github
  • -- cgit v1.2.3 From d704612f58c0ba423a08aa55b9ccfa1454533fdc Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 13 Jul 2010 16:39:56 +0200 Subject: Fix pom.xml --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9dee1b7..34e78e6 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,6 @@ jcommander http://maven.apache.org - [...] -- cgit v1.2.3 From b34da0757f631ef33a6bbcb197b42f6c3d4b09a3 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 13 Jul 2010 16:39:49 +0200 Subject: Ignore target folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1de5659 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file -- cgit v1.2.3 From e5253ad5d92cb76c34db05f67185b82612a165f0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 07:46:28 -0700 Subject: Fixed pom.xml --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9dee1b7..34e78e6 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,6 @@ jcommander http://maven.apache.org - [...] -- cgit v1.2.3 From 07a7aad62b951b805eaf09b1e24c4b37363eaf2d Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 13 Jul 2010 17:01:55 +0200 Subject: Ignore eclipse files --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1de5659..387cacf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -target \ No newline at end of file +target +.classpath +.project +.settings \ No newline at end of file -- cgit v1.2.3 From 5a3441b747c98f5b32e58b5a64fcb02fed5836fe Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 13 Jul 2010 17:03:10 +0200 Subject: Accept arguments as varargs --- src/main/java/com/beust/jcommander/JCommander.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 9355749..88e5225 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -21,7 +21,7 @@ public class JCommander { m_object = object; } - public JCommander(Object object, String[] args) { + public JCommander(Object object, String... args) { m_object = object; parse(args); } @@ -29,7 +29,7 @@ public class JCommander { /** * Parse the command line parameters. */ - public void parse(String[] args) { + public void parse(String... args) { createDescriptions(); parseValues(expandArgs(args)); } -- cgit v1.2.3 From 9b61b415283ee11c5cdcbfa6dbe22301c437235d Mon Sep 17 00:00:00 2001 From: David Gageot Date: Tue, 13 Jul 2010 17:07:16 +0200 Subject: Attach sources --- pom.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pom.xml b/pom.xml index 34e78e6..f2888ca 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,19 @@ + + org.apache.maven.plugins + maven-source-plugin + 2.1.1 + + + attach-sources + + jar + + + + org.apache.maven.plugins maven-compiler-plugin -- cgit v1.2.3 From f2566adab5ec5a0778d3b73173d6e8cc850ac310 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 12:29:53 -0700 Subject: Updated pom with license and other things --- pom.xml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pom.xml b/pom.xml index f2888ca..f0be034 100644 --- a/pom.xml +++ b/pom.xml @@ -5,11 +5,23 @@ jcommander jar 1.0-SNAPSHOT + A Java framework to parse command line options with annotations. jcommander http://maven.apache.org + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + http://github.com/cbeust/jcommander + + org.apache.maven.plugins maven-source-plugin @@ -23,6 +35,7 @@ + org.apache.maven.plugins maven-compiler-plugin @@ -31,6 +44,21 @@ 1.5 + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + -- cgit v1.2.3 From 9cf556fb35638b7f8d90581da50e377cae52a2c3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 12:32:06 -0700 Subject: Added a tag for bundle creation --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index f0be034..bb884e6 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ http://github.com/cbeust/jcommander + http://github.com/cbeust/jcommander -- cgit v1.2.3 From 0115dc31f82df171e507e20061f5114b1cf6351a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 14:55:32 -0700 Subject: Updated TODO --- doc/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index d08a06b..37b7254 100644 --- a/doc/index.html +++ b/doc/index.html @@ -215,9 +215,10 @@ You can download JCommander from the following locations: Some of the features I am considering adding:
      -
    • Support for arities >= 2 (syntaxes such as java Main -pair pair1 pair2)
    • . +
    • Support for arities >= 2 (syntaxes such as java Main -pair pair1 pair2).
    • Type converters, to enable fields to have any type.
    • HTML generation for usage(). +
    • Internationalization (bundles).
    -- cgit v1.2.3 From 696418a94157048544c44f405d757ede86eec926 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 20:28:54 -0700 Subject: Fixed a bug that showed duplicate lines in usage() --- src/main/java/com/beust/jcommander/JCommander.java | 46 ++++++++++++++++++++-- .../java/com/beust/jcommander/JCommanderTest.java | 16 ++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 88e5225..f048906 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -5,18 +5,40 @@ import java.io.FileReader; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.Collection; import java.util.List; import java.util.Map; +/** + * 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 + * values and a few other helper methods, such as usage(). + * + * @author cbeust + * + */ public class JCommander { + /** + * A map to look up parameter description per option name. + */ private Map m_descriptions; + + /** + * The object that contains the fields annotated with @Parameter. + */ private Object m_object; - /** This field will contain whatever command line parameter is not an option. + /** + * This field will contain whatever command line parameter is not an option. * It is expected to be a List. */ private Field m_mainParameterField; + /** + * A map of all the fields that describe an option. + */ + private Map m_fields = Maps.newHashMap(); + public JCommander(Object object) { m_object = object; } @@ -113,6 +135,9 @@ public class JCommander { Annotation annotation = f.getAnnotation(Parameter.class); if (annotation != null) { Parameter p = (Parameter) annotation; + if (p.names().length > 0) { + m_fields.put(f, p); + } if (p.names().length == 0) { p("Found main parameter:" + f); m_mainParameterField = f; @@ -181,14 +206,27 @@ public class JCommander { } } + /** + * Display a the help on System.out. + */ public void usage() { System.out.println("Usage:"); - for (ParameterDescription pd : m_descriptions.values()) { + for (Parameter p : m_fields.values()) { StringBuilder sb = new StringBuilder(); - for (String n : pd.getNames()) { + for (String n : p.names()) { sb.append(n).append(" "); } - System.out.println("\t" + sb.toString() + "\t" + pd.getDescription()); + System.out.println("\t" + sb.toString() + "\t" + p.description()); } } + + /** + * @return a Collection of all the @Parameter annotations found on the + * target class. This can be used to display the usage() in a different + * format (e.g. HTML). + */ + public Collection getParameters() { + return m_fields.values(); + } } + diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index b525d98..9e170f7 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -31,4 +31,20 @@ public class JCommanderTest { Assert.assertEquals(jct.groups, "unit"); Assert.assertEquals(jct.parameters, Arrays.asList("a", "b", "c")); } + + /** + * Make sure that if there are args with multiple names (e.g. "-log" and "-verbose"), + * the usage will only display it once. + */ + @Test + public void repeatedArgs() { + JCommanderTest jct = new JCommanderTest(); + String[] argv = { "-log", "2" }; + JCommander jc = new JCommander(jct, argv); + Assert.assertEquals(jc.getParameters().size(), 3); + } + + public static void main(String[] args) { + new JCommanderTest().repeatedArgs(); + } } -- cgit v1.2.3 From dc76d5707bd6f5b761772203e9d7c285846e8362 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 21:11:57 -0700 Subject: Added required and tests --- src/main/java/com/beust/jcommander/JCommander.java | 39 ++++++++++++++++++---- src/main/java/com/beust/jcommander/Parameter.java | 13 ++++++++ .../com/beust/jcommander/ParameterDescription.java | 4 +++ .../java/com/beust/jcommander/JCommanderTest.java | 32 +++++++++++++++++- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index f048906..7fc3a5f 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -8,6 +8,7 @@ import java.lang.reflect.Field; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; /** * The main class for JCommander. It's responsible for parsing the object that contains @@ -15,7 +16,6 @@ import java.util.Map; * values and a few other helper methods, such as usage(). * * @author cbeust - * */ public class JCommander { /** @@ -35,7 +35,17 @@ public class JCommander { private Field m_mainParameterField; /** - * A map of all the fields that describe an option. + * A set of all the fields that are required. During the reflection phase, + * this field receives all the fields that are annotated with required=true + * and during the parsing phase, all the fields that are assigned a value + * are removed from it. At the end of the parsing phase, if it's not empty, + * then some required fields did not receive a value and an exception is + * thrown. + */ + private Map m_requiredFields = Maps.newHashMap(); + + /** + * A map of all the annotated fields. */ private Map m_fields = Maps.newHashMap(); @@ -54,12 +64,28 @@ public class JCommander { public void parse(String... args) { createDescriptions(); parseValues(expandArgs(args)); + validateOptions(); } + /** + * Make sure that all the required parameters have received a value. + */ + private void validateOptions() { + if (! m_requiredFields.isEmpty()) { + StringBuilder missingFields = new StringBuilder(); + for (ParameterDescription pd : m_requiredFields.values()) { + missingFields.append(pd.getNames()[0]).append(" "); + } + throw new ParameterException("The following options are required: " + missingFields); + } + + } + /** * Expand the command line parameters to take @ parameters into account. * When @ is encountered, the content of the file that follows is inserted - * in the command line + * in the command line. + * * @param originalArgv the original command line parameters * @return the new and enriched command line parameters */ @@ -135,9 +161,6 @@ public class JCommander { Annotation annotation = f.getAnnotation(Parameter.class); if (annotation != null) { Parameter p = (Parameter) annotation; - if (p.names().length > 0) { - m_fields.put(f, p); - } if (p.names().length == 0) { p("Found main parameter:" + f); m_mainParameterField = f; @@ -145,7 +168,9 @@ public class JCommander { for (String name : p.names()) { p("Adding description for " + name); ParameterDescription pd = new ParameterDescription(m_object, p, f); + m_fields.put(f, p); m_descriptions.put(name, pd); + if (p.required()) m_requiredFields.put(f, pd); } } } @@ -167,8 +192,10 @@ public class JCommander { Class fieldType = pd.getField().getType(); if (fieldType == boolean.class || fieldType == Boolean.class) { pd.addValue(Boolean.TRUE); + m_requiredFields.remove(pd.getField()); } else if (i + 1 < args.length) { pd.addValue(trim(args[i + 1])); + m_requiredFields.remove(pd.getField()); i++; } else { throw new ParameterException("Parameter expected after " + args[i]); diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 9e6bc6a..bd1ea88 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -9,7 +9,20 @@ import java.lang.annotation.Target; @Target({ FIELD }) public @interface Parameter { + /** + * An array of allowed command line parameters (e.g. "-d", "--outputdir", etc...). + * If this attribute is omitted, the field it's annotating will receive all the + * unparsed options. There can only be at most one such annotation. + */ String[] names() default {}; + /** + * A description of this option. + */ String description() default ""; + + /** + * Whether this option is required. + */ + boolean required() default false; } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index e44c0cb..5308591 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -25,6 +25,10 @@ public class ParameterDescription { return m_parameterAnnotation.description(); } + public Parameter getParameter() { + return m_parameterAnnotation; + } + public Field getField() { return m_field; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9e170f7..30af305 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -11,7 +11,7 @@ public class JCommanderTest { @Parameter public List parameters = Lists.newArrayList(); - @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity", required = true) public Integer verbose = 1; @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") @@ -44,6 +44,36 @@ public class JCommanderTest { Assert.assertEquals(jc.getParameters().size(), 3); } + /** + * Not specifying a required option should throw an exception. + */ + @Test(expectedExceptions = ParameterException.class) + public void requiredFields1() { + JCommanderTest jct = new JCommanderTest(); + String[] argv = { "-debug" }; + JCommander jc = new JCommander(jct, argv); + } + + /** + * Required options with multiple names should work with all names. + */ + @Test + public void requiredFields2() { + JCommanderTest jct = new JCommanderTest(); + String[] argv = { "-log", "2" }; + JCommander jc = new JCommander(jct, argv); + } + + /** + * Required options with multiple names should work with all names. + */ + @Test + public void requiredFields3() { + JCommanderTest jct = new JCommanderTest(); + String[] argv = { "-verbose", "2" }; + JCommander jc = new JCommander(jct, argv); + } + public static void main(String[] args) { new JCommanderTest().repeatedArgs(); } -- cgit v1.2.3 From db7a571f6cc481746c1a7e0f4d3100e47b22b18f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 21:15:59 -0700 Subject: Doc for required and exceptions --- doc/index.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/index.html b/doc/index.html index 37b7254..fa1c7c7 100644 --- a/doc/index.html +++ b/doc/index.html @@ -184,6 +184,29 @@ java Main -d /tmp java Main --outputDirectory /tmp +

    Required and optional parameters

    + +If some of your parameters are mandatory, you can use the +required attribute (which default to false): + +
    +
    +  @Parameter(names = "-host", required = true)
    +  public String host;
    +
    +
    + +If this parameter is not specified, JCommander will throw an exception +telling you which options are missing. + +

    Exception

    + +Whenever JCommander detects an error, it will throw a +ParameterException. Note that this is a Runtime Exception, +since your application is probably not initialized correctly at this +point. + +

    Usage

    You can invoke usage() on the JCommander instance that you used to parse your command line in order to generate a summary of all the options that your program understands: -- cgit v1.2.3 From 55ea189f8bea382611c2067d12df2e68ae29a0bc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 21:54:42 -0700 Subject: Doc update --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index fa1c7c7..c437690 100644 --- a/doc/index.html +++ b/doc/index.html @@ -115,7 +115,7 @@ will cause an exception to be thrown.

    Lists

    -When a Parameter annotation is found on a field of type List, JCommander will interpret it as an option that can happen multiple times: +When a Parameter annotation is found on a field of type List, JCommander will interpret it as an option that can occur multiple times:
     @Parameter(names = "-hosts", description = "Level of verbosity")
    -- 
    cgit v1.2.3
    
    
    From 9b9a740c04d97ccbb5c643e55775cf9e9e6fc2d7 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Tue, 13 Jul 2010 23:13:03 -0700
    Subject: Added support for i18n
    
    ---
     src/main/java/com/beust/jcommander/JCommander.java | 28 ++++++++++++-------
     src/main/java/com/beust/jcommander/Parameter.java  |  5 ++++
     .../com/beust/jcommander/ParameterDescription.java | 20 ++++++++++++--
     src/test/java/com/beust/jcommander/I18N.java       |  7 +++++
     .../java/com/beust/jcommander/JCommanderTest.java  | 31 +++++++++++++++++++++-
     src/test/resources/MessageBundle.properties        |  2 ++
     src/test/resources/MessageBundle_fr_FR.properties  |  1 +
     7 files changed, 81 insertions(+), 13 deletions(-)
     create mode 100644 src/test/java/com/beust/jcommander/I18N.java
     create mode 100644 src/test/resources/MessageBundle.properties
     create mode 100644 src/test/resources/MessageBundle_fr_FR.properties
    
    diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
    index 7fc3a5f..24a801f 100644
    --- a/src/main/java/com/beust/jcommander/JCommander.java
    +++ b/src/main/java/com/beust/jcommander/JCommander.java
    @@ -5,10 +5,10 @@ import java.io.FileReader;
     import java.io.IOException;
     import java.lang.annotation.Annotation;
     import java.lang.reflect.Field;
    -import java.util.Collection;
    +import java.util.ArrayList;
     import java.util.List;
     import java.util.Map;
    -import java.util.Set;
    +import java.util.ResourceBundle;
     
     /**
      * The main class for JCommander. It's responsible for parsing the object that contains
    @@ -47,12 +47,20 @@ public class JCommander {
       /**
        * A map of all the annotated fields.
        */
    -  private Map m_fields = Maps.newHashMap();
    +  private Map m_fields = Maps.newHashMap();
    +
    +  private ResourceBundle m_bundle;
     
       public JCommander(Object object) {
         m_object = object;
       }
     
    +  public JCommander(Object object, ResourceBundle bundle, String... args) {
    +    m_object = object;
    +    m_bundle = bundle;
    +    parse(args);
    +  }
    +
       public JCommander(Object object, String... args) {
         m_object = object;
         parse(args);
    @@ -167,8 +175,8 @@ public class JCommander {
             } else {
               for (String name : p.names()) {
                 p("Adding description for " + name);
    -            ParameterDescription pd = new ParameterDescription(m_object, p, f);
    -            m_fields.put(f, p);
    +            ParameterDescription pd = new ParameterDescription(m_object, p, f, m_bundle);
    +            m_fields.put(f, pd);
                 m_descriptions.put(name, pd);
                 if (p.required()) m_requiredFields.put(f, pd);
               }
    @@ -238,12 +246,12 @@ public class JCommander {
        */
       public void usage() {
         System.out.println("Usage:");
    -    for (Parameter p : m_fields.values()) {
    +    for (ParameterDescription pd : m_fields.values()) {
           StringBuilder sb = new StringBuilder();
    -      for (String n : p.names()) {
    +      for (String n : pd.getParameter().names()) {
             sb.append(n).append(" ");
           }
    -      System.out.println("\t" + sb.toString() + "\t" + p.description());
    +      System.out.println("\t" + sb.toString() + "\t" + pd.getDescription());
         }
       }
     
    @@ -252,8 +260,8 @@ public class JCommander {
        * target class. This can be used to display the usage() in a different
        * format (e.g. HTML).
        */
    -  public Collection getParameters() {
    -    return m_fields.values();
    +  public List getParameters() {
    +    return new ArrayList(m_fields.values());
       }
     }
     
    diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java
    index bd1ea88..6536a9f 100644
    --- a/src/main/java/com/beust/jcommander/Parameter.java
    +++ b/src/main/java/com/beust/jcommander/Parameter.java
    @@ -25,4 +25,9 @@ public @interface Parameter {
        * Whether this option is required.
        */
       boolean required() default false;
    +
    +  /**
    +   * The key used to find the string in the message bundle.
    +   */
    +  String descriptionKey() default "";
     }
    diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
    index 5308591..8088272 100644
    --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
    +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
    @@ -1,7 +1,9 @@
     package com.beust.jcommander;
     
    +
     import java.lang.reflect.Field;
     import java.util.List;
    +import java.util.ResourceBundle;
     import java.util.Set;
     
     public class ParameterDescription {
    @@ -10,11 +12,25 @@ public class ParameterDescription {
       private Field m_field;
       /** Keep track of whether a value was added to flag an error */
       private boolean m_added = false;
    +  private ResourceBundle m_bundle;
    +  private String m_description;
    +
    +  public ParameterDescription(Object object, Parameter annotation, Field field,
    +      ResourceBundle bundle) {
    +    init(object, annotation, field, bundle);
    +  }
     
    -  public ParameterDescription(Object object, Parameter annotation, Field field) {
    +  private void init(Object object, Parameter annotation, Field field, ResourceBundle bundle) {
         m_object = object;
         m_parameterAnnotation = annotation;
         m_field = field;
    +    m_bundle = bundle;
    +
    +    if (m_bundle != null) {
    +      m_description = m_bundle.getString(annotation.descriptionKey());
    +    } else {
    +      m_description = annotation.description();
    +    }
       }
     
       public String[] getNames() {
    @@ -22,7 +38,7 @@ public class ParameterDescription {
       }
     
       public String getDescription() {
    -    return m_parameterAnnotation.description();
    +    return m_description;
       }
     
       public Parameter getParameter() {
    diff --git a/src/test/java/com/beust/jcommander/I18N.java b/src/test/java/com/beust/jcommander/I18N.java
    new file mode 100644
    index 0000000..8b2f3af
    --- /dev/null
    +++ b/src/test/java/com/beust/jcommander/I18N.java
    @@ -0,0 +1,7 @@
    +package com.beust.jcommander;
    +
    +public class I18N {
    +
    +  @Parameter(names = "-host", description = "Host", descriptionKey = "host")
    +  String hostName;
    +}
    diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
    index 30af305..d1802ff 100644
    --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
    +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
    @@ -6,6 +6,8 @@ import org.testng.collections.Lists;
     
     import java.util.Arrays;
     import java.util.List;
    +import java.util.Locale;
    +import java.util.ResourceBundle;
     
     public class JCommanderTest {
       @Parameter
    @@ -74,7 +76,34 @@ public class JCommanderTest {
         JCommander jc = new JCommander(jct, argv);
       }
     
    +  private void i18n(Locale locale, String expectedString) {
    +    ResourceBundle bundle = locale != null ? ResourceBundle.getBundle("MessageBundle", locale)
    +        : null;
    +
    +    I18N i18n = new I18N();
    +    String[] argv = { "-host", "localhost" };
    +    JCommander jc = new JCommander(i18n, bundle, argv);
    +
    +    ParameterDescription pd = jc.getParameters().get(0);
    +    Assert.assertEquals(pd.getDescription(), expectedString);
    +  }
    +
    +  @Test
    +  public void i18nNoLocale() {
    +    i18n(null, "Host");
    +  }
    +
    +  @Test
    +  public void i18nUsLocale() {
    +    i18n(new Locale("en", "US"), "Host");
    +  }
    +
    +  @Test
    +  public void i18nFrLocale() {
    +    i18n(new Locale("fr", "FR"), "H™te");
    +  }
    +
       public static void main(String[] args) {
    -    new JCommanderTest().repeatedArgs();
    +    new JCommanderTest().i18nNoLocale();
       }
     }
    diff --git a/src/test/resources/MessageBundle.properties b/src/test/resources/MessageBundle.properties
    new file mode 100644
    index 0000000..2125848
    --- /dev/null
    +++ b/src/test/resources/MessageBundle.properties
    @@ -0,0 +1,2 @@
    +host = Host
    +
    diff --git a/src/test/resources/MessageBundle_fr_FR.properties b/src/test/resources/MessageBundle_fr_FR.properties
    new file mode 100644
    index 0000000..c74e3de
    --- /dev/null
    +++ b/src/test/resources/MessageBundle_fr_FR.properties
    @@ -0,0 +1 @@
    +host = Hôte
    -- 
    cgit v1.2.3
    
    
    From 913f6ff2562a4ebcd3aa4dca35ac4f74cad0005b Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Tue, 13 Jul 2010 23:29:47 -0700
    Subject: Documented i18n
    
    ---
     doc/index.html                                     | 39 ++++++++++++++++++++++
     .../java/com/beust/jcommander/JCommanderTest.java  |  3 +-
     2 files changed, 41 insertions(+), 1 deletion(-)
    
    diff --git a/doc/index.html b/doc/index.html
    index c437690..9c5a8ab 100644
    --- a/doc/index.html
    +++ b/doc/index.html
    @@ -219,6 +219,45 @@ Usage:
     	-testclass		List of classes
     
    +

    Internationalization

    + +You can internationalize the descriptions of your parameters. First, +you use the descriptionKey attribute instead of +description. This descriptionKey is the key to the +string into your message bundle: + +

    I18N.java

    +
    +@Parameter(names = "-host", descriptionKey = "host")
    +String hostName;
    +
    + +Your bundle needs to define this key: + +
    + +

    MessageBundle_fr_FR.properties

    +
    +host: Hôte
    +
    + +Then you pass the Locale when you initialize the JCommander +object: + +
    +Locale locale = new Locale("fr", "FR");
    +ResourceBundle bundle = ResourceBundle.getBundle("MessageBundle", locale);
    +I18N i18n = new I18N();
    +String[] argv = { "-host", "localhost" };
    +JCommander jc = new JCommander(i18n, bundle, argv);
    +jc.usage();
    +
    +will display: + +
    +Usage:
    +	-host 	Hôte
    +

    More examples

    diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index d1802ff..d442c8a 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -83,6 +83,7 @@ public class JCommanderTest { I18N i18n = new I18N(); String[] argv = { "-host", "localhost" }; JCommander jc = new JCommander(i18n, bundle, argv); + jc.usage(); ParameterDescription pd = jc.getParameters().get(0); Assert.assertEquals(pd.getDescription(), expectedString); @@ -104,6 +105,6 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().i18nNoLocale(); + new JCommanderTest().i18nFrLocale(); } } -- cgit v1.2.3 From 14516e91e6be4ba1c3e7b573ea450e5c59925ecf Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 23:30:18 -0700 Subject: Removed trace --- src/test/java/com/beust/jcommander/JCommanderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index d442c8a..054f28b 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -83,7 +83,7 @@ public class JCommanderTest { I18N i18n = new I18N(); String[] argv = { "-host", "localhost" }; JCommander jc = new JCommander(i18n, bundle, argv); - jc.usage(); +// jc.usage(); ParameterDescription pd = jc.getParameters().get(0); Assert.assertEquals(pd.getDescription(), expectedString); -- cgit v1.2.3 From 080153cdadd0c6c3a053a7dbe2dfe04dd7c107b8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Jul 2010 23:32:04 -0700 Subject: Updated TODO --- doc/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 9c5a8ab..e12f079 100644 --- a/doc/index.html +++ b/doc/index.html @@ -280,7 +280,6 @@ Some of the features I am considering adding:
  • Support for arities >= 2 (syntaxes such as java Main -pair pair1 pair2).
  • Type converters, to enable fields to have any type.
  • HTML generation for usage(). -
  • Internationalization (bundles). -- cgit v1.2.3 From 94fca5e6d4506c5b070b17db4063ad360a85d8fc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 08:58:08 -0700 Subject: Better tests --- src/test/java/com/beust/jcommander/Args1.java | 20 +++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 39 ++++++++-------------- 2 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/Args1.java diff --git a/src/test/java/com/beust/jcommander/Args1.java b/src/test/java/com/beust/jcommander/Args1.java new file mode 100644 index 0000000..9105d24 --- /dev/null +++ b/src/test/java/com/beust/jcommander/Args1.java @@ -0,0 +1,20 @@ +package com.beust.jcommander; + +import org.testng.collections.Lists; + +import java.util.List; + +public class Args1 { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity", required = true) + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 054f28b..e62419c 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -10,28 +10,15 @@ import java.util.Locale; import java.util.ResourceBundle; public class JCommanderTest { - @Parameter - public List parameters = Lists.newArrayList(); - - @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity", required = true) - public Integer verbose = 1; - - @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; - - @Parameter(names = "-debug", description = "Debug mode") - public boolean debug = false; - @Test public void simpleArgs() { - JCommanderTest jct = new JCommanderTest(); + Args1 args = new Args1(); String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; - new JCommander(jct, argv); + new JCommander(args, argv); - System.out.println("Verbose:" + verbose); - Assert.assertEquals(jct.verbose.intValue(), 2); - Assert.assertEquals(jct.groups, "unit"); - Assert.assertEquals(jct.parameters, Arrays.asList("a", "b", "c")); + Assert.assertEquals(args.verbose.intValue(), 2); + Assert.assertEquals(args.groups, "unit"); + Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c")); } /** @@ -40,9 +27,9 @@ public class JCommanderTest { */ @Test public void repeatedArgs() { - JCommanderTest jct = new JCommanderTest(); + Args1 args = new Args1(); String[] argv = { "-log", "2" }; - JCommander jc = new JCommander(jct, argv); + JCommander jc = new JCommander(args, argv); Assert.assertEquals(jc.getParameters().size(), 3); } @@ -51,9 +38,9 @@ public class JCommanderTest { */ @Test(expectedExceptions = ParameterException.class) public void requiredFields1() { - JCommanderTest jct = new JCommanderTest(); + Args1 args = new Args1(); String[] argv = { "-debug" }; - JCommander jc = new JCommander(jct, argv); + new JCommander(args, argv); } /** @@ -61,9 +48,9 @@ public class JCommanderTest { */ @Test public void requiredFields2() { - JCommanderTest jct = new JCommanderTest(); + Args1 args = new Args1(); String[] argv = { "-log", "2" }; - JCommander jc = new JCommander(jct, argv); + new JCommander(args, argv); } /** @@ -71,9 +58,9 @@ public class JCommanderTest { */ @Test public void requiredFields3() { - JCommanderTest jct = new JCommanderTest(); + Args1 args = new Args1(); String[] argv = { "-verbose", "2" }; - JCommander jc = new JCommander(jct, argv); + new JCommander(args, argv); } private void i18n(Locale locale, String expectedString) { -- cgit v1.2.3 From d4e3897873895131ae5ebef4e9552b15a9e804dd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 09:19:53 -0700 Subject: Added multi object support and tests --- src/main/java/com/beust/jcommander/JCommander.java | 81 +++++++++++++++------- src/test/java/com/beust/jcommander/ArgsMaster.java | 12 ++++ src/test/java/com/beust/jcommander/ArgsSlave.java | 12 ++++ .../java/com/beust/jcommander/JCommanderTest.java | 17 +++++ 4 files changed, 97 insertions(+), 25 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/ArgsMaster.java create mode 100644 src/test/java/com/beust/jcommander/ArgsSlave.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 24a801f..c5a25f4 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -24,9 +25,9 @@ public class JCommander { private Map m_descriptions; /** - * The object that contains the fields annotated with @Parameter. + * The objects that contain fields annotated with @Parameter. */ - private Object m_object; + private List m_objects; /** * This field will contain whatever command line parameter is not an option. @@ -34,6 +35,11 @@ public class JCommander { */ private Field m_mainParameterField; + /** + * The object on which we found the main parameter field. + */ + private Object m_mainParameterObject; + /** * A set of all the fields that are required. During the reflection phase, * this field receives all the fields that are annotated with required=true @@ -52,20 +58,38 @@ public class JCommander { private ResourceBundle m_bundle; public JCommander(Object object) { - m_object = object; + init(object, null); } public JCommander(Object object, ResourceBundle bundle, String... args) { - m_object = object; - m_bundle = bundle; + init(object, bundle); parse(args); } public JCommander(Object object, String... args) { - m_object = object; + init(object, null); parse(args); } + private void init(Object object, ResourceBundle bundle) { + m_bundle = bundle; + m_objects = Lists.newArrayList(); + if (object instanceof Iterable) { + // Iterable + for (Object o : (Iterable) object) { + m_objects.add(o); + } + } else if (object.getClass().isArray()) { + // Array + for (Object o : (Object[]) object) { + m_objects.add(o); + } + } else { + // Single object + m_objects.add(object); + } + } + /** * Parse the command line parameters. */ @@ -162,23 +186,27 @@ public class JCommander { private void createDescriptions() { m_descriptions = Maps.newHashMap(); - Class cls = m_object.getClass(); - for (Field f : cls.getDeclaredFields()) { - p("Field:" + f.getName()); - f.setAccessible(true); - Annotation annotation = f.getAnnotation(Parameter.class); - if (annotation != null) { - Parameter p = (Parameter) annotation; - if (p.names().length == 0) { - p("Found main parameter:" + f); - m_mainParameterField = f; - } else { - for (String name : p.names()) { - p("Adding description for " + name); - ParameterDescription pd = new ParameterDescription(m_object, p, f, m_bundle); - m_fields.put(f, pd); - m_descriptions.put(name, pd); - if (p.required()) m_requiredFields.put(f, pd); + + for (Object object : m_objects) { + Class cls = object.getClass(); + for (Field f : cls.getDeclaredFields()) { + p("Field:" + f.getName()); + f.setAccessible(true); + Annotation annotation = f.getAnnotation(Parameter.class); + if (annotation != null) { + Parameter p = (Parameter) annotation; + if (p.names().length == 0) { + p("Found main parameter:" + f); + m_mainParameterField = f; + m_mainParameterObject = object; + } else { + for (String name : p.names()) { + p("Adding description for " + name); + ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle); + m_fields.put(f, pd); + m_descriptions.put(name, pd); + if (p.required()) m_requiredFields.put(f, pd); + } } } } @@ -222,6 +250,9 @@ public class JCommander { return s == null || "".equals(s); } + /** + * @return the field that's meant to receive all the parameters that are not options. + */ private List getMainParameter() { if (m_mainParameterField == null) { throw new ParameterException( @@ -229,10 +260,10 @@ public class JCommander { } try { - List result = (List) m_mainParameterField.get(m_object); + List result = (List) m_mainParameterField.get(m_mainParameterObject); if (result == null) { result = Lists.newArrayList(); - m_mainParameterField.set(m_object, result); + m_mainParameterField.set(m_mainParameterObject, result); } return result; } diff --git a/src/test/java/com/beust/jcommander/ArgsMaster.java b/src/test/java/com/beust/jcommander/ArgsMaster.java new file mode 100644 index 0000000..b3a5469 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsMaster.java @@ -0,0 +1,12 @@ +package com.beust.jcommander; + +/** + * Test multi-object parsing, along with ArgsSlave. + * + * @author cbeust + */ +public class ArgsMaster { + @Parameter(names = "-master") + public String master; + +} diff --git a/src/test/java/com/beust/jcommander/ArgsSlave.java b/src/test/java/com/beust/jcommander/ArgsSlave.java new file mode 100644 index 0000000..c360af7 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsSlave.java @@ -0,0 +1,12 @@ +package com.beust.jcommander; + +/** + * Test multi-object parsing, along with ArgsSlave. + * + * @author cbeust + */ +public class ArgsSlave { + @Parameter(names = "-slave") + public String slave; + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index e62419c..fd941d9 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -91,7 +91,24 @@ public class JCommanderTest { i18n(new Locale("fr", "FR"), "H™te"); } + @Test + public void multiObjects() { + ArgsMaster m = new ArgsMaster(); + ArgsSlave s = new ArgsSlave(); + String[] argv = { "-master", "master", "-slave", "slave" }; + new JCommander(new Object[] {m , s}, argv); + + Assert.assertEquals(m.master, "master"); + Assert.assertEquals(s.slave, "slave"); + } + public static void main(String[] args) { +// new JCommanderTest().multiObjects(); new JCommanderTest().i18nFrLocale(); } + + // check that + // - only one main parameter is present + // - Long, Int + } -- cgit v1.2.3 From b945b741b5de0510ce39f8c793e31202070ef942 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 09:23:56 -0700 Subject: Documented multi object --- doc/index.html | 39 +++++++++++++++++++++- src/test/java/com/beust/jcommander/ArgsMaster.java | 1 - src/test/java/com/beust/jcommander/ArgsSlave.java | 1 - .../java/com/beust/jcommander/JCommanderTest.java | 2 +- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/doc/index.html b/doc/index.html index e12f079..181f903 100644 --- a/doc/index.html +++ b/doc/index.html @@ -147,7 +147,44 @@ will allow you to parse: java Main -debug file1 file2 -and the field files will receive the strings "file1" and "file2". +and the field files will receive the strings "file1" and +"file2". + +

    Multiple descriptions

    + +You can spread the description of your parameters on more than one +class. For example, you can define the following two classes: + +

    + +

    ArgsMaster.java

    +
    +public class ArgsMaster {
    +  @Parameter(names = "-master")
    +  public String master;
    +}
    +
    + +

    ArgsSlave.java

    +
    +public class ArgsSlave {
    +  @Parameter(names = "-slave")
    +  public String slave;
    +}
    +
    + +and pass these two objects to JCommander: + +
    +ArgsMaster m = new ArgsMaster();
    +ArgsSlave s = new ArgsSlave();
    +String[] argv = { "-master", "master", "-slave", "slave" };
    +new JCommander(new Object[] { m , s }, argv);
    +
    +Assert.assertEquals(m.master, "master");
    +Assert.assertEquals(s.slave, "slave");
    +
    +

    @ syntax

    diff --git a/src/test/java/com/beust/jcommander/ArgsMaster.java b/src/test/java/com/beust/jcommander/ArgsMaster.java index b3a5469..98e5228 100644 --- a/src/test/java/com/beust/jcommander/ArgsMaster.java +++ b/src/test/java/com/beust/jcommander/ArgsMaster.java @@ -8,5 +8,4 @@ package com.beust.jcommander; public class ArgsMaster { @Parameter(names = "-master") public String master; - } diff --git a/src/test/java/com/beust/jcommander/ArgsSlave.java b/src/test/java/com/beust/jcommander/ArgsSlave.java index c360af7..8f43cc7 100644 --- a/src/test/java/com/beust/jcommander/ArgsSlave.java +++ b/src/test/java/com/beust/jcommander/ArgsSlave.java @@ -8,5 +8,4 @@ package com.beust.jcommander; public class ArgsSlave { @Parameter(names = "-slave") public String slave; - } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index fd941d9..c7e624d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -96,7 +96,7 @@ public class JCommanderTest { ArgsMaster m = new ArgsMaster(); ArgsSlave s = new ArgsSlave(); String[] argv = { "-master", "master", "-slave", "slave" }; - new JCommander(new Object[] {m , s}, argv); + new JCommander(new Object[] { m , s }, argv); Assert.assertEquals(m.master, "master"); Assert.assertEquals(s.slave, "slave"); -- cgit v1.2.3 From a21262377768de124914e354e428ed6860828949 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 09:40:39 -0700 Subject: Implemented arity and tests --- src/main/java/com/beust/jcommander/JCommander.java | 16 +++++++++++----- src/main/java/com/beust/jcommander/Parameter.java | 6 ++++++ src/test/java/com/beust/jcommander/JCommanderTest.java | 15 ++++++++++++++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index c5a25f4..9b71dfe 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -229,12 +229,18 @@ public class JCommander { if (fieldType == boolean.class || fieldType == Boolean.class) { pd.addValue(Boolean.TRUE); m_requiredFields.remove(pd.getField()); - } else if (i + 1 < args.length) { - pd.addValue(trim(args[i + 1])); - m_requiredFields.remove(pd.getField()); - i++; } else { - throw new ParameterException("Parameter expected after " + args[i]); + int arity = pd.getParameter().arity(); + int n = (arity != -1 ? arity : 1); + if (i + n < args.length) { + for (int j = 1; j <= n; j++) { + pd.addValue(trim(args[i + j])); + m_requiredFields.remove(pd.getField()); + } + i += n; + } else { + throw new ParameterException("Parameter expected after " + args[i]); + } } } else { throw new ParameterException("Unknown option: " + a); diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 6536a9f..721413b 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -30,4 +30,10 @@ public @interface Parameter { * The key used to find the string in the message bundle. */ String descriptionKey() default ""; + + /** + * How many parameter values this parameter will consume. For example, + * an arity of 2 will allow "-pair value1 value2". + */ + int arity() default -1; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index c7e624d..8a94804 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -102,9 +102,22 @@ public class JCommanderTest { Assert.assertEquals(s.slave, "slave"); } + @Test + public void arity() { + ArgsArity args = new ArgsArity(); + String[] argv = { "-pairs", "pair0", "pair1", "rest" }; + new JCommander(args, argv); + + Assert.assertEquals(args.pairs.size(), 2); + Assert.assertEquals(args.pairs.get(0), "pair0"); + Assert.assertEquals(args.pairs.get(1), "pair1"); + Assert.assertEquals(args.rest.size(), 1); + Assert.assertEquals(args.rest.get(0), "rest"); + } + public static void main(String[] args) { // new JCommanderTest().multiObjects(); - new JCommanderTest().i18nFrLocale(); + new JCommanderTest().arity(); } // check that -- cgit v1.2.3 From 0c0b2226295308797b486e7dcc81d10497ad4886 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 09:45:49 -0700 Subject: Now failing if the same option is found more than once --- src/main/java/com/beust/jcommander/JCommander.java | 3 +++ src/test/java/com/beust/jcommander/ArgsArity.java | 17 +++++++++++++++++ src/test/java/com/beust/jcommander/ArgsSlaveBogus.java | 11 +++++++++++ src/test/java/com/beust/jcommander/JCommanderTest.java | 12 +++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/beust/jcommander/ArgsArity.java create mode 100644 src/test/java/com/beust/jcommander/ArgsSlaveBogus.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 9b71dfe..7d4db50 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -201,6 +201,9 @@ public class JCommander { m_mainParameterObject = object; } else { for (String name : p.names()) { + if (m_descriptions.containsKey(name)) { + throw new ParameterException("Found the option " + name + " multiple times"); + } p("Adding description for " + name); ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle); m_fields.put(f, pd); diff --git a/src/test/java/com/beust/jcommander/ArgsArity.java b/src/test/java/com/beust/jcommander/ArgsArity.java new file mode 100644 index 0000000..9879ef3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsArity.java @@ -0,0 +1,17 @@ +package com.beust.jcommander; + +import java.util.List; + +/** + * Test parameter arity. + * + * @author cbeust + */ +public class ArgsArity { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public List pairs; + + @Parameter(description = "Rest") + public List rest; +} diff --git a/src/test/java/com/beust/jcommander/ArgsSlaveBogus.java b/src/test/java/com/beust/jcommander/ArgsSlaveBogus.java new file mode 100644 index 0000000..ed72174 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsSlaveBogus.java @@ -0,0 +1,11 @@ +package com.beust.jcommander; + +/** + * Same as ArgsMaster class, should cause an error. + * + * @author cbeust + */ +public class ArgsSlaveBogus extends ArgsSlave { + @Parameter(names = "-master") + public String master; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 8a94804..67f1392 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -102,6 +102,14 @@ public class JCommanderTest { Assert.assertEquals(s.slave, "slave"); } + @Test(expectedExceptions = ParameterException.class) + public void multiObjectsWithDuplicates() { + ArgsMaster m = new ArgsMaster(); + ArgsSlave s = new ArgsSlaveBogus(); + String[] argv = { "-master", "master", "-slave", "slave" }; + new JCommander(new Object[] { m , s }, argv); + } + @Test public void arity() { ArgsArity args = new ArgsArity(); @@ -117,11 +125,13 @@ public class JCommanderTest { public static void main(String[] args) { // new JCommanderTest().multiObjects(); - new JCommanderTest().arity(); + new JCommanderTest().multiObjectsWithDuplicates(); } // check that // - only one main parameter is present // - Long, Int + // - error if same parameter found on different classes + // - error cases in arities } -- cgit v1.2.3 From f3b82e196a622a959374d7588688e74fe852a512 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 10:03:30 -0700 Subject: Documented arities and more tests --- doc/index.html | 28 ++++++++++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/ArgsArity.java | 17 ------------- .../com/beust/jcommander/ArgsArityInteger.java | 17 +++++++++++++ .../java/com/beust/jcommander/ArgsArityString.java | 17 +++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 13 +++++++--- 6 files changed, 73 insertions(+), 21 deletions(-) delete mode 100644 src/test/java/com/beust/jcommander/ArgsArity.java create mode 100644 src/test/java/com/beust/jcommander/ArgsArityInteger.java create mode 100644 src/test/java/com/beust/jcommander/ArgsArityString.java diff --git a/doc/index.html b/doc/index.html index 181f903..0d1c86a 100644 --- a/doc/index.html +++ b/doc/index.html @@ -203,6 +203,34 @@ file3 java Main @/tmp/parameters +

    Arities (multiple values for parameters)

    + +If some of your parameters require more than one value, such as the +following example where two values are expected after -pairs: + +
    +java Main -pairs slave master foo.xml
    +
    + +then you need to define your parameter with the arity +attribute and make that parameter a List<String>: + +
    +@Parameter(names = "-pairs", arity = 2, description = "Pairs")
    +public List pairs;
    +
    + +You don't need to specify an arity for parameters of type +boolean or Boolean (which have a default arity of 0) +and of types String, Integer, int, +Long and long (which have a default arity of 1). + +

    +Also, note that only List<String> is allowed for +parameters that define an arity. You will have to convert these values +yourself if the parameters you need are of type Integer or +other (this limitation is due to Java's erasure). +

    Multiple option names

    You can specify more than one option name: diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 7d4db50..7874ce4 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -242,7 +242,7 @@ public class JCommander { } i += n; } else { - throw new ParameterException("Parameter expected after " + args[i]); + throw new ParameterException(arity + " parameters expected after " + args[i]); } } } else { diff --git a/src/test/java/com/beust/jcommander/ArgsArity.java b/src/test/java/com/beust/jcommander/ArgsArity.java deleted file mode 100644 index 9879ef3..0000000 --- a/src/test/java/com/beust/jcommander/ArgsArity.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.beust.jcommander; - -import java.util.List; - -/** - * Test parameter arity. - * - * @author cbeust - */ -public class ArgsArity { - - @Parameter(names = "-pairs", arity = 2, description = "Pairs") - public List pairs; - - @Parameter(description = "Rest") - public List rest; -} diff --git a/src/test/java/com/beust/jcommander/ArgsArityInteger.java b/src/test/java/com/beust/jcommander/ArgsArityInteger.java new file mode 100644 index 0000000..36d8749 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsArityInteger.java @@ -0,0 +1,17 @@ +package com.beust.jcommander; + +import java.util.List; + +/** + * Test parameter arity. + * + * @author cbeust + */ +public class ArgsArityInteger { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public List pairs; + + @Parameter(description = "Rest") + public List rest; +} diff --git a/src/test/java/com/beust/jcommander/ArgsArityString.java b/src/test/java/com/beust/jcommander/ArgsArityString.java new file mode 100644 index 0000000..281d7d2 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsArityString.java @@ -0,0 +1,17 @@ +package com.beust.jcommander; + +import java.util.List; + +/** + * Test parameter arity. + * + * @author cbeust + */ +public class ArgsArityString { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public List pairs; + + @Parameter(description = "Rest") + public List rest; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 67f1392..462af85 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -111,8 +111,8 @@ public class JCommanderTest { } @Test - public void arity() { - ArgsArity args = new ArgsArity(); + public void arityString() { + ArgsArityString args = new ArgsArityString(); String[] argv = { "-pairs", "pair0", "pair1", "rest" }; new JCommander(args, argv); @@ -123,9 +123,16 @@ public class JCommanderTest { Assert.assertEquals(args.rest.get(0), "rest"); } + @Test(expectedExceptions = ParameterException.class) + public void arityFail1() { + ArgsArityString args = new ArgsArityString(); + String[] argv = { "-pairs", "pair0" }; + new JCommander(args, argv); + } + public static void main(String[] args) { // new JCommanderTest().multiObjects(); - new JCommanderTest().multiObjectsWithDuplicates(); +// new JCommanderTest().arityInteger(); } // check that -- cgit v1.2.3 From cb91ef843854605fcde3b84ce91ec4d46205a47a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 10:08:56 -0700 Subject: More tests --- src/main/java/com/beust/jcommander/JCommander.java | 6 +++++- .../com/beust/jcommander/ArgsMultipleUnparsed.java | 15 +++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 20 ++++++++++---------- 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 7874ce4..5dcb3d6 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -33,7 +33,7 @@ public class JCommander { * This field will contain whatever command line parameter is not an option. * It is expected to be a List. */ - private Field m_mainParameterField; + private Field m_mainParameterField = null; /** * The object on which we found the main parameter field. @@ -197,6 +197,10 @@ public class JCommander { Parameter p = (Parameter) annotation; if (p.names().length == 0) { p("Found main parameter:" + f); + if (m_mainParameterField != null) { + throw new ParameterException("Only one @Parameter with no names attribute is" + + " allowed, found:" + m_mainParameterField + " and " + f); + } m_mainParameterField = f; m_mainParameterObject = object; } else { diff --git a/src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java b/src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java new file mode 100644 index 0000000..a3222f2 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java @@ -0,0 +1,15 @@ +package com.beust.jcommander; + +/** + * Error case if multiple unparsed (without a names attribute) arguments are defined. + * + * @author cbeust + */ +public class ArgsMultipleUnparsed { + + @Parameter(description = "Bogus1") + public String unparsed1; + + @Parameter(description = "Bogus2") + public String unparsed2; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 462af85..1bad968 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -2,10 +2,8 @@ package com.beust.jcommander; import org.testng.Assert; import org.testng.annotations.Test; -import org.testng.collections.Lists; import java.util.Arrays; -import java.util.List; import java.util.Locale; import java.util.ResourceBundle; @@ -13,9 +11,10 @@ public class JCommanderTest { @Test public void simpleArgs() { Args1 args = new Args1(); - String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; + String[] argv = { "-debug", "-log", "2", "-groups", "unit", "a", "b", "c" }; new JCommander(args, argv); + Assert.assertTrue(args.debug); Assert.assertEquals(args.verbose.intValue(), 2); Assert.assertEquals(args.groups, "unit"); Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c")); @@ -130,15 +129,16 @@ public class JCommanderTest { new JCommander(args, argv); } + @Test(expectedExceptions = ParameterException.class) + public void multipleUnparsedFail() { + ArgsMultipleUnparsed args = new ArgsMultipleUnparsed(); + String[] argv = { }; + new JCommander(args, argv); + } + public static void main(String[] args) { // new JCommanderTest().multiObjects(); -// new JCommanderTest().arityInteger(); + new JCommanderTest().multipleUnparsedFail(); } - // check that - // - only one main parameter is present - // - Long, Int - // - error if same parameter found on different classes - // - error cases in arities - } -- cgit v1.2.3 From 1f846b5dc8d840f6ce8714a6202b3a4ff02448a4 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 10:09:21 -0700 Subject: Doc update --- doc/index.html | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/doc/index.html b/doc/index.html index 0d1c86a..e00aa8d 100644 --- a/doc/index.html +++ b/doc/index.html @@ -337,17 +337,6 @@ You can download JCommander from the following locations:
  • Source on github
  • -

    TODO

    - -Some of the features I am considering adding: - -
      -
    • Support for arities >= 2 (syntaxes such as java Main -pair pair1 pair2). -
    • Type converters, to enable fields to have any type. -
    • HTML generation for usage(). -
    - - -- cgit v1.2.3 From 5b337d30385b7dcad9113be0637aefb6b064c85c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jul 2010 10:11:40 -0700 Subject: Doc --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index e00aa8d..e734763 100644 --- a/doc/index.html +++ b/doc/index.html @@ -217,7 +217,7 @@ attribute and make that parameter a List<String>:
     @Parameter(names = "-pairs", arity = 2, description = "Pairs")
    -public List pairs;
    +public List<String> pairs;
     
    You don't need to specify an arity for parameters of type -- cgit v1.2.3 From c3e28e12136391968250719b1627b6b4eaa196cd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 15 Jul 2010 08:38:42 -0700 Subject: Doc, pom and test update --- doc/index.html | 32 ++++++++++------------ pom.xml | 25 ++++++++++++++++- .../java/com/beust/jcommander/JCommanderTest.java | 4 ++- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/doc/index.html b/doc/index.html index e734763..4ba880f 100644 --- a/doc/index.html +++ b/doc/index.html @@ -38,9 +38,8 @@ Cédric Beust -

    -Overview -

    + +

    Overview

    JCommander is a very small Java framework that makes it trivial to parse command line parameters.

    @@ -74,9 +73,7 @@ new JCommander(jct, argv); Assert.assertEquals(jct.verbose.intValue(), 2); -

    -Types of options -

    +

    Types of options

    JCommander supports many types of options. @@ -118,7 +115,7 @@ will cause an exception to be thrown. When a Parameter annotation is found on a field of type List, JCommander will interpret it as an option that can occur multiple times:
    -@Parameter(names = "-hosts", description = "Level of verbosity")
    +@Parameter(names = "-host", description = "Level of verbosity")
     public List<String> hosts = new ArrayList<String>();
     
    @@ -150,7 +147,7 @@ java Main -debug file1 file2 and the field files will receive the strings "file1" and "file2". -

    Multiple descriptions

    +

    Multiple descriptions

    You can spread the description of your parameters on more than one class. For example, you can define the following two classes: @@ -186,7 +183,7 @@ Assert.assertEquals(s.slave, "slave"); -

    @ syntax

    +

    @ syntax

    JCommander supports the @ syntax, which allows you to put all your options into a file and pass this file as parameter: @@ -203,7 +200,7 @@ file3 java Main @/tmp/parameters -

    Arities (multiple values for parameters)

    +

    Arities (multiple values for parameters)

    If some of your parameters require more than one value, such as the following example where two values are expected after -pairs: @@ -231,7 +228,7 @@ parameters that define an arity. You will have to convert these values yourself if the parameters you need are of type Integer or other (this limitation is due to Java's erasure). -

    Multiple option names

    +

    Multiple option names

    You can specify more than one option name: @@ -249,7 +246,7 @@ java Main -d /tmp java Main --outputDirectory /tmp -

    Required and optional parameters

    +

    Required and optional parameters

    If some of your parameters are mandatory, you can use the required attribute (which default to false): @@ -264,7 +261,7 @@ If some of your parameters are mandatory, you can use the If this parameter is not specified, JCommander will throw an exception telling you which options are missing. -

    Exception

    +

    Exception

    Whenever JCommander detects an error, it will throw a ParameterException. Note that this is a Runtime Exception, @@ -272,7 +269,7 @@ since your application is probably not initialized correctly at this point. -

    Usage

    +

    Usage

    You can invoke usage() on the JCommander instance that you used to parse your command line in order to generate a summary of all the options that your program understands: @@ -284,7 +281,7 @@ Usage: -testclass List of classes -

    Internationalization

    +

    Internationalization

    You can internationalize the descriptions of your parameters. First, you use the descriptionKey attribute instead of @@ -324,16 +321,15 @@ Usage: -host Hôte -

    More examples

    +

    More examples

    TestNG uses JCommander to parse its command line, here is its definition file. -

    Download

    +

    Download

    You can download JCommander from the following locations: diff --git a/pom.xml b/pom.xml index bb884e6..05609cc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.beust jcommander jar - 1.0-SNAPSHOT + 1.0 A Java framework to parse command line options with annotations. jcommander http://maven.apache.org @@ -20,9 +20,17 @@ http://github.com/cbeust/jcommander + + + Cedric Beust + + + + + org.apache.maven.plugins maven-source-plugin @@ -37,6 +45,7 @@ + org.apache.maven.plugins maven-compiler-plugin @@ -46,6 +55,20 @@ + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.7 + + + com.beust.jcommander.JCommander + + + + + + org.apache.maven.plugins maven-gpg-plugin diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 1bad968..217ac40 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -140,5 +140,7 @@ public class JCommanderTest { // new JCommanderTest().multiObjects(); new JCommanderTest().multipleUnparsedFail(); } - + + // Tests: + // required unparsed parameter } -- cgit v1.2.3 From 4f570bfe806783486922e1b3544cce87ae4c9a96 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 15 Jul 2010 20:38:13 -0700 Subject: Updated doc and version --- doc/index.html | 14 ++++++++++++++ pom.xml | 9 ++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/index.html b/doc/index.html index 4ba880f..47091e9 100644 --- a/doc/index.html +++ b/doc/index.html @@ -331,6 +331,20 @@ You can download JCommander from the following locations: diff --git a/pom.xml b/pom.xml index 05609cc..f898064 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.beust jcommander jar - 1.0 + 1.1-SNAPSHOT A Java framework to parse command line options with annotations. jcommander http://maven.apache.org @@ -17,7 +17,7 @@ http://github.com/cbeust/jcommander - http://github.com/cbeust/jcommander + scm:git:http://github.com/cbeust/jcommander.git @@ -60,11 +60,6 @@ org.apache.maven.plugins maven-javadoc-plugin 2.7 - - - com.beust.jcommander.JCommander - - -- cgit v1.2.3 From 5f00acc5afee348e6f3b3741d5e53ca01e508b3e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 07:02:51 -0700 Subject: Documented and tested private parameters --- doc/index.html | 22 ++++++++++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 5 +++++ .../java/com/beust/jcommander/JCommanderTest.java | 7 +++++++ 3 files changed, 34 insertions(+) diff --git a/doc/index.html b/doc/index.html index 47091e9..9f6be90 100644 --- a/doc/index.html +++ b/doc/index.html @@ -147,6 +147,28 @@ java Main -debug file1 file2 and the field files will receive the strings "file1" and "file2". +

    Private parameters

    + +Parameters can be private: + +
    +public class ArgsPrivate {
    +  @Parameter(names = "-verbose")
    +  private Integer verbose = 1;
    +
    +  public Integer getVerbose() {
    +    return verbose;
    +  }
    +}
    +
    + +
    +ArgsPrivate args = new ArgsPrivate();
    +new JCommander(args, "-verbose", "3");
    +Assert.assertEquals(args.getVerbose().intValue(), 3);
    +
    + +

    Multiple descriptions

    You can spread the description of your parameters on more than one diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 5dcb3d6..e0588d1 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -16,6 +16,11 @@ import java.util.ResourceBundle; * all the annotated fields, parse the command line and assign the fields with the correct * values and a few other helper methods, such as usage(). * + * The object(s) you pass in the constructor are expected to have one or more + * @Parameter annotations on them. You can pass either a single object, an array of objects + * or an instance of Iterable. In the case of an array or Iterable, JCommander will collect + * the @Parameter annotations from all the objects passed in parameter. + * * @author cbeust */ public class JCommander { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 217ac40..7b98061 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -136,6 +136,13 @@ public class JCommanderTest { new JCommander(args, argv); } + @Test + public void privateArgs() { + ArgsPrivate args = new ArgsPrivate(); + new JCommander(args, "-verbose", "3"); + Assert.assertEquals(args.getVerbose().intValue(), 3); + } + public static void main(String[] args) { // new JCommanderTest().multiObjects(); new JCommanderTest().multipleUnparsedFail(); -- cgit v1.2.3 From d095e39e4a4ba659ec031bd7a4695d48502ba5eb Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 09:29:43 -0700 Subject: Added password and test for private fields --- src/main/java/com/beust/jcommander/JCommander.java | 39 ++++++++++++++-------- src/main/java/com/beust/jcommander/Parameter.java | 6 ++++ .../java/com/beust/jcommander/ArgsPassword.java | 7 ++++ .../java/com/beust/jcommander/ArgsPrivate.java | 10 ++++++ .../java/com/beust/jcommander/JCommanderTest.java | 6 +++- 5 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/ArgsPassword.java create mode 100644 src/test/java/com/beust/jcommander/ArgsPrivate.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index e0588d1..555e360 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,12 +1,12 @@ package com.beust.jcommander; import java.io.BufferedReader; +import java.io.Console; import java.io.FileReader; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -237,21 +237,32 @@ public class JCommander { if (a.startsWith("-")) { ParameterDescription pd = m_descriptions.get(a); if (pd != null) { - Class fieldType = pd.getField().getType(); - if (fieldType == boolean.class || fieldType == Boolean.class) { - pd.addValue(Boolean.TRUE); - m_requiredFields.remove(pd.getField()); + if (pd.getParameter().password()) { + Console console = System.console(); + if (console == null) { + throw new ParameterException("No console is available to get parameter " + + pd.getNames()[0]); + } + System.out.print("Value for " + pd.getNames()[0] + " (" + pd.getDescription() + "):"); + char[] password = console.readPassword(); + pd.addValue(new String(password)); } else { - int arity = pd.getParameter().arity(); - int n = (arity != -1 ? arity : 1); - if (i + n < args.length) { - for (int j = 1; j <= n; j++) { - pd.addValue(trim(args[i + j])); - m_requiredFields.remove(pd.getField()); - } - i += n; + Class fieldType = pd.getField().getType(); + if (fieldType == boolean.class || fieldType == Boolean.class) { + pd.addValue(Boolean.TRUE); + m_requiredFields.remove(pd.getField()); } else { - throw new ParameterException(arity + " parameters expected after " + args[i]); + int arity = pd.getParameter().arity(); + int n = (arity != -1 ? arity : 1); + if (i + n < args.length) { + for (int j = 1; j <= n; j++) { + pd.addValue(trim(args[i + j])); + m_requiredFields.remove(pd.getField()); + } + i += n; + } else { + throw new ParameterException(arity + " parameters expected after " + args[i]); + } } } } else { diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 721413b..ecefd2a 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -36,4 +36,10 @@ public @interface Parameter { * an arity of 2 will allow "-pair value1 value2". */ int arity() default -1; + + /** + * If true, this parameter is a password and it will be prompted on the console + * (if available). + */ + boolean password() default false; } diff --git a/src/test/java/com/beust/jcommander/ArgsPassword.java b/src/test/java/com/beust/jcommander/ArgsPassword.java new file mode 100644 index 0000000..5e4b78f --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsPassword.java @@ -0,0 +1,7 @@ +package com.beust.jcommander; + +public class ArgsPassword { + + @Parameter(names = "-password", description = "Connection password", password = true) + public String password; +} diff --git a/src/test/java/com/beust/jcommander/ArgsPrivate.java b/src/test/java/com/beust/jcommander/ArgsPrivate.java new file mode 100644 index 0000000..87ebe5b --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsPrivate.java @@ -0,0 +1,10 @@ +package com.beust.jcommander; + +public class ArgsPrivate { + @Parameter(names = "-verbose") + private Integer verbose = 1; + + public Integer getVerbose() { + return verbose; + } +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 7b98061..6a2d95d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -144,8 +144,12 @@ public class JCommanderTest { } public static void main(String[] args) { + ArgsPassword a = new ArgsPassword(); + new JCommander(a, "-password"); + System.out.println("Received:" + a.password); +// Assert.assertEquals(args.getVerbose().intValue(), 3); // new JCommanderTest().multiObjects(); - new JCommanderTest().multipleUnparsedFail(); +// new JCommanderTest().multipleUnparsedFail(); } // Tests: -- cgit v1.2.3 From 6cec497e00d1ccaaf26cffdc2f935246818e9f97 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 09:36:31 -0700 Subject: Documented password --- doc/index.html | 19 +++++++++++++++++++ src/test/java/com/beust/jcommander/ArgsPassword.java | 1 - 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 9f6be90..78078b5 100644 --- a/doc/index.html +++ b/doc/index.html @@ -127,6 +127,25 @@ java Main -host host1 -verbose -host host2 When JCommander is done parsing the line above, the field hosts will contain the strings "host1" and "host2". +

    Password

    + +If one of your parameters is a password or some other value that you do not wish to appear in your history or in clear, you can declare it of type password and JCommander will then ask you to enter it in the console: + +
    +public class ArgsPassword {
    +  @Parameter(names = "-password", description = "Connection password", password = true)
    +  public String password;
    +}
    +
    + +When you run your program, you will get the following prompt: + +
    +Value for -password (Connection password):
    +
    + +You will need to type the value at this point before JCommander resumes. +

    Main parameter

    So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a List<String> and it will contain all the parameters that are not options: diff --git a/src/test/java/com/beust/jcommander/ArgsPassword.java b/src/test/java/com/beust/jcommander/ArgsPassword.java index 5e4b78f..1a598a4 100644 --- a/src/test/java/com/beust/jcommander/ArgsPassword.java +++ b/src/test/java/com/beust/jcommander/ArgsPassword.java @@ -1,7 +1,6 @@ package com.beust.jcommander; public class ArgsPassword { - @Parameter(names = "-password", description = "Connection password", password = true) public String password; } -- cgit v1.2.3 From b65aee8e0ed696b8c4c71793a57c75b4543ca9c1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 09:43:22 -0700 Subject: Moved classes into internal --- src/main/java/com/beust/jcommander/JCommander.java | 3 +++ src/main/java/com/beust/jcommander/Lists.java | 20 -------------------- src/main/java/com/beust/jcommander/Maps.java | 11 ----------- .../com/beust/jcommander/ParameterDescription.java | 2 ++ src/main/java/com/beust/jcommander/Sets.java | 12 ------------ .../java/com/beust/jcommander/internal/Lists.java | 20 ++++++++++++++++++++ .../java/com/beust/jcommander/internal/Maps.java | 11 +++++++++++ .../java/com/beust/jcommander/internal/Sets.java | 12 ++++++++++++ 8 files changed, 48 insertions(+), 43 deletions(-) delete mode 100644 src/main/java/com/beust/jcommander/Lists.java delete mode 100644 src/main/java/com/beust/jcommander/Maps.java delete mode 100644 src/main/java/com/beust/jcommander/Sets.java create mode 100644 src/main/java/com/beust/jcommander/internal/Lists.java create mode 100644 src/main/java/com/beust/jcommander/internal/Maps.java create mode 100644 src/main/java/com/beust/jcommander/internal/Sets.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 555e360..10f7c22 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,5 +1,8 @@ package com.beust.jcommander; +import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Maps; + import java.io.BufferedReader; import java.io.Console; import java.io.FileReader; diff --git a/src/main/java/com/beust/jcommander/Lists.java b/src/main/java/com/beust/jcommander/Lists.java deleted file mode 100644 index 5794beb..0000000 --- a/src/main/java/com/beust/jcommander/Lists.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.beust.jcommander; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class Lists { - - public static List newArrayList() { - return new ArrayList(); - } - - public static List newArrayList(Collection c) { - return new ArrayList(c); - } - - public static List newArrayList(int size) { - return new ArrayList(size); - } -} diff --git a/src/main/java/com/beust/jcommander/Maps.java b/src/main/java/com/beust/jcommander/Maps.java deleted file mode 100644 index 1442e85..0000000 --- a/src/main/java/com/beust/jcommander/Maps.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.beust.jcommander; - -import java.util.HashMap; -import java.util.Map; - -public class Maps { - - public static Map newHashMap() { - return new HashMap(); - } -} diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 8088272..8af24b3 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -1,6 +1,8 @@ package com.beust.jcommander; +import com.beust.jcommander.internal.Lists; + import java.lang.reflect.Field; import java.util.List; import java.util.ResourceBundle; diff --git a/src/main/java/com/beust/jcommander/Sets.java b/src/main/java/com/beust/jcommander/Sets.java deleted file mode 100644 index 5e7c3ef..0000000 --- a/src/main/java/com/beust/jcommander/Sets.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beust.jcommander; - -import java.util.HashSet; -import java.util.Set; - -public class Sets { - - public static Set newHashSet() { - return new HashSet(); - } - -} diff --git a/src/main/java/com/beust/jcommander/internal/Lists.java b/src/main/java/com/beust/jcommander/internal/Lists.java new file mode 100644 index 0000000..8cacc33 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/Lists.java @@ -0,0 +1,20 @@ +package com.beust.jcommander.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Lists { + + public static List newArrayList() { + return new ArrayList(); + } + + public static List newArrayList(Collection c) { + return new ArrayList(c); + } + + public static List newArrayList(int size) { + return new ArrayList(size); + } +} diff --git a/src/main/java/com/beust/jcommander/internal/Maps.java b/src/main/java/com/beust/jcommander/internal/Maps.java new file mode 100644 index 0000000..6a0dba6 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/Maps.java @@ -0,0 +1,11 @@ +package com.beust.jcommander.internal; + +import java.util.HashMap; +import java.util.Map; + +public class Maps { + + public static Map newHashMap() { + return new HashMap(); + } +} diff --git a/src/main/java/com/beust/jcommander/internal/Sets.java b/src/main/java/com/beust/jcommander/internal/Sets.java new file mode 100644 index 0000000..ced1045 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/Sets.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.internal; + +import java.util.HashSet; +import java.util.Set; + +public class Sets { + + public static Set newHashSet() { + return new HashSet(); + } + +} -- cgit v1.2.3 From 5a8d2cda56e06eccac04f985cfb6df4886cb270e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 10:47:14 -0700 Subject: Implemented type converters --- .../com/beust/jcommander/IStringConverter.java | 10 ++++ src/main/java/com/beust/jcommander/JCommander.java | 6 +- src/main/java/com/beust/jcommander/Parameter.java | 4 ++ .../com/beust/jcommander/ParameterDescription.java | 70 +++++++++++++++++----- .../jcommander/converters/BooleanConverter.java | 12 ++++ .../converters/CommaSeparatedConverter.java | 15 +++++ .../beust/jcommander/converters/FileConverter.java | 14 +++++ .../jcommander/converters/IntegerConverter.java | 12 ++++ .../beust/jcommander/converters/LongConverter.java | 12 ++++ .../beust/jcommander/converters/NoConverter.java | 12 ++++ .../jcommander/converters/StringConverter.java | 12 ++++ .../java/com/beust/jcommander/ArgsConverter.java | 16 +++++ .../java/com/beust/jcommander/JCommanderTest.java | 19 ++++-- 13 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/IStringConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/BooleanConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/FileConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/IntegerConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/LongConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/NoConverter.java create mode 100644 src/main/java/com/beust/jcommander/converters/StringConverter.java create mode 100644 src/test/java/com/beust/jcommander/ArgsConverter.java diff --git a/src/main/java/com/beust/jcommander/IStringConverter.java b/src/main/java/com/beust/jcommander/IStringConverter.java new file mode 100644 index 0000000..9abd96c --- /dev/null +++ b/src/main/java/com/beust/jcommander/IStringConverter.java @@ -0,0 +1,10 @@ +package com.beust.jcommander; + +/** + * An interface that converts strings to any arbitrary type. + * + * @author cbeust + */ +public interface IStringConverter { + T convert(String value); +} diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 10f7c22..a14a3e5 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,5 +1,8 @@ package com.beust.jcommander; +import com.beust.jcommander.converters.IntegerConverter; +import com.beust.jcommander.converters.LongConverter; +import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.Lists; import com.beust.jcommander.internal.Maps; @@ -10,6 +13,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -252,7 +256,7 @@ public class JCommander { } else { Class fieldType = pd.getField().getType(); if (fieldType == boolean.class || fieldType == Boolean.class) { - pd.addValue(Boolean.TRUE); + pd.addValue("true"); m_requiredFields.remove(pd.getField()); } else { int arity = pd.getParameter().arity(); diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index ecefd2a..9d4ef62 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -2,6 +2,8 @@ package com.beust.jcommander; import static java.lang.annotation.ElementType.FIELD; +import com.beust.jcommander.converters.NoConverter; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -42,4 +44,6 @@ public @interface Parameter { * (if available). */ boolean password() default false; + + Class converter() default NoConverter.class; } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 8af24b3..c314fba 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -1,14 +1,41 @@ package com.beust.jcommander; +import com.beust.jcommander.converters.BooleanConverter; +import com.beust.jcommander.converters.IntegerConverter; +import com.beust.jcommander.converters.LongConverter; +import com.beust.jcommander.converters.NoConverter; +import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Maps; import java.lang.reflect.Field; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.ResourceBundle; import java.util.Set; public class ParameterDescription { + /** + * A map of converters per class. + */ + private static Map, Class> m_classConverters + = new HashMap() {{ + put(String.class, StringConverter.class); + put(Integer.class, IntegerConverter.class); + put(int.class, IntegerConverter.class); + put(Long.class, LongConverter.class); + put(long.class, LongConverter.class); + put(Boolean.class, BooleanConverter.class); + put(boolean.class, BooleanConverter.class); + }}; + + /** + * A map of converters per field. Will take precedence over the class converter map. + */ + private Map m_fieldConverters = Maps.newHashMap(); + private Object m_object; private Parameter m_parameterAnnotation; private Field m_field; @@ -56,36 +83,49 @@ public class ParameterDescription { return fieldType.equals(List.class) || fieldType.equals(Set.class); } - public void addValue(Object value) { + /** + * Add the specified value to the field. First look up any field converter, then + * any type converter, and if we can't find any, throw an exception. + */ + public void addValue(String value) { + boolean arity = false; if (m_added && ! isMultiOption()) { throw new ParameterException("Can only specify option " + getNames()[0] + " once."); } + Class converterClass = m_parameterAnnotation.converter(); + if (converterClass == NoConverter.class) { + converterClass = m_classConverters.get(m_field.getType()); + } + if (converterClass == null && m_parameterAnnotation.arity() >= 2) { + converterClass = StringConverter.class; + arity = true; + } + if (converterClass == null) { + throw new ParameterException("Don't know how to convert " + value + + " to type " + m_field.getType() + " (field: " + m_field.getName() + ")"); + } m_added = true; + IStringConverter converter; try { - Class fieldType = m_field.getType(); - if (fieldType.equals(String.class)) { - m_field.set(m_object, value); - } else if (fieldType.equals(int.class) || fieldType.equals(Integer.class)) { - m_field.set(m_object, Integer.parseInt(value.toString())); - } else if (fieldType.equals(long.class) || fieldType.equals(Long.class)) { - m_field.set(m_object, Long.parseLong(value.toString())); - } else if (fieldType.equals(float.class) || fieldType.equals(Float.class)) { - m_field.set(m_object, Float.parseFloat(value.toString())); - } else if (fieldType.equals(Boolean.class) || fieldType.equals(boolean.class)) { - m_field.set(m_object, value); - } else if (isMultiOption()) { + converter = converterClass.newInstance(); + Object convertedValue = converter.convert(value); + if (arity) { List l = (List) m_field.get(m_object); if (l == null) { l = Lists.newArrayList(); m_field.set(m_object, l); } - l.add(value); + l.add(convertedValue); + } else { + m_field.set(m_object, convertedValue); } - } catch (IllegalArgumentException e) { + } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); } } } diff --git a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java new file mode 100644 index 0000000..52cd74c --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +public class BooleanConverter implements IStringConverter { + + @Override + public Boolean convert(String value) { + return Boolean.parseBoolean(value); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java new file mode 100644 index 0000000..44c3455 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java @@ -0,0 +1,15 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +import java.util.Arrays; +import java.util.List; + +public class CommaSeparatedConverter implements IStringConverter> { + + @Override + public List convert(String value) { + return Arrays.asList(value.split(",")); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/FileConverter.java b/src/main/java/com/beust/jcommander/converters/FileConverter.java new file mode 100644 index 0000000..36364fc --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/FileConverter.java @@ -0,0 +1,14 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +import java.io.File; + +public class FileConverter implements IStringConverter { + + @Override + public File convert(String value) { + return new File(value); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java new file mode 100644 index 0000000..2efe058 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +public class IntegerConverter implements IStringConverter { + + @Override + public Integer convert(String value) { + return Integer.parseInt(value); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java new file mode 100644 index 0000000..d14fd23 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +public class LongConverter implements IStringConverter { + + @Override + public Long convert(String value) { + return Long.parseLong(value); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/NoConverter.java b/src/main/java/com/beust/jcommander/converters/NoConverter.java new file mode 100644 index 0000000..bae1898 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/NoConverter.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +public class NoConverter implements IStringConverter { + + @Override + public String convert(String value) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/StringConverter.java b/src/main/java/com/beust/jcommander/converters/StringConverter.java new file mode 100644 index 0000000..05fec0e --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/StringConverter.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +public class StringConverter implements IStringConverter { + + @Override + public String convert(String value) { + return value; + } + +} diff --git a/src/test/java/com/beust/jcommander/ArgsConverter.java b/src/test/java/com/beust/jcommander/ArgsConverter.java new file mode 100644 index 0000000..9ccd2e3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsConverter.java @@ -0,0 +1,16 @@ +package com.beust.jcommander; + +import com.beust.jcommander.converters.CommaSeparatedConverter; +import com.beust.jcommander.converters.FileConverter; + +import java.io.File; +import java.util.List; + +public class ArgsConverter { + + @Parameter(names = "-file", converter = FileConverter.class) + File file; + + @Parameter(names = "-days", converter = CommaSeparatedConverter.class) + List days; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 6a2d95d..3d28d32 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -143,12 +143,23 @@ public class JCommanderTest { Assert.assertEquals(args.getVerbose().intValue(), 3); } + @Test + public void converterArgs() { + ArgsConverter args = new ArgsConverter(); + String fileName = "a"; + new JCommander(args, "-file", "/tmp/" + fileName, "-days", "Tuesday,Thursday"); + Assert.assertEquals(args.file.getName(), fileName); + Assert.assertEquals(args.days.size(), 2); + Assert.assertEquals(args.days.get(0), "Tuesday"); + Assert.assertEquals(args.days.get(1), "Thursday"); + } + public static void main(String[] args) { - ArgsPassword a = new ArgsPassword(); - new JCommander(a, "-password"); - System.out.println("Received:" + a.password); +// ArgsPassword a = new ArgsPassword(); +// new JCommander(a, "-password"); +// System.out.println("Received:" + a.password); // Assert.assertEquals(args.getVerbose().intValue(), 3); -// new JCommanderTest().multiObjects(); + new JCommanderTest().converterArgs(); // new JCommanderTest().multipleUnparsedFail(); } -- cgit v1.2.3 From 6734de3a3b73ec9fe6bbfe4f8ba1da9f57264587 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 11:36:41 -0700 Subject: Added @ResourceBundle annotation --- .../com/beust/jcommander/ParameterDescription.java | 21 ++++++++++++--- .../java/com/beust/jcommander/ResourceBundle.java | 15 +++++++++++ src/test/java/com/beust/jcommander/ArgsI18N1.java | 7 +++++ src/test/java/com/beust/jcommander/ArgsI18N2.java | 8 ++++++ src/test/java/com/beust/jcommander/I18N.java | 7 ----- .../java/com/beust/jcommander/JCommanderTest.java | 30 ++++++++++++++-------- 6 files changed, 67 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/ResourceBundle.java create mode 100644 src/test/java/com/beust/jcommander/ArgsI18N1.java create mode 100644 src/test/java/com/beust/jcommander/ArgsI18N2.java delete mode 100644 src/test/java/com/beust/jcommander/I18N.java diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index c314fba..64bef39 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -12,6 +12,7 @@ import com.beust.jcommander.internal.Maps; import java.lang.reflect.Field; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; @@ -54,11 +55,23 @@ public class ParameterDescription { m_parameterAnnotation = annotation; m_field = field; m_bundle = bundle; + if (m_bundle == null) { + com.beust.jcommander.ResourceBundle a + = object.getClass().getAnnotation(com.beust.jcommander.ResourceBundle.class); + if (a != null) { + m_bundle = ResourceBundle.getBundle(a.value(), Locale.getDefault()); + } + } - if (m_bundle != null) { - m_description = m_bundle.getString(annotation.descriptionKey()); - } else { - m_description = annotation.description(); + m_description = annotation.description(); + if (! "".equals(annotation.descriptionKey())) { + if (m_bundle != null) { + m_description = m_bundle.getString(annotation.descriptionKey()); + } else { +// System.out.println("Warning: field " + object.getClass() + "." + field.getName() +// + " has a descriptionKey but no bundle was defined with @ResourceBundle, using " + +// "default description:'" + m_description + "'"); + } } } diff --git a/src/main/java/com/beust/jcommander/ResourceBundle.java b/src/main/java/com/beust/jcommander/ResourceBundle.java new file mode 100644 index 0000000..789f738 --- /dev/null +++ b/src/main/java/com/beust/jcommander/ResourceBundle.java @@ -0,0 +1,15 @@ +package com.beust.jcommander; + +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@Target({ TYPE }) +public @interface ResourceBundle { + /** + * The name of the resource bundle to use for this class. + */ + String value(); +} diff --git a/src/test/java/com/beust/jcommander/ArgsI18N1.java b/src/test/java/com/beust/jcommander/ArgsI18N1.java new file mode 100644 index 0000000..bda4ed1 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsI18N1.java @@ -0,0 +1,7 @@ +package com.beust.jcommander; + +public class ArgsI18N1 { + + @Parameter(names = "-host", description = "Host", descriptionKey = "host") + String hostName; +} diff --git a/src/test/java/com/beust/jcommander/ArgsI18N2.java b/src/test/java/com/beust/jcommander/ArgsI18N2.java new file mode 100644 index 0000000..cd608e0 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsI18N2.java @@ -0,0 +1,8 @@ +package com.beust.jcommander; + +@ResourceBundle("MessageBundle") +public class ArgsI18N2 { + + @Parameter(names = "-host", description = "Host", descriptionKey = "host") + String hostName; +} diff --git a/src/test/java/com/beust/jcommander/I18N.java b/src/test/java/com/beust/jcommander/I18N.java deleted file mode 100644 index 8b2f3af..0000000 --- a/src/test/java/com/beust/jcommander/I18N.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.beust.jcommander; - -public class I18N { - - @Parameter(names = "-host", description = "Host", descriptionKey = "host") - String hostName; -} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 3d28d32..6b0de07 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -36,7 +36,7 @@ public class JCommanderTest { * Not specifying a required option should throw an exception. */ @Test(expectedExceptions = ParameterException.class) - public void requiredFields1() { + public void requiredFields1Fail() { Args1 args = new Args1(); String[] argv = { "-debug" }; new JCommander(args, argv); @@ -62,11 +62,11 @@ public class JCommanderTest { new JCommander(args, argv); } - private void i18n(Locale locale, String expectedString) { - ResourceBundle bundle = locale != null ? ResourceBundle.getBundle("MessageBundle", locale) + private void i18n1(String bundleName, Locale locale, String expectedString) { + ResourceBundle bundle = locale != null ? ResourceBundle.getBundle(bundleName, locale) : null; - I18N i18n = new I18N(); + ArgsI18N1 i18n = new ArgsI18N1(); String[] argv = { "-host", "localhost" }; JCommander jc = new JCommander(i18n, bundle, argv); // jc.usage(); @@ -77,17 +77,27 @@ public class JCommanderTest { @Test public void i18nNoLocale() { - i18n(null, "Host"); + i18n1("MessageBundle", null, "Host"); } @Test public void i18nUsLocale() { - i18n(new Locale("en", "US"), "Host"); + i18n1("MessageBundle", new Locale("en", "US"), "Host"); } @Test public void i18nFrLocale() { - i18n(new Locale("fr", "FR"), "H™te"); + i18n1("MessageBundle", new Locale("fr", "FR"), "H™te"); + } + + @Test + public void i18nWithResourceAnnotation() { + ArgsI18N2 i18n = new ArgsI18N2(); + String[] argv = { "-host", "localhost" }; + Locale.setDefault(new Locale("fr", "FR")); + JCommander jc = new JCommander(i18n, argv); + ParameterDescription pd = jc.getParameters().get(0); + Assert.assertEquals(pd.getDescription(), "H™te"); } @Test @@ -102,7 +112,7 @@ public class JCommanderTest { } @Test(expectedExceptions = ParameterException.class) - public void multiObjectsWithDuplicates() { + public void multiObjectsWithDuplicatesFail() { ArgsMaster m = new ArgsMaster(); ArgsSlave s = new ArgsSlaveBogus(); String[] argv = { "-master", "master", "-slave", "slave" }; @@ -123,7 +133,7 @@ public class JCommanderTest { } @Test(expectedExceptions = ParameterException.class) - public void arityFail1() { + public void arity1Fail() { ArgsArityString args = new ArgsArityString(); String[] argv = { "-pairs", "pair0" }; new JCommander(args, argv); @@ -159,7 +169,7 @@ public class JCommanderTest { // new JCommander(a, "-password"); // System.out.println("Received:" + a.password); // Assert.assertEquals(args.getVerbose().intValue(), 3); - new JCommanderTest().converterArgs(); + new JCommanderTest().i18nWithResourceAnnotation(); // new JCommanderTest().multipleUnparsedFail(); } -- cgit v1.2.3 From a2deb87ad99fd0fff8f1238be710c9f26811f471 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 12:19:29 -0700 Subject: Updated i18n doc --- doc/index.html | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/doc/index.html b/doc/index.html index 78078b5..73c94c7 100644 --- a/doc/index.html +++ b/doc/index.html @@ -324,15 +324,19 @@ Usage:

    Internationalization

    -You can internationalize the descriptions of your parameters. First, -you use the descriptionKey attribute instead of -description. This descriptionKey is the key to the -string into your message bundle: +You can internationalize the descriptions of your parameters. + +

    + +First you use the @ResourceBundle annotation at the top of your class to define the name of your message bundle, and then you use the descriptionKey attribute instead of description on all the @Parameters that require translations. This descriptionKey is the key to the string into your message bundle:

    I18N.java

    -@Parameter(names = "-host", descriptionKey = "host")
    -String hostName;
    +@ResourceBundle("MessageBundle")
    +public class ArgsI18N2 {
    +  @Parameter(names = "-host", description = "Host", descriptionKey = "host")
    +  String hostName;
    +}
     
    Your bundle needs to define this key: @@ -344,23 +348,7 @@ Your bundle needs to define this key: host: Hôte -Then you pass the Locale when you initialize the JCommander -object: - -
    -Locale locale = new Locale("fr", "FR");
    -ResourceBundle bundle = ResourceBundle.getBundle("MessageBundle", locale);
    -I18N i18n = new I18N();
    -String[] argv = { "-host", "localhost" };
    -JCommander jc = new JCommander(i18n, bundle, argv);
    -jc.usage();
    -
    -will display: - -
    -Usage:
    -	-host 	Hôte
    -
    +JCommander will then use the default locale to resolve your descriptions.

    More examples

    -- cgit v1.2.3 From 1d8d7fed4ca7bb1f2d8c318a60b9c46ffef1a506 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Sat, 17 Jul 2010 01:13:38 +0200 Subject: Fix warnings --- src/main/java/com/beust/jcommander/JCommander.java | 11 +++++------ src/main/java/com/beust/jcommander/ParameterDescription.java | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index a14a3e5..bdc36f7 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -88,7 +88,7 @@ public class JCommander { m_objects = Lists.newArrayList(); if (object instanceof Iterable) { // Iterable - for (Object o : (Iterable) object) { + for (Object o : (Iterable) object) { m_objects.add(o); } } else if (object.getClass().isArray()) { @@ -188,12 +188,10 @@ public class JCommander { if (result.startsWith("\"")) { if (result.endsWith("\"")) { return result.substring(1, result.length() - 1); - } else { - return result.substring(1); } - } else { - return result; + return result.substring(1); } + return result; } private void createDescriptions() { @@ -296,6 +294,7 @@ public class JCommander { } try { + @SuppressWarnings("unchecked") List result = (List) m_mainParameterField.get(m_mainParameterObject); if (result == null) { result = Lists.newArrayList(); @@ -328,7 +327,7 @@ public class JCommander { * format (e.g. HTML). */ public List getParameters() { - return new ArrayList(m_fields.values()); + return new ArrayList(m_fields.values()); } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 64bef39..301e376 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -124,7 +124,8 @@ public class ParameterDescription { converter = converterClass.newInstance(); Object convertedValue = converter.convert(value); if (arity) { - List l = (List) m_field.get(m_object); + @SuppressWarnings("unchecked") + List l = (List) m_field.get(m_object); if (l == null) { l = Lists.newArrayList(); m_field.set(m_object, l); -- cgit v1.2.3 From c27a04a2e10667dff4390b25fa4224b58b291ca0 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Sat, 17 Jul 2010 00:35:36 +0200 Subject: Fix encoding and default locale issues --- pom.xml | 12 +++++++++++- src/test/java/com/beust/jcommander/JCommanderTest.java | 4 ++-- src/test/resources/MessageBundle.properties | 2 -- src/test/resources/MessageBundle_en_US.properties | 1 + src/test/resources/MessageBundle_fr_FR.properties | 2 +- 5 files changed, 15 insertions(+), 6 deletions(-) delete mode 100644 src/test/resources/MessageBundle.properties create mode 100644 src/test/resources/MessageBundle_en_US.properties diff --git a/pom.xml b/pom.xml index f898064..84846d2 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,17 @@ 2.3.1 1.5 + UTF-8 + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.1 + + UTF-8 @@ -62,7 +73,6 @@ 2.7 - org.apache.maven.plugins diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 6b0de07..c4be065 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -87,7 +87,7 @@ public class JCommanderTest { @Test public void i18nFrLocale() { - i18n1("MessageBundle", new Locale("fr", "FR"), "H™te"); + i18n1("MessageBundle", new Locale("fr", "FR"), "Hôte"); } @Test @@ -97,7 +97,7 @@ public class JCommanderTest { Locale.setDefault(new Locale("fr", "FR")); JCommander jc = new JCommander(i18n, argv); ParameterDescription pd = jc.getParameters().get(0); - Assert.assertEquals(pd.getDescription(), "H™te"); + Assert.assertEquals(pd.getDescription(), "Hôte"); } @Test diff --git a/src/test/resources/MessageBundle.properties b/src/test/resources/MessageBundle.properties deleted file mode 100644 index 2125848..0000000 --- a/src/test/resources/MessageBundle.properties +++ /dev/null @@ -1,2 +0,0 @@ -host = Host - diff --git a/src/test/resources/MessageBundle_en_US.properties b/src/test/resources/MessageBundle_en_US.properties new file mode 100644 index 0000000..65148aa --- /dev/null +++ b/src/test/resources/MessageBundle_en_US.properties @@ -0,0 +1 @@ +host = Host \ No newline at end of file diff --git a/src/test/resources/MessageBundle_fr_FR.properties b/src/test/resources/MessageBundle_fr_FR.properties index c74e3de..bdbaf57 100644 --- a/src/test/resources/MessageBundle_fr_FR.properties +++ b/src/test/resources/MessageBundle_fr_FR.properties @@ -1 +1 @@ -host = Hôte +host = Hôte \ No newline at end of file -- cgit v1.2.3 From 00cd334507ec167fc9a69a788bc139318e9f77a1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 18:31:45 -0700 Subject: Minor fix to pom.xml --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f898064..4f362f6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,10 +4,10 @@ com.beust jcommander jar + JCommander 1.1-SNAPSHOT A Java framework to parse command line options with annotations. - jcommander - http://maven.apache.org + http://beust.com/jcommander The Apache Software License, Version 2.0 -- cgit v1.2.3 From 122e13e253d676b47b23df91f9c5107086ce91ad Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 19:35:49 -0700 Subject: Removed tab --- src/main/java/com/beust/jcommander/ParameterDescription.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 301e376..5dd774b 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -125,7 +125,7 @@ public class ParameterDescription { Object convertedValue = converter.convert(value); if (arity) { @SuppressWarnings("unchecked") - List l = (List) m_field.get(m_object); + List l = (List) m_field.get(m_object); if (l == null) { l = Lists.newArrayList(); m_field.set(m_object, l); -- cgit v1.2.3 From f4af92675def06bbba93e881ae801486224b9b3b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 20:02:36 -0700 Subject: Removed unused field --- src/main/java/com/beust/jcommander/ParameterDescription.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 5dd774b..cd4c4f7 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -32,11 +32,6 @@ public class ParameterDescription { put(boolean.class, BooleanConverter.class); }}; - /** - * A map of converters per field. Will take precedence over the class converter map. - */ - private Map m_fieldConverters = Maps.newHashMap(); - private Object m_object; private Parameter m_parameterAnnotation; private Field m_field; -- cgit v1.2.3 From e94313e57b9066fd289fe7b8effa5c19bb53c950 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 16 Jul 2010 22:04:44 -0700 Subject: Excluding internal package from javadoc --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 14d802c..cfa59ff 100644 --- a/pom.xml +++ b/pom.xml @@ -71,6 +71,9 @@ org.apache.maven.plugins maven-javadoc-plugin 2.7 + + *.internal + -- cgit v1.2.3 From c7cf5ca352f2f8259e960b2345a47a00b997cefc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 17 Jul 2010 12:03:14 -0700 Subject: Added snapshot repo --- pom.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cfa59ff..df3a708 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,15 @@ Cedric Beust - + + + + + snapshot-repository + Sonatype snapshot repository + https://oss.sonatype.org/content/repositories/snapshots + + -- cgit v1.2.3 From d3b9e34aed415eba172befec79d2261c3ac38123 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 10:54:24 -0700 Subject: Added arity boolean parameters () --- pom.xml | 13 +++++-------- src/main/java/com/beust/jcommander/JCommander.java | 16 ++++++++-------- src/test/java/com/beust/jcommander/JCommanderTest.java | 8 +++++++- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index df3a708..d11c686 100644 --- a/pom.xml +++ b/pom.xml @@ -26,19 +26,16 @@ - - - snapshot-repository - Sonatype snapshot repository - https://oss.sonatype.org/content/repositories/snapshots - - + + org.sonatype.oss + oss-parent + 3 + - org.apache.maven.plugins maven-source-plugin diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index bdc36f7..7f62949 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,8 +1,5 @@ package com.beust.jcommander; -import com.beust.jcommander.converters.IntegerConverter; -import com.beust.jcommander.converters.LongConverter; -import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.Lists; import com.beust.jcommander.internal.Maps; @@ -13,7 +10,6 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -253,7 +249,8 @@ public class JCommander { pd.addValue(new String(password)); } else { Class fieldType = pd.getField().getType(); - if (fieldType == boolean.class || fieldType == Boolean.class) { + if ((fieldType == boolean.class || fieldType == Boolean.class) + && pd.getParameter().arity() == -1) { pd.addValue("true"); m_requiredFields.remove(pd.getField()); } else { @@ -275,7 +272,7 @@ public class JCommander { } } else { - if (! isStringEmpty(args[i])) getMainParameter().add(args[i]); + if (! isStringEmpty(args[i])) getMainParameter(args[i]).add(args[i]); } } } @@ -286,11 +283,14 @@ public class JCommander { /** * @return the field that's meant to receive all the parameters that are not options. + * + * @param arg the arg that we're about to add (only passed here to ouput a meaningful + * error message). */ - private List getMainParameter() { + private List getMainParameter(String arg) { if (m_mainParameterField == null) { throw new ParameterException( - "Non option parameters were found but no main parameter was defined"); + "Was passed main parameter '" + arg + "' but no main parameter was defined"); } try { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index c4be065..2b63ea4 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -164,12 +164,18 @@ public class JCommanderTest { Assert.assertEquals(args.days.get(1), "Thursday"); } + public void booleanArity() { + ArgsBooleanArity args = new ArgsBooleanArity(); + new JCommander(args, "-debug", "true"); + Assert.assertEquals(args.debug, Boolean.TRUE); + } + public static void main(String[] args) { // ArgsPassword a = new ArgsPassword(); // new JCommander(a, "-password"); // System.out.println("Received:" + a.password); // Assert.assertEquals(args.getVerbose().intValue(), 3); - new JCommanderTest().i18nWithResourceAnnotation(); + new JCommanderTest().converterArgs(); // new JCommanderTest().multipleUnparsedFail(); } -- cgit v1.2.3 From b45c8d8f7af1d808a9073a436e27002edad3b451 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 13:30:26 -0700 Subject: Added traces with -Djcommander.debug=true --- pom.xml | 19 +++++++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 11 +++++++++++ .../com/beust/jcommander/ParameterDescription.java | 7 +++++++ 3 files changed, 37 insertions(+) diff --git a/pom.xml b/pom.xml index d11c686..b4e8d3b 100644 --- a/pom.xml +++ b/pom.xml @@ -71,6 +71,20 @@ + + + org.apache.maven.plugins @@ -103,7 +117,12 @@ org.testng testng + + 5.13-SNAPSHOT test diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 7f62949..07a451a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -27,6 +27,8 @@ import java.util.ResourceBundle; * @author cbeust */ public class JCommander { + public static final String DEBUG_PROPERTY = "jcommander.debug"; + /** * A map to look up parameter description per option name. */ @@ -233,8 +235,11 @@ public class JCommander { } private void parseValues(String[] args) { +// log("Parsing args" + join(args, " "); + for (int i = 0; i < args.length; i++) { String a = trim(args[i]); + log("Parsing arg:" + a); if (a.startsWith("-")) { ParameterDescription pd = m_descriptions.get(a); if (pd != null) { @@ -329,5 +334,11 @@ public class JCommander { public List getParameters() { return new ArrayList(m_fields.values()); } + + private void log(String string) { + if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { + System.out.println("[JCommander] " + string); + } + } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index cd4c4f7..85daf8e 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -96,6 +96,7 @@ public class ParameterDescription { * any type converter, and if we can't find any, throw an exception. */ public void addValue(String value) { + log("Adding value:" + value + " to parameter:" + m_field); boolean arity = false; if (m_added && ! isMultiOption()) { throw new ParameterException("Can only specify option " + getNames()[0] + " once."); @@ -137,4 +138,10 @@ public class ParameterDescription { e.printStackTrace(); } } + + private void log(String string) { + if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { + System.out.println("[ParameterDescription] " + string); + } + } } -- cgit v1.2.3 From c2559dfb9a77c3c8223c5cfb1eac5cc6bbba488e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 17:33:55 -0700 Subject: Test refactoring --- .../java/com/beust/jcommander/JCommanderTest.java | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 2b63ea4..b7bb64c 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -45,21 +45,21 @@ public class JCommanderTest { /** * Required options with multiple names should work with all names. */ - @Test - public void requiredFields2() { + private void multipleNames(String option) { Args1 args = new Args1(); - String[] argv = { "-log", "2" }; + String[] argv = { option, "2" }; new JCommander(args, argv); + Assert.assertEquals(args.verbose.intValue(), 2); + } + + @Test + public void multipleNames1() { + multipleNames("-log"); } - /** - * Required options with multiple names should work with all names. - */ @Test - public void requiredFields3() { - Args1 args = new Args1(); - String[] argv = { "-verbose", "2" }; - new JCommander(args, argv); + public void multipleNames2() { + multipleNames("-verbose"); } private void i18n1(String bundleName, Locale locale, String expectedString) { @@ -175,8 +175,12 @@ public class JCommanderTest { // new JCommander(a, "-password"); // System.out.println("Received:" + a.password); // Assert.assertEquals(args.getVerbose().intValue(), 3); - new JCommanderTest().converterArgs(); +// new JCommanderTest().i18nWithResourceAnnotation(); // new JCommanderTest().multipleUnparsedFail(); + ArgsI18N2 i18n = new ArgsI18N2(); + String[] argv = { "-host", "localhost" }; + JCommander jc = new JCommander(i18n, argv); + jc.usage(); } // Tests: -- cgit v1.2.3 From 5af6f1671d298ed61820f1d1bd3516fbeb5baa2a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:06:55 -0700 Subject: pom changes --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b4e8d3b..7a38d86 100644 --- a/pom.xml +++ b/pom.xml @@ -16,8 +16,9 @@ - http://github.com/cbeust/jcommander - scm:git:http://github.com/cbeust/jcommander.git + scm:git:git@github.com:cbeust/jcommander.git + scm:git:git@github.com:cbeust/jcommander.git + git@github.com:cbeust/jcommander.git @@ -122,7 +123,7 @@ 5.11 jdk15 --> - 5.13-SNAPSHOT + 5.12.1 test -- cgit v1.2.3 From a8e2fed790c7764d1c3c6aad18a00a5322df08b7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:07:23 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.1 --- pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 7a38d86..c82dcdf 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 com.beust jcommander jar JCommander - 1.1-SNAPSHOT + 1.1 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From ec45a101fb756a532a4275ad72ca51e9c1b2f11c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:07:28 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c82dcdf..0c4cbee 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jcommander jar JCommander - 1.1 + 1.2-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From d768c59a33fb6bb27da7170e059578011f9c5bc4 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:09:49 -0700 Subject: Release script --- release | 1 + 1 file changed, 1 insertion(+) create mode 100644 release diff --git a/release b/release new file mode 100644 index 0000000..9363e09 --- /dev/null +++ b/release @@ -0,0 +1 @@ +release:clean release:prepare -- cgit v1.2.3 From 94312d43de91f466c0d60a13e3173a038534ec73 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:23:23 -0700 Subject: Release script update --- release | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release b/release index 9363e09..81aa5ca 100644 --- a/release +++ b/release @@ -1 +1,3 @@ +# https://oss.sonatype.org/index.html + release:clean release:prepare -- cgit v1.2.3 From 899b9ab691c8cae89dd504bf7a09d577dc0abb73 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:24:13 -0700 Subject: Forgot test file --- src/test/java/com/beust/jcommander/ArgsBooleanArity.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/java/com/beust/jcommander/ArgsBooleanArity.java diff --git a/src/test/java/com/beust/jcommander/ArgsBooleanArity.java b/src/test/java/com/beust/jcommander/ArgsBooleanArity.java new file mode 100644 index 0000000..a352a51 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsBooleanArity.java @@ -0,0 +1,6 @@ +package com.beust.jcommander; + +public class ArgsBooleanArity { + @Parameter(names = "-debug", arity = 1) + Boolean debug = false; +} -- cgit v1.2.3 From 819736592856bda21bb4f5295766f5ba48c7320f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 18 Jul 2010 20:32:51 -0700 Subject: Release script --- release | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release b/release index 81aa5ca..690dfe1 100644 --- a/release +++ b/release @@ -1,3 +1,4 @@ -# https://oss.sonatype.org/index.html +# UI : https://oss.sonatype.org/index.html +# Wiki: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide release:clean release:prepare -- cgit v1.2.3 From cc2a776904ef50e8922fd0fdf074ffe6e90f2296 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 19 Jul 2010 07:46:37 -0700 Subject: Trying release again --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0c4cbee..c62054c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jcommander jar JCommander - 1.2-SNAPSHOT + 1.1-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From b0f8a9773e8fb4e6a2169f9fd65ff58d7caf0c68 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 19 Jul 2010 07:46:59 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c62054c..c82dcdf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jcommander jar JCommander - 1.1-SNAPSHOT + 1.1 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 07a29527f3923106e98cac9df6c62c5522373424 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 19 Jul 2010 09:44:58 -0700 Subject: Release --- release | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release b/release index 690dfe1..edfcf91 100644 --- a/release +++ b/release @@ -1,4 +1,6 @@ # UI : https://oss.sonatype.org/index.html # Wiki: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide +# +# deploy without tagging: mvn deploy -DperformRelease release:clean release:prepare -- cgit v1.2.3 From 6748e075fcac44ee0de0be9f1249d33e9bd29fb9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 19 Jul 2010 10:03:36 -0700 Subject: Updated doc --- doc/index.html | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 73c94c7..ee6b91c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -75,7 +75,7 @@ Assert.assertEquals(jct.verbose.intValue(), 2);

    Types of options

    -JCommander supports many types of options. +The fields representing your parameters can be of any type. Basic types (Integer, Boolean., etc...) are supported by default and you can write type converters to support any other type (File, etc...).

    Boolean

    @@ -92,7 +92,6 @@ Such a parameter does not require any additional parameter on the command line a When a Parameter annotation is found on a field of type String, Integer, int, Long or long, JCommander will parse the following parameter and it will attempt to cast it to the right type: -
     @Parameter(names = "-log", description = "Level of verbosity")
     public Integer verbose = 1;
    @@ -146,6 +145,36 @@ Value for -password (Connection password):
     
     You will need to type the value at this point before JCommander resumes.
     
    +

    Custom types

    + +By default, JCommander parses the command line into basic types only (strings, booleans, integers and longs). Very often, your application actually needs more complex types, such as files, host names, lists, etc... To achieve this, you can write a type converter by implementing the following interface: + +
    +public interface IStringConverter<T> {
    +  T convert(String value);
    +}
    +
    + +For example, here is a converter that turns a string into a File: + +
    +public class FileConverter implements IStringConverter<File> {
    +  @Override
    +  public File convert(String value) {
    +    return new File(value);
    +  }
    +}
    +
    + +Then, all you need to do is declare your field with the correct type and specify the converter as an attribute: + +
    +@Parameter(names = "-file", converter = FileConverter.class)
    +File file;
    +
    + +JCommander ships with a few common converters (e.g. one that turns a comma separated list into a List<String>). +

    Main parameter

    So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a List<String> and it will contain all the parameters that are not options: -- cgit v1.2.3 From 4312bccb3787db4e24d19c16c5786bf2a503a9b9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 20 Jul 2010 22:03:51 -0700 Subject: Throwing ParameterException if bad parameters passed --- doc/index.html | 4 ++-- .../java/com/beust/jcommander/ParameterException.java | 4 ++++ .../beust/jcommander/converters/IntegerConverter.java | 7 ++++++- .../com/beust/jcommander/converters/LongConverter.java | 7 ++++++- src/test/java/com/beust/jcommander/Args1.java | 2 ++ src/test/java/com/beust/jcommander/JCommanderTest.java | 17 ++++++++++++++++- 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/doc/index.html b/doc/index.html index ee6b91c..88eae51 100644 --- a/doc/index.html +++ b/doc/index.html @@ -389,7 +389,7 @@ You can download JCommander from the following locations:
    • Source on github
    • -
    • Jar file
    • +
    • Jar file
    • Or if you are using Maven, add the following dependency to your pom.xml:
      @@ -397,7 +397,7 @@ You can download JCommander from the following locations:
       
         com.beust
         jcommander
      -  1.0
      +  1.1
       
         
      diff --git a/src/main/java/com/beust/jcommander/ParameterException.java b/src/main/java/com/beust/jcommander/ParameterException.java index 5004cd0..81353bf 100644 --- a/src/main/java/com/beust/jcommander/ParameterException.java +++ b/src/main/java/com/beust/jcommander/ParameterException.java @@ -2,6 +2,10 @@ package com.beust.jcommander; public class ParameterException extends RuntimeException { + public ParameterException(Throwable t) { + super(t); + } + public ParameterException(String string) { super(string); } diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java index 2efe058..77c52c2 100644 --- a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java @@ -1,12 +1,17 @@ package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; +import com.beust.jcommander.ParameterException; public class IntegerConverter implements IStringConverter { @Override public Integer convert(String value) { - return Integer.parseInt(value); + try { + return Integer.parseInt(value); + } catch(NumberFormatException ex) { + throw new ParameterException(ex); + } } } diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java index d14fd23..cc3e9b7 100644 --- a/src/main/java/com/beust/jcommander/converters/LongConverter.java +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java @@ -1,12 +1,17 @@ package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; +import com.beust.jcommander.ParameterException; public class LongConverter implements IStringConverter { @Override public Long convert(String value) { - return Long.parseLong(value); + try { + return Long.parseLong(value); + } catch(NumberFormatException ex) { + throw new ParameterException(ex); + } } } diff --git a/src/test/java/com/beust/jcommander/Args1.java b/src/test/java/com/beust/jcommander/Args1.java index 9105d24..6e6074f 100644 --- a/src/test/java/com/beust/jcommander/Args1.java +++ b/src/test/java/com/beust/jcommander/Args1.java @@ -17,4 +17,6 @@ public class Args1 { @Parameter(names = "-debug", description = "Debug mode") public boolean debug = false; + @Parameter(names = "-long", description = "A long number") + public long l; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index b7bb64c..da66a0f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -29,7 +29,7 @@ public class JCommanderTest { Args1 args = new Args1(); String[] argv = { "-log", "2" }; JCommander jc = new JCommander(args, argv); - Assert.assertEquals(jc.getParameters().size(), 3); + Assert.assertEquals(jc.getParameters().size(), 4); } /** @@ -170,6 +170,21 @@ public class JCommanderTest { Assert.assertEquals(args.debug, Boolean.TRUE); } + @Test(expectedExceptions = ParameterException.class) + public void badParameterShouldThrowParameter1Exception() { + Args1 args = new Args1(); + String[] argv = { "-log", "foo" }; + new JCommander(args, argv); + } + + + @Test(expectedExceptions = ParameterException.class) + public void badParameterShouldThrowParameter2Exception() { + Args1 args = new Args1(); + String[] argv = { "-long", "foo" }; + new JCommander(args, argv); + } + public static void main(String[] args) { // ArgsPassword a = new ArgsPassword(); // new JCommander(a, "-password"); -- cgit v1.2.3 From 0a0d8099f7e0c2f2f79e6f9233bcfeb7147995e6 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 20 Jul 2010 22:33:08 -0700 Subject: Usage is sorted and aligned --- src/main/java/com/beust/jcommander/JCommander.java | 34 +++++-- .../com/beust/jcommander/ParameterDescription.java | 16 +++- .../java/com/beust/jcommander/CommandLineArgs.java | 101 +++++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 6 +- 4 files changed, 141 insertions(+), 16 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/CommandLineArgs.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 07a451a..80fa60c 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -10,6 +10,8 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -116,7 +118,7 @@ public class JCommander { if (! m_requiredFields.isEmpty()) { StringBuilder missingFields = new StringBuilder(); for (ParameterDescription pd : m_requiredFields.values()) { - missingFields.append(pd.getNames()[0]).append(" "); + missingFields.append(pd.getNames()).append(" "); } throw new ParameterException("The following options are required: " + missingFields); } @@ -246,10 +248,9 @@ public class JCommander { if (pd.getParameter().password()) { Console console = System.console(); if (console == null) { - throw new ParameterException("No console is available to get parameter " - + pd.getNames()[0]); + throw new ParameterException("No console is available to get parameter " + a); } - System.out.print("Value for " + pd.getNames()[0] + " (" + pd.getDescription() + "):"); + System.out.print("Value for " + a + " (" + pd.getDescription() + "):"); char[] password = console.readPassword(); pd.addValue(new String(password)); } else { @@ -317,12 +318,29 @@ public class JCommander { */ public void usage() { System.out.println("Usage:"); + int longestName = 0; + List sorted = Lists.newArrayList(); for (ParameterDescription pd : m_fields.values()) { - StringBuilder sb = new StringBuilder(); - for (String n : pd.getParameter().names()) { - sb.append(n).append(" "); + sorted.add(pd); + int length = pd.getNames().length(); + if (length > longestName) { + longestName = length; } - System.out.println("\t" + sb.toString() + "\t" + pd.getDescription()); + } + int target = longestName %8 != 0 ? (((longestName + 8) / 8) * 8): longestName; + Collections.sort(sorted, new Comparator() { + @Override + public int compare(ParameterDescription arg0, ParameterDescription arg1) { + return arg0.getNames().compareTo(arg1.getNames()); + } + }); + + for (ParameterDescription pd : sorted) { + int l = target - pd.getNames().length(); + int tabCount = l / 8 + (l % 8 == 0 ? 0 : 1); + StringBuilder tabs = new StringBuilder(); + for (int i = 0; i < tabCount; i++) tabs.append("\t"); + System.out.println("\t" + pd.getNames() + tabs + pd.getDescription()); } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 85daf8e..b1aea92 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -70,14 +70,19 @@ public class ParameterDescription { } } - public String[] getNames() { - return m_parameterAnnotation.names(); - } - public String getDescription() { return m_description; } + public String getNames() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < m_parameterAnnotation.names().length; i++) { + if (i > 0) sb.append(", "); + sb.append(m_parameterAnnotation.names()[i]); + } + return sb.toString(); + } + public Parameter getParameter() { return m_parameterAnnotation; } @@ -99,7 +104,8 @@ public class ParameterDescription { log("Adding value:" + value + " to parameter:" + m_field); boolean arity = false; if (m_added && ! isMultiOption()) { - throw new ParameterException("Can only specify option " + getNames()[0] + " once."); + throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] + + " once."); } Class converterClass = m_parameterAnnotation.converter(); if (converterClass == NoConverter.class) { diff --git a/src/test/java/com/beust/jcommander/CommandLineArgs.java b/src/test/java/com/beust/jcommander/CommandLineArgs.java new file mode 100644 index 0000000..5adae0f --- /dev/null +++ b/src/test/java/com/beust/jcommander/CommandLineArgs.java @@ -0,0 +1,101 @@ +package com.beust.jcommander; + +import com.beust.jcommander.internal.Lists; + +import java.util.List; + +public class CommandLineArgs { + + @Parameter(description = "The XML suite files to run") + public List suiteFiles = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") + public Integer verbose; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-excludedgroups", description ="Comma-separated list of group names to be " + + "run") + public String excludedGroups; + + @Parameter(names = "-d", description ="Output directory") + public String outputDirectory; + + @Parameter(names = "-junit", description ="JUnit mode") + public Boolean junit = Boolean.FALSE; + + @Parameter(names = "-listener", description = "List of .class files or list of class names" + + " implementing ITestListener or ISuiteListener") + public String listener; + + @Parameter(names = "-methodselectors", description = "List of .class files or list of class " + + "names implementing IMethodSelector") + public String methodSelectors; + + @Parameter(names = "-objectfactory", description = "List of .class files or list of class " + + "names implementing ITestRunnerFactory") + public String objectFactory; + + @Parameter(names = "-parallel", description = "Parallel mode (methods, tests or classes)") + public String parallelMode; + + @Parameter(names = "-configfailurepolicy", description = "Configuration failure policy (skip or continue)") + public String configFailurePolicy; + + @Parameter(names = "-threadcount", description = "Number of threads to use when running tests " + + "in parallel") + public Integer threadCount; + + @Parameter(names = "-dataproviderthreadcount", description = "Number of threads to use when " + + "running data providers") + public Integer dataProviderThreadCount; + + @Parameter(names = "-suitename", description = "Default name of test suite, if not specified " + + "in suite definition file or source code") + public String suiteName; + + @Parameter(names = "-testname", description = "Default name of test, if not specified in suite" + + "definition file or source code") + public String testName; + + @Parameter(names = "-reporter", description = "Extended configuration for custom report listener") + public String reporter; + + /** + * Used as map key for the complete list of report listeners provided with the above argument + */ + @Parameter(names = "-reporterslist") + public String reportersList; + + @Parameter(names = "-usedefaultlisteners", description = "Whether to use the default listeners") + public String useDefaultListeners = "true"; + + @Parameter(names = "-skipfailedinvocationcounts") + public Boolean skipFailedInvocationCounts; + + @Parameter(names = "-testclass", description = "The list of test classes") + public String testClass; + + @Parameter(names = "-testnames", description = "The list of test names to run") + public String testNames; + + @Parameter(names = "-testjar", description = "") + public String testJar; + + @Parameter(names = "-testRunFactory", description = "") + public String testRunFactory; + + @Parameter(names = "-port", description = "The port") + public Integer port; + + @Parameter(names = "-host", description = "The host") + public String host; + + @Parameter(names = "-master", description ="Host where the master is") + public String master; + + @Parameter(names = "-slave", description ="Host where the slave is") + public String slave; + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index da66a0f..7c71fc9 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -192,9 +192,9 @@ public class JCommanderTest { // Assert.assertEquals(args.getVerbose().intValue(), 3); // new JCommanderTest().i18nWithResourceAnnotation(); // new JCommanderTest().multipleUnparsedFail(); - ArgsI18N2 i18n = new ArgsI18N2(); - String[] argv = { "-host", "localhost" }; - JCommander jc = new JCommander(i18n, argv); + Object a1 = new CommandLineArgs(); + String[] argv = { "-log", "3" }; + JCommander jc = new JCommander(a1, argv); jc.usage(); } -- cgit v1.2.3 From 2a7a6d405f321cb557d62eb8924ff1bf2bddf0f3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 20 Jul 2010 22:37:47 -0700 Subject: CHANGELOG and pom version update --- CHANGELOG | 10 ++++++++++ pom.xml | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..b9a66b0 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,10 @@ +1.2 + +Usage is now aligned and alphabetically sorted. + +1.1 + +Better internationalization +Password support +Type converters + diff --git a/pom.xml b/pom.xml index c82dcdf..0c4cbee 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jcommander jar JCommander - 1.1 + 1.2-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 5f6f1801b59d729dd3dbce026ab887b503953c61 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 20 Jul 2010 22:39:23 -0700 Subject: Doc update --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 88eae51..6847b28 100644 --- a/doc/index.html +++ b/doc/index.html @@ -389,7 +389,7 @@ You can download JCommander from the following locations:
      • Source on github
      • -
      • Jar file
      • +
      • Jar file
      • Or if you are using Maven, add the following dependency to your pom.xml:
        -- 
        cgit v1.2.3
        
        
        From b10564134cd6e95603198fdb0d910af839f79c6a Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Tue, 20 Jul 2010 23:11:25 -0700
        Subject: Added hidden
        
        ---
         CHANGELOG                                              |  3 ++-
         src/main/java/com/beust/jcommander/JCommander.java     | 10 ++++++----
         src/main/java/com/beust/jcommander/Parameter.java      |  8 ++++++++
         src/test/java/com/beust/jcommander/JCommanderTest.java |  2 +-
         4 files changed, 17 insertions(+), 6 deletions(-)
        
        diff --git a/CHANGELOG b/CHANGELOG
        index b9a66b0..5db4beb 100644
        --- a/CHANGELOG
        +++ b/CHANGELOG
        @@ -1,6 +1,7 @@
         1.2
         
        -Usage is now aligned and alphabetically sorted.
        +Usage is now aligned and alphabetically sorted
        +Added the hidden attribute
         
         1.1
         
        diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
        index 80fa60c..09ea6ed 100644
        --- a/src/main/java/com/beust/jcommander/JCommander.java
        +++ b/src/main/java/com/beust/jcommander/JCommander.java
        @@ -321,10 +321,12 @@ public class JCommander {
             int longestName = 0;
             List sorted = Lists.newArrayList();
             for (ParameterDescription pd : m_fields.values()) {
        -      sorted.add(pd);
        -      int length = pd.getNames().length();
        -      if (length > longestName) {
        -        longestName = length;
        +      if (! pd.getParameter().hidden()) {
        +        sorted.add(pd);
        +        int length = pd.getNames().length();
        +        if (length > longestName) {
        +          longestName = length;
        +        }
               }
             }
             int target = longestName %8 != 0 ? (((longestName + 8) / 8) * 8): longestName;
        diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java
        index 9d4ef62..462a526 100644
        --- a/src/main/java/com/beust/jcommander/Parameter.java
        +++ b/src/main/java/com/beust/jcommander/Parameter.java
        @@ -45,5 +45,13 @@ public @interface Parameter {
            */
           boolean password() default false;
         
        +  /**
        +   * The string converter to use for this field.
        +   */
           Class converter() default NoConverter.class;
        +
        +  /**
        +   * If true, this parameter won't appear in the usage().
        +   */
        +  boolean hidden() default false;
         }
        diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
        index 7c71fc9..251866e 100644
        --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
        +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
        @@ -192,7 +192,7 @@ public class JCommanderTest {
         //    Assert.assertEquals(args.getVerbose().intValue(), 3);
         //    new JCommanderTest().i18nWithResourceAnnotation();
         //    new JCommanderTest().multipleUnparsedFail();
        -    Object a1 = new CommandLineArgs();
        +    Object a1 = new Args1();
             String[] argv = { "-log", "3" };
             JCommander jc = new JCommander(a1, argv);
             jc.usage();
        -- 
        cgit v1.2.3
        
        
        From 010076fc59e6304034a2294ddae646542b2fbbd1 Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Tue, 20 Jul 2010 23:23:32 -0700
        Subject: Better error messages
        
        ---
         src/main/java/com/beust/jcommander/JCommander.java                  | 3 ++-
         src/main/java/com/beust/jcommander/converters/IntegerConverter.java | 2 +-
         src/main/java/com/beust/jcommander/converters/LongConverter.java    | 2 +-
         src/test/java/com/beust/jcommander/JCommanderTest.java              | 2 +-
         4 files changed, 5 insertions(+), 4 deletions(-)
        
        diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
        index 09ea6ed..be2983c 100644
        --- a/src/main/java/com/beust/jcommander/JCommander.java
        +++ b/src/main/java/com/beust/jcommander/JCommander.java
        @@ -100,13 +100,14 @@ public class JCommander {
               // Single object
               m_objects.add(object);
             }
        +
        +    createDescriptions();
           }
         
           /**
            * Parse the command line parameters.
            */
           public void parse(String... args) {
        -    createDescriptions();
             parseValues(expandArgs(args));
             validateOptions();
           }
        diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java
        index 77c52c2..0be0b5d 100644
        --- a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java
        +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java
        @@ -10,7 +10,7 @@ public class IntegerConverter implements IStringConverter {
             try {
               return Integer.parseInt(value);
             } catch(NumberFormatException ex) {
        -      throw new ParameterException(ex);
        +      throw new ParameterException("Couldn't convert \"" + value + "\" to an integer");
             }
           }
         
        diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java
        index cc3e9b7..c785fbc 100644
        --- a/src/main/java/com/beust/jcommander/converters/LongConverter.java
        +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java
        @@ -10,7 +10,7 @@ public class LongConverter implements IStringConverter {
             try {
               return Long.parseLong(value);
             } catch(NumberFormatException ex) {
        -      throw new ParameterException(ex);
        +      throw new ParameterException("Couldn't convert \"" + value + "\" to a long");
             }
           }
         
        diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
        index 251866e..6562ab6 100644
        --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
        +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
        @@ -193,7 +193,7 @@ public class JCommanderTest {
         //    new JCommanderTest().i18nWithResourceAnnotation();
         //    new JCommanderTest().multipleUnparsedFail();
             Object a1 = new Args1();
        -    String[] argv = { "-log", "3" };
        +    String[] argv = new String[] { "-log", "foo" };
             JCommander jc = new JCommander(a1, argv);
             jc.usage();
           }
        -- 
        cgit v1.2.3
        
        
        From 9311fbee357630f8406df0114d4c9b3023561156 Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Tue, 20 Jul 2010 23:26:28 -0700
        Subject: Updated doc with hidden
        
        ---
         doc/index.html | 9 +++++++++
         1 file changed, 9 insertions(+)
        
        diff --git a/doc/index.html b/doc/index.html
        index 6847b28..a7ab730 100644
        --- a/doc/index.html
        +++ b/doc/index.html
        @@ -351,6 +351,15 @@ Usage:
         	-testclass		List of classes
         
        +

        Hiding paramters

        + +If you don't want certain parameters to appear in the usage, you can mark them as "hidden": + +
        +@Parameter(names = "-debug", description = "Debug mode", hidden = true)
        +public boolean debug = false;
        +
        +

        Internationalization

        You can internationalize the descriptions of your parameters. -- cgit v1.2.3 From bbd4079f71757019159ee2a98b32479fb2ef511b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 20 Jul 2010 23:27:00 -0700 Subject: Updated doc with hidden --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index a7ab730..f8becc9 100644 --- a/doc/index.html +++ b/doc/index.html @@ -351,7 +351,7 @@ Usage: -testclass List of classes
    -

    Hiding paramters

    +

    Hiding parameters

    If you don't want certain parameters to appear in the usage, you can mark them as "hidden": -- cgit v1.2.3 From d326f67def5cc55fd7ad3b1c37cc17556f939ebd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 21 Jul 2010 16:15:47 -0700 Subject: Doc typo --- doc/index.html | 2 +- src/test/java/com/beust/jcommander/JCommanderTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index f8becc9..3c77f77 100644 --- a/doc/index.html +++ b/doc/index.html @@ -114,7 +114,7 @@ will cause an exception to be thrown. When a Parameter annotation is found on a field of type List, JCommander will interpret it as an option that can occur multiple times:
    -@Parameter(names = "-host", description = "Level of verbosity")
    +@Parameter(names = "-host", description = "The host")
     public List<String> hosts = new ArrayList<String>();
     
    diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 6562ab6..e8ba9bd 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -194,7 +194,7 @@ public class JCommanderTest { // new JCommanderTest().multipleUnparsedFail(); Object a1 = new Args1(); String[] argv = new String[] { "-log", "foo" }; - JCommander jc = new JCommander(a1, argv); + JCommander jc = new JCommander(a1); jc.usage(); } -- cgit v1.2.3 From 2bf18b767712ce3b24df4be60bc341381432dddd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 21 Jul 2010 17:04:37 -0700 Subject: Inserted a space after description usages --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../com/beust/jcommander/CommandLineArgs2.java | 49 ++++++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 2 +- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/CommandLineArgs2.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index be2983c..08467b3 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -324,7 +324,7 @@ public class JCommander { for (ParameterDescription pd : m_fields.values()) { if (! pd.getParameter().hidden()) { sorted.add(pd); - int length = pd.getNames().length(); + int length = pd.getNames().length() + 1; if (length > longestName) { longestName = length; } diff --git a/src/test/java/com/beust/jcommander/CommandLineArgs2.java b/src/test/java/com/beust/jcommander/CommandLineArgs2.java new file mode 100644 index 0000000..99613e6 --- /dev/null +++ b/src/test/java/com/beust/jcommander/CommandLineArgs2.java @@ -0,0 +1,49 @@ +package com.beust.jcommander; + +import com.beust.jcommander.converters.FileConverter; + +import java.io.File; + +public class CommandLineArgs2 { + @Parameter(names = { "-v", "--verbose" }, description = "print verbose log messages.") + public boolean verbose = false; + + @Parameter(names = { "-h", "--help" }, description = "show this help.") + public boolean showHelp = false; + + @Parameter(names = { "-F", "--flush-preferences" }, description = "flush gui preferences.") + public boolean flushPreferences = false; + + @Parameter(names = { "-L", "--flush-licensed" }, description = "flush licensed.") + public boolean flushLicensed = false; + + @Parameter(names = { "-I", "--index-file" }, description = "indexes the given file.") + public String indexFile; + + @Parameter(names = { "-b", "--bonjour" }, description = "enable Bonjour.") + public boolean enableBonjour = false; + + @Parameter(names = { "-m", "--md5" }, description = "create an MD5 checksum for the given file.", converter = FileConverter.class) + public File md5File; + + @Parameter(names = { "-c", "--cat" }, description = "'cat' the given Lilith logfile.", converter = FileConverter.class) + public File catFile; + + @Parameter(names = { "-t", "--tail" }, description = "'tail' the given Lilith logfile.", converter = FileConverter.class) + public File tailFile; + + @Parameter(names = { "-p", "--pattern" }, description = "pattern used by 'cat' or 'tail'.") + public String pattern; + + @Parameter(names = { "-f", "--keep-running" }, description = "keep tailing the given Lilith logfile.") + public boolean keepRunning = false; + + @Parameter(names = { "-n", "--number-of-lines" }, description = "number of entries printed by cat or tail") + public Integer numberOfLines = -1; + + @Parameter(names = { "-e", "--export-preferences" }, description = "export preferences into the given file.") + public String exportPreferencesFile; + + @Parameter(names = { "-i", "--import-preferences" }, description = "import preferences from the given file.") + public String importPreferencesFile; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index e8ba9bd..4234d4f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -192,7 +192,7 @@ public class JCommanderTest { // Assert.assertEquals(args.getVerbose().intValue(), 3); // new JCommanderTest().i18nWithResourceAnnotation(); // new JCommanderTest().multipleUnparsedFail(); - Object a1 = new Args1(); + Object a1 = new CommandLineArgs2(); String[] argv = new String[] { "-log", "foo" }; JCommander jc = new JCommander(a1); jc.usage(); -- cgit v1.2.3 From 76c4b6ace154f18794f9eb0c3d6211101bf426d0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 21 Jul 2010 19:05:53 -0700 Subject: Including the option name in the conversion error message --- src/main/java/com/beust/jcommander/Parameter.java | 2 +- .../com/beust/jcommander/ParameterDescription.java | 38 +++++++++++++++++++--- .../beust/jcommander/converters/BaseConverter.java | 21 ++++++++++++ .../jcommander/converters/BooleanConverter.java | 14 ++++++-- .../jcommander/converters/IntegerConverter.java | 9 +++-- .../beust/jcommander/converters/LongConverter.java | 9 +++-- .../com/beust/jcommander/CommandLineArgs2.java | 4 +-- .../java/com/beust/jcommander/JCommanderTest.java | 6 ++-- 8 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/converters/BaseConverter.java diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 462a526..741dbf5 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -48,7 +48,7 @@ public @interface Parameter { /** * The string converter to use for this field. */ - Class converter() default NoConverter.class; + Class> converter() default NoConverter.class; /** * If true, this parameter won't appear in the usage(). diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index b1aea92..6a48a9b 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -7,9 +7,11 @@ import com.beust.jcommander.converters.LongConverter; import com.beust.jcommander.converters.NoConverter; import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.Lists; -import com.beust.jcommander.internal.Maps; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.TypeVariable; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -21,7 +23,7 @@ public class ParameterDescription { /** * A map of converters per class. */ - private static Map, Class> m_classConverters + private static Map, Class>> m_classConverters = new HashMap() {{ put(String.class, StringConverter.class); put(Integer.class, IntegerConverter.class); @@ -107,7 +109,7 @@ public class ParameterDescription { throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] + " once."); } - Class converterClass = m_parameterAnnotation.converter(); + Class> converterClass = m_parameterAnnotation.converter(); if (converterClass == NoConverter.class) { converterClass = m_classConverters.get(m_field.getType()); } @@ -121,9 +123,9 @@ public class ParameterDescription { } m_added = true; - IStringConverter converter; + IStringConverter converter; try { - converter = converterClass.newInstance(); + converter = instantiateConverter(converterClass); Object convertedValue = converter.convert(value); if (arity) { @SuppressWarnings("unchecked") @@ -136,6 +138,8 @@ public class ParameterDescription { } else { m_field.set(m_object, convertedValue); } + } catch (InvocationTargetException e) { + e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { @@ -145,6 +149,30 @@ public class ParameterDescription { } } + private IStringConverter instantiateConverter( + Class> converterClass) + throws IllegalArgumentException, InstantiationException, IllegalAccessException, + InvocationTargetException { + Constructor> ctor = null; + Constructor> stringCtor = null; + Constructor>[] ctors + = (Constructor>[]) converterClass.getDeclaredConstructors(); + for (Constructor> c : ctors) { + Class[] types = c.getParameterTypes(); + if (types.length == 1 && types[0].equals(String.class)) { + stringCtor = c; + } else if (types.length == 0) { + ctor = c; + } + } + + IStringConverter result = stringCtor != null + ? stringCtor.newInstance(m_parameterAnnotation.names()[0]) + : ctor.newInstance(); + + return result; + } + private void log(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { System.out.println("[ParameterDescription] " + string); diff --git a/src/main/java/com/beust/jcommander/converters/BaseConverter.java b/src/main/java/com/beust/jcommander/converters/BaseConverter.java new file mode 100644 index 0000000..94ceaf8 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/BaseConverter.java @@ -0,0 +1,21 @@ +package com.beust.jcommander.converters; + +import com.beust.jcommander.IStringConverter; + +abstract public class BaseConverter implements IStringConverter { + + private String m_optionName; + + public BaseConverter(String optionName) { + m_optionName = optionName; + } + + public String getOptionName() { + return m_optionName; + } + + protected String getErrorString(String value, String to) { + return "\"" + getOptionName() + "\": couldn't convert \"" + value + "\" to " + to; + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java index 52cd74c..30fdf1a 100644 --- a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java @@ -1,12 +1,20 @@ package com.beust.jcommander.converters; -import com.beust.jcommander.IStringConverter; +import com.beust.jcommander.ParameterException; -public class BooleanConverter implements IStringConverter { +public class BooleanConverter extends BaseConverter { + + public BooleanConverter(String optionName) { + super(optionName); + } @Override public Boolean convert(String value) { - return Boolean.parseBoolean(value); + if ("false".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value)) { + return Boolean.parseBoolean(value); + } else { + throw new ParameterException(getErrorString(value, "a boolean")); + } } } diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java index 0be0b5d..4fdf77e 100644 --- a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java @@ -1,16 +1,19 @@ package com.beust.jcommander.converters; -import com.beust.jcommander.IStringConverter; import com.beust.jcommander.ParameterException; -public class IntegerConverter implements IStringConverter { +public class IntegerConverter extends BaseConverter { + + public IntegerConverter(String optionName) { + super(optionName); + } @Override public Integer convert(String value) { try { return Integer.parseInt(value); } catch(NumberFormatException ex) { - throw new ParameterException("Couldn't convert \"" + value + "\" to an integer"); + throw new ParameterException(getErrorString(value, "an integer")); } } diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java index c785fbc..b3cec97 100644 --- a/src/main/java/com/beust/jcommander/converters/LongConverter.java +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java @@ -1,16 +1,19 @@ package com.beust.jcommander.converters; -import com.beust.jcommander.IStringConverter; import com.beust.jcommander.ParameterException; -public class LongConverter implements IStringConverter { +public class LongConverter extends BaseConverter { + + public LongConverter(String optionName) { + super(optionName); + } @Override public Long convert(String value) { try { return Long.parseLong(value); } catch(NumberFormatException ex) { - throw new ParameterException("Couldn't convert \"" + value + "\" to a long"); + throw new ParameterException(getErrorString(value, "a long")); } } diff --git a/src/test/java/com/beust/jcommander/CommandLineArgs2.java b/src/test/java/com/beust/jcommander/CommandLineArgs2.java index 99613e6..50f8ec7 100644 --- a/src/test/java/com/beust/jcommander/CommandLineArgs2.java +++ b/src/test/java/com/beust/jcommander/CommandLineArgs2.java @@ -5,7 +5,7 @@ import com.beust.jcommander.converters.FileConverter; import java.io.File; public class CommandLineArgs2 { - @Parameter(names = { "-v", "--verbose" }, description = "print verbose log messages.") + @Parameter(names = { "-v", "--verbose" }, description = "print verbose log messages.", arity = 1) public boolean verbose = false; @Parameter(names = { "-h", "--help" }, description = "show this help.") @@ -18,7 +18,7 @@ public class CommandLineArgs2 { public boolean flushLicensed = false; @Parameter(names = { "-I", "--index-file" }, description = "indexes the given file.") - public String indexFile; + public Long indexFile; @Parameter(names = { "-b", "--bonjour" }, description = "enable Bonjour.") public boolean enableBonjour = false; diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 4234d4f..7c3f1cd 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -193,8 +193,10 @@ public class JCommanderTest { // new JCommanderTest().i18nWithResourceAnnotation(); // new JCommanderTest().multipleUnparsedFail(); Object a1 = new CommandLineArgs2(); - String[] argv = new String[] { "-log", "foo" }; - JCommander jc = new JCommander(a1); +// String[] argv = new String[] { "-n", "foo" }; +// String[] argv = new String[] { "-v", "t" }; + String[] argv = new String[] { "-I", "t" }; + JCommander jc = new JCommander(a1, argv); jc.usage(); } -- cgit v1.2.3 From 07fd8c45f06c52a2de0d8f60d43b86c57d377631 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 21 Jul 2010 19:17:03 -0700 Subject: Minor fix by Todd Quessenberry --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 08467b3..70d0a52 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -270,7 +270,7 @@ public class JCommander { } i += n; } else { - throw new ParameterException(arity + " parameters expected after " + args[i]); + throw new ParameterException(n + " parameters expected after " + args[i]); } } } -- cgit v1.2.3 From 1a5a124a6c78c9e14fc3b3d027cc0c303e5cd241 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 21 Jul 2010 20:04:09 -0700 Subject: Added Javadoc --- src/main/java/com/beust/jcommander/IStringConverter.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/beust/jcommander/IStringConverter.java b/src/main/java/com/beust/jcommander/IStringConverter.java index 9abd96c..53cd35f 100644 --- a/src/main/java/com/beust/jcommander/IStringConverter.java +++ b/src/main/java/com/beust/jcommander/IStringConverter.java @@ -3,8 +3,19 @@ package com.beust.jcommander; /** * An interface that converts strings to any arbitrary type. * + * If your class implements a constructor that takes a String, this + * constructor will be used to instantiate your converter and the + * parameter will receive the name of the option that's being parsed, + * which can be useful to issue a more useful error message if the + * conversion fails. + * + * You can also extend BaseConverter to make your life easier. + * * @author cbeust */ public interface IStringConverter { + /** + * @return an object of type created from the parameter value. + */ T convert(String value); } -- cgit v1.2.3 From 116f9d2fd1500980bbd36255020bfce5b1deb84a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 21 Jul 2010 21:39:47 -0700 Subject: Minor fixes --- src/main/java/com/beust/jcommander/JCommander.java | 43 +++++++++++++++------- .../java/com/beust/jcommander/JCommanderTest.java | 4 +- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 70d0a52..4cdf0c8 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -153,7 +153,7 @@ public class JCommander { /** * Reads the file specified by filename and returns the file content as a string. - * End of lines are replaced by a space + * End of lines are replaced by a space. * * @param fileName the command line filename * @return the file content as a string. @@ -181,8 +181,7 @@ public class JCommander { } /** - * @param string - * @return + * Remove spaces at both ends and handle double quotes. */ private static String trim(String string) { String result = string.trim(); @@ -195,6 +194,9 @@ public class JCommander { return result; } + /** + * Create the ParameterDescriptions for all the @Parameter found. + */ private void createDescriptions() { m_descriptions = Maps.newHashMap(); @@ -231,22 +233,20 @@ public class JCommander { } } - private void p(String string) { - if (false) { - System.out.println("[JCommander] " + string); - } - } - + /** + * Main method that parses the values and initializes the fields accordingly. + */ private void parseValues(String[] args) { -// log("Parsing args" + join(args, " "); - for (int i = 0; i < args.length; i++) { String a = trim(args[i]); - log("Parsing arg:" + a); + p("Parsing arg:" + a); if (a.startsWith("-")) { ParameterDescription pd = m_descriptions.get(a); if (pd != null) { if (pd.getParameter().password()) { + // + // Password option, use the Console to retrieve the password + // Console console = System.console(); if (console == null) { throw new ParameterException("No console is available to get parameter " + a); @@ -255,12 +255,20 @@ public class JCommander { char[] password = console.readPassword(); 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()); } 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); if (i + n < args.length) { @@ -319,17 +327,23 @@ public class JCommander { */ public void usage() { System.out.println("Usage:"); + + // Will contain the size of the longest option name int longestName = 0; List sorted = Lists.newArrayList(); for (ParameterDescription pd : m_fields.values()) { if (! pd.getParameter().hidden()) { sorted.add(pd); + // +1 to have an extra space between the name and the description int length = pd.getNames().length() + 1; if (length > longestName) { longestName = length; } } } + + // Calculate the tab stop at which all the descriptions should be + // aligned based on the longest option name found. int target = longestName %8 != 0 ? (((longestName + 8) / 8) * 8): longestName; Collections.sort(sorted, new Comparator() { @Override @@ -337,7 +351,8 @@ public class JCommander { return arg0.getNames().compareTo(arg1.getNames()); } }); - + + // Display all the names and descriptions at the right tab position for (ParameterDescription pd : sorted) { int l = target - pd.getNames().length(); int tabCount = l / 8 + (l % 8 == 0 ? 0 : 1); @@ -356,7 +371,7 @@ public class JCommander { return new ArrayList(m_fields.values()); } - private void log(String string) { + private void p(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { System.out.println("[JCommander] " + string); } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 7c3f1cd..69dd45e 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -195,8 +195,8 @@ public class JCommanderTest { Object a1 = new CommandLineArgs2(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; - String[] argv = new String[] { "-I", "t" }; - JCommander jc = new JCommander(a1, argv); + String[] argv = null; // new String[] { "-I", "t" }; + JCommander jc = new JCommander(a1); jc.usage(); } -- cgit v1.2.3 From b2b58d4e3845c1eaa85d7a63cf4632f58e634056 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 22 Jul 2010 09:23:00 -0700 Subject: Fixed List bug --- src/main/java/com/beust/jcommander/JCommander.java | 15 ++++++++++++-- .../com/beust/jcommander/ParameterDescription.java | 12 +++++++---- src/test/java/com/beust/jcommander/Args2.java | 23 ++++++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 22 +++++++++++++++++---- 4 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/Args2.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 4cdf0c8..275ae6b 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -52,6 +52,11 @@ public class JCommander { */ private Object m_mainParameterObject; + /** + * The annotation found on the main parameter field. + */ + private Parameter m_mainParameterAnnotation; + /** * A set of all the fields that are required. During the reflection phase, * this field receives all the fields that are annotated with required=true @@ -216,6 +221,7 @@ public class JCommander { } m_mainParameterField = f; m_mainParameterObject = object; + m_mainParameterAnnotation = p; } else { for (String name : p.names()) { if (m_descriptions.containsKey(name)) { @@ -326,7 +332,12 @@ public class JCommander { * Display a the help on System.out. */ public void usage() { - System.out.println("Usage:"); + StringBuilder sb = new StringBuilder("Usage:
    [options]"); + if (m_mainParameterAnnotation != null) { + sb.append(" " + m_mainParameterAnnotation.description()); + } + sb.append("\n Options:"); + System.out.println(sb.toString()); // Will contain the size of the longest option name int longestName = 0; @@ -358,7 +369,7 @@ public class JCommander { int tabCount = l / 8 + (l % 8 == 0 ? 0 : 1); StringBuilder tabs = new StringBuilder(); for (int i = 0; i < tabCount; i++) tabs.append("\t"); - System.out.println("\t" + pd.getNames() + tabs + pd.getDescription()); + System.out.println(" " + pd.getNames() + tabs + pd.getDescription()); } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 6a48a9b..9493d81 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -11,7 +11,7 @@ import com.beust.jcommander.internal.Lists; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.TypeVariable; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -104,7 +104,7 @@ public class ParameterDescription { */ public void addValue(String value) { log("Adding value:" + value + " to parameter:" + m_field); - boolean arity = false; + boolean isCollection = false; if (m_added && ! isMultiOption()) { throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] + " once."); @@ -115,7 +115,11 @@ public class ParameterDescription { } if (converterClass == null && m_parameterAnnotation.arity() >= 2) { converterClass = StringConverter.class; - arity = true; + isCollection = true; + } + if (converterClass == null && Collection.class.isAssignableFrom(m_field.getType())) { + converterClass = StringConverter.class; + isCollection = true; } if (converterClass == null) { throw new ParameterException("Don't know how to convert " + value @@ -127,7 +131,7 @@ public class ParameterDescription { try { converter = instantiateConverter(converterClass); Object convertedValue = converter.convert(value); - if (arity) { + if (isCollection) { @SuppressWarnings("unchecked") List l = (List) m_field.get(m_object); if (l == null) { diff --git a/src/test/java/com/beust/jcommander/Args2.java b/src/test/java/com/beust/jcommander/Args2.java new file mode 100644 index 0000000..3acf610 --- /dev/null +++ b/src/test/java/com/beust/jcommander/Args2.java @@ -0,0 +1,23 @@ +package com.beust.jcommander; + +import com.beust.jcommander.internal.Lists; + +import java.util.ArrayList; +import java.util.List; + +public class Args2 { + @Parameter(description = "List of parameters") + public List parameters = Lists.newArrayList(); + + @Parameter(names = {"-log", "-verbose"}, description = "Level of verbosity") + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + + @Parameter(names = "-host", description = "The host") + public List hosts = new ArrayList(); +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 69dd45e..babc61d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -185,6 +185,17 @@ public class JCommanderTest { new JCommander(args, argv); } + @Test + public void listParameters() { + Args2 a = new Args2(); + String[] argv = {"-log", "2", "-groups", "unit", "a", "b", "c", "-host", "host2"}; + new JCommander(a, argv); + Assert.assertEquals(a.verbose.intValue(), 2); + Assert.assertEquals(a.groups, "unit"); + Assert.assertEquals(a.hosts, Arrays.asList("host2")); + Assert.assertEquals(a.parameters, Arrays.asList("a", "b", "c")); + } + public static void main(String[] args) { // ArgsPassword a = new ArgsPassword(); // new JCommander(a, "-password"); @@ -192,12 +203,15 @@ public class JCommanderTest { // Assert.assertEquals(args.getVerbose().intValue(), 3); // new JCommanderTest().i18nWithResourceAnnotation(); // new JCommanderTest().multipleUnparsedFail(); - Object a1 = new CommandLineArgs2(); + Args2 a = new Args2(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; - String[] argv = null; // new String[] { "-I", "t" }; - JCommander jc = new JCommander(a1); - jc.usage(); + String[] argv = {"-log", "2", "-groups", "unit", "a", "b", "c", "-host", "host2"}; + JCommander jc = new JCommander(a, argv); + Assert.assertEquals(a.verbose.intValue(), 2); + Assert.assertEquals(a.groups, "unit"); + Assert.assertEquals(a.hosts, Arrays.asList("host2")); + Assert.assertEquals(a.parameters, Arrays.asList("a", "b", "c")); } // Tests: -- cgit v1.2.3 From b8010b01b766d131076f7343be5e36e7014319e3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 23 Jul 2010 10:17:48 -0700 Subject: Introduced @Parameters, moved resourceBundle there --- doc/index.html | 5 ++-- .../com/beust/jcommander/ParameterDescription.java | 28 ++++++++++++++++++---- .../java/com/beust/jcommander/ResourceBundle.java | 5 ++++ .../java/com/beust/jcommander/JCommanderTest.java | 14 ++++++++--- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/doc/index.html b/doc/index.html index 3c77f77..d872d22 100644 --- a/doc/index.html +++ b/doc/index.html @@ -183,7 +183,7 @@ So far, all the @Parameter annotations we have seen had defined an attr public List<String> files = new ArrayList<String>(); @Parameter(names = "-debug", description = "Debugging level") -public Integer verbose = 1; +public Integer debug = 1; will allow you to parse: @@ -192,8 +192,7 @@ will allow you to parse: java Main -debug file1 file2 -and the field files will receive the strings "file1" and -"file2". +and the field files will receive the strings "file1" and "file2".

    Private parameters

    diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 9493d81..1f1746d 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -47,17 +47,35 @@ public class ParameterDescription { init(object, annotation, field, bundle); } + /** + * Find the resource bundle in the annotations. + * @return + */ + private ResourceBundle findResourceBundle(Object o) { + ResourceBundle result = null; + + Parameters p = o.getClass().getAnnotation(Parameters.class); + if (p != null) { + result = ResourceBundle.getBundle(p.resourceBundle(), Locale.getDefault()); + } + else { + com.beust.jcommander.ResourceBundle a = o.getClass().getAnnotation( + com.beust.jcommander.ResourceBundle.class); + if (a != null) { + result = ResourceBundle.getBundle(a.value(), Locale.getDefault()); + } + } + + return result; + } + private void init(Object object, Parameter annotation, Field field, ResourceBundle bundle) { m_object = object; m_parameterAnnotation = annotation; m_field = field; m_bundle = bundle; if (m_bundle == null) { - com.beust.jcommander.ResourceBundle a - = object.getClass().getAnnotation(com.beust.jcommander.ResourceBundle.class); - if (a != null) { - m_bundle = ResourceBundle.getBundle(a.value(), Locale.getDefault()); - } + m_bundle = findResourceBundle(object); } m_description = annotation.description(); diff --git a/src/main/java/com/beust/jcommander/ResourceBundle.java b/src/main/java/com/beust/jcommander/ResourceBundle.java index 789f738..94df0ae 100644 --- a/src/main/java/com/beust/jcommander/ResourceBundle.java +++ b/src/main/java/com/beust/jcommander/ResourceBundle.java @@ -5,6 +5,11 @@ import static java.lang.annotation.ElementType.TYPE; import java.lang.annotation.Retention; import java.lang.annotation.Target; +/** + * @deprecated, use @Parameters + * + * @author cbeust + */ @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({ TYPE }) public @interface ResourceBundle { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index babc61d..5665d0c 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -90,9 +90,7 @@ public class JCommanderTest { i18n1("MessageBundle", new Locale("fr", "FR"), "Hôte"); } - @Test - public void i18nWithResourceAnnotation() { - ArgsI18N2 i18n = new ArgsI18N2(); + private void i18n2(Object i18n) { String[] argv = { "-host", "localhost" }; Locale.setDefault(new Locale("fr", "FR")); JCommander jc = new JCommander(i18n, argv); @@ -100,6 +98,16 @@ public class JCommanderTest { Assert.assertEquals(pd.getDescription(), "Hôte"); } + @Test + public void i18nWithResourceAnnotation() { + i18n2(new ArgsI18N2()); + } + + @Test + public void i18nWithResourceAnnotationNew() { + i18n2(new ArgsI18N2New()); + } + @Test public void multiObjects() { ArgsMaster m = new ArgsMaster(); -- cgit v1.2.3 From 133eecf3498f32ddcfc0930c0b07dd30c702410d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 23 Jul 2010 10:19:03 -0700 Subject: Forgot files --- src/main/java/com/beust/jcommander/Parameters.java | 26 ++++++++++++++++++++++ .../java/com/beust/jcommander/ArgsI18N2New.java | 8 +++++++ 2 files changed, 34 insertions(+) create mode 100644 src/main/java/com/beust/jcommander/Parameters.java create mode 100644 src/test/java/com/beust/jcommander/ArgsI18N2New.java diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java new file mode 100644 index 0000000..1feb224 --- /dev/null +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -0,0 +1,26 @@ +package com.beust.jcommander; + +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * An annotation used to specify settings for parameter parsing. + * + * @author cbeust + */ +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@Target({ TYPE }) +public @interface Parameters { + + /** + * The name of the resource bundle to use for this class. + */ + String resourceBundle() default ""; + + /** + * The character(s) that separate options. + */ + String separators() default " "; +} diff --git a/src/test/java/com/beust/jcommander/ArgsI18N2New.java b/src/test/java/com/beust/jcommander/ArgsI18N2New.java new file mode 100644 index 0000000..a12f121 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsI18N2New.java @@ -0,0 +1,8 @@ +package com.beust.jcommander; + +@Parameters(resourceBundle = "MessageBundle") +public class ArgsI18N2New { + + @Parameter(names = "-host", description = "Host", descriptionKey = "host") + String hostName; +} -- cgit v1.2.3 From 85866a95d6479be731596a838b6f5e793a341f5b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 23 Jul 2010 11:19:54 -0700 Subject: First pass at implementing separators --- src/main/java/com/beust/jcommander/JCommander.java | 57 +++++++++++++++++++--- .../com/beust/jcommander/ParameterDescription.java | 15 ++++-- .../java/com/beust/jcommander/JCommanderTest.java | 28 +++++------ src/test/java/com/beust/jcommander/Separator.java | 8 +++ 4 files changed, 83 insertions(+), 25 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/Separator.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 275ae6b..0fe79b4 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -139,21 +139,64 @@ public class JCommander { * @param originalArgv the original command line parameters * @return the new and enriched command line parameters */ - private static String[] expandArgs(String[] originalArgv) { - List vResult = Lists.newArrayList(); - + private String[] expandArgs(String[] originalArgv) { + List vResult1 = Lists.newArrayList(); + + // + // Expand @ + // for (String arg : originalArgv) { if (arg.startsWith("@")) { String fileName = arg.substring(1); - vResult.addAll(readFile(fileName)); + vResult1.addAll(readFile(fileName)); } else { - vResult.add(arg); + vResult1.add(arg); } } - - return vResult.toArray(new String[vResult.size()]); + + // + // Expand separators + // + List vResult2 = Lists.newArrayList(); + for (int i = 0; i < vResult1.size(); i++) { + String arg = vResult1.get(i); + // TODO: make sure it's really an option and not that it starts with "-" + if (arg.startsWith("-")) { + String sep = getSeparatorFor(arg); + if (! " ".equals(sep)) { + String[] sp = arg.split(sep); + for (String ssp : sp) { + vResult2.add(ssp); + } + } else { + vResult2.add(arg); + } + } else { + vResult2.add(arg); + } + } + + return vResult2.toArray(new String[vResult2.size()]); + } + + private ParameterDescription getDescriptionFor(String arg) { + for (ParameterDescription p : m_descriptions.values()) { + for (String n : p.getParameter().names()) { + if (arg.startsWith(n)) { + return p; + } + } + } + throw new ParameterException("Couldn't find a description for " + arg); + } + + private String getSeparatorFor(String arg) { + ParameterDescription pd = getDescriptionFor(arg); + Parameters p = pd.getObject().getClass().getAnnotation(Parameters.class); + if (p != null) return p.separators(); + else return " "; } /** diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 1f1746d..f990208 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -55,13 +55,12 @@ public class ParameterDescription { ResourceBundle result = null; Parameters p = o.getClass().getAnnotation(Parameters.class); - if (p != null) { + if (p != null && ! isEmpty(p.resourceBundle())) { result = ResourceBundle.getBundle(p.resourceBundle(), Locale.getDefault()); - } - else { + } else { com.beust.jcommander.ResourceBundle a = o.getClass().getAnnotation( com.beust.jcommander.ResourceBundle.class); - if (a != null) { + if (a != null && ! isEmpty(a.value())) { result = ResourceBundle.getBundle(a.value(), Locale.getDefault()); } } @@ -69,6 +68,10 @@ public class ParameterDescription { return result; } + private boolean isEmpty(String s) { + return s == null || "".equals(s); + } + private void init(Object object, Parameter annotation, Field field, ResourceBundle bundle) { m_object = object; m_parameterAnnotation = annotation; @@ -94,6 +97,10 @@ public class ParameterDescription { return m_description; } + public Object getObject() { + return m_object; + } + public String getNames() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < m_parameterAnnotation.names().length; i++) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 5665d0c..a3bcf78 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -203,23 +203,23 @@ public class JCommanderTest { Assert.assertEquals(a.hosts, Arrays.asList("host2")); Assert.assertEquals(a.parameters, Arrays.asList("a", "b", "c")); } - + + @Test + public void separatorTest() { + Separator s = new Separator(); + String[] argv = { "-log=3" }; + new JCommander(s, argv); + Assert.assertEquals(s.log.intValue(), 3); + } + public static void main(String[] args) { -// ArgsPassword a = new ArgsPassword(); -// new JCommander(a, "-password"); -// System.out.println("Received:" + a.password); -// Assert.assertEquals(args.getVerbose().intValue(), 3); -// new JCommanderTest().i18nWithResourceAnnotation(); -// new JCommanderTest().multipleUnparsedFail(); - Args2 a = new Args2(); + new JCommanderTest().separatorTest(); +// Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; - String[] argv = {"-log", "2", "-groups", "unit", "a", "b", "c", "-host", "host2"}; - JCommander jc = new JCommander(a, argv); - Assert.assertEquals(a.verbose.intValue(), 2); - Assert.assertEquals(a.groups, "unit"); - Assert.assertEquals(a.hosts, Arrays.asList("host2")); - Assert.assertEquals(a.parameters, Arrays.asList("a", "b", "c")); +// String[] argv = { "-log=10" }; +// JCommander jc = new JCommander(a, argv); +// Assert.assertEquals(a.log.intValue(), 10); } // Tests: diff --git a/src/test/java/com/beust/jcommander/Separator.java b/src/test/java/com/beust/jcommander/Separator.java new file mode 100644 index 0000000..be69a87 --- /dev/null +++ b/src/test/java/com/beust/jcommander/Separator.java @@ -0,0 +1,8 @@ +package com.beust.jcommander; + +@Parameters(separators = "=") +public class Separator { + + @Parameter(names = "-log") + public Integer log = 2; +} -- cgit v1.2.3 From fe9b1e59d132e6b10819ae8c9dc3300fb3200ae0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 23 Jul 2010 15:18:22 -0700 Subject: More tests --- CHANGELOG | 3 ++ src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../java/com/beust/jcommander/JCommanderTest.java | 33 ++++++++++++++++++++-- src/test/java/com/beust/jcommander/Separator.java | 8 ------ .../java/com/beust/jcommander/SeparatorColon.java | 8 ++++++ .../java/com/beust/jcommander/SeparatorEqual.java | 8 ++++++ .../java/com/beust/jcommander/SeparatorMixed.java | 11 ++++++++ 7 files changed, 61 insertions(+), 12 deletions(-) delete mode 100644 src/test/java/com/beust/jcommander/Separator.java create mode 100644 src/test/java/com/beust/jcommander/SeparatorColon.java create mode 100644 src/test/java/com/beust/jcommander/SeparatorEqual.java create mode 100644 src/test/java/com/beust/jcommander/SeparatorMixed.java diff --git a/CHANGELOG b/CHANGELOG index 5db4beb..cd99fdb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,11 @@ Usage is now aligned and alphabetically sorted Added the hidden attribute +Added support for different separators than " " (e.g. "="). +Deprecated @ResourceBundle, replaced with @Parameters 1.1 +2010/08/15 Better internationalization Password support diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 0fe79b4..4b7b621 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -166,7 +166,7 @@ public class JCommander { if (arg.startsWith("-")) { String sep = getSeparatorFor(arg); if (! " ".equals(sep)) { - String[] sp = arg.split(sep); + String[] sp = arg.split("[" + sep + "]"); for (String ssp : sp) { vResult2.add(ssp); } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index a3bcf78..7f87d62 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -205,15 +205,42 @@ public class JCommanderTest { } @Test - public void separatorTest() { - Separator s = new Separator(); + public void separatorEqual() { + SeparatorEqual s = new SeparatorEqual(); String[] argv = { "-log=3" }; new JCommander(s, argv); Assert.assertEquals(s.log.intValue(), 3); } + @Test + public void separatorColon() { + SeparatorColon s = new SeparatorColon(); + String[] argv = { "-verbose:true" }; + new JCommander(s, argv); + Assert.assertTrue(s.verbose); + } + + @Test + public void separatorBoth() { + SeparatorColon s = new SeparatorColon(); + SeparatorEqual s2 = new SeparatorEqual(); + String[] argv = { "-verbose:true", "-log=3" }; + new JCommander(new Object[] { s, s2 }, argv); + Assert.assertTrue(s.verbose); + Assert.assertEquals(s2.log.intValue(), 3); + } + + @Test + public void separatorMixed1() { + SeparatorMixed s = new SeparatorMixed(); + String[] argv = { "-long:1", "-level=42" }; + new JCommander(s, argv); + Assert.assertEquals(s.l.longValue(), 1l); + Assert.assertEquals(s.level.intValue(), 42); + } + public static void main(String[] args) { - new JCommanderTest().separatorTest(); + new JCommanderTest().separatorMixed1(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; diff --git a/src/test/java/com/beust/jcommander/Separator.java b/src/test/java/com/beust/jcommander/Separator.java deleted file mode 100644 index be69a87..0000000 --- a/src/test/java/com/beust/jcommander/Separator.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.beust.jcommander; - -@Parameters(separators = "=") -public class Separator { - - @Parameter(names = "-log") - public Integer log = 2; -} diff --git a/src/test/java/com/beust/jcommander/SeparatorColon.java b/src/test/java/com/beust/jcommander/SeparatorColon.java new file mode 100644 index 0000000..8dc8421 --- /dev/null +++ b/src/test/java/com/beust/jcommander/SeparatorColon.java @@ -0,0 +1,8 @@ +package com.beust.jcommander; + +@Parameters(separators = ":") +public class SeparatorColon { + + @Parameter(names = "-verbose", arity = 1) + public boolean verbose = false; +} diff --git a/src/test/java/com/beust/jcommander/SeparatorEqual.java b/src/test/java/com/beust/jcommander/SeparatorEqual.java new file mode 100644 index 0000000..64dd08c --- /dev/null +++ b/src/test/java/com/beust/jcommander/SeparatorEqual.java @@ -0,0 +1,8 @@ +package com.beust.jcommander; + +@Parameters(separators = "=") +public class SeparatorEqual { + + @Parameter(names = "-log") + public Integer log = 2; +} diff --git a/src/test/java/com/beust/jcommander/SeparatorMixed.java b/src/test/java/com/beust/jcommander/SeparatorMixed.java new file mode 100644 index 0000000..8229e1f --- /dev/null +++ b/src/test/java/com/beust/jcommander/SeparatorMixed.java @@ -0,0 +1,11 @@ +package com.beust.jcommander; + +@Parameters(separators = ":=") +public class SeparatorMixed { + + @Parameter(names = "-level") + public Integer level = 0; + + @Parameter(names = "-long") + public Long l = 0l; +} -- cgit v1.2.3 From 057d3653da7c514f8bb86a69f8e29f99d27b688d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 23 Jul 2010 15:25:41 -0700 Subject: Documented separators and @Parameters --- doc/index.html | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index d872d22..1982643 100644 --- a/doc/index.html +++ b/doc/index.html @@ -215,6 +215,33 @@ new JCommander(args, "-verbose", "3"); Assert.assertEquals(args.getVerbose().intValue(), 3); +

    Parameter separators

    + +By default, parameters are separated by spaces, but you can change this setting to allow different separators: + +
    +java Main -log:3
    +
    + +or + +
    +java Main -level=42
    +
    + +You define the separator with the @Parameters annotation: + +
    +@Parameters(separators = "=")
    +public class SeparatorEqual {
    +  @Parameter(names = "-level")
    +  public Integer level = 2;
    +}
    +
    + + + +

    Multiple descriptions

    @@ -365,11 +392,11 @@ You can internationalize the descriptions of your parameters.

    -First you use the @ResourceBundle annotation at the top of your class to define the name of your message bundle, and then you use the descriptionKey attribute instead of description on all the @Parameters that require translations. This descriptionKey is the key to the string into your message bundle: +First you use the @Parameters annotation at the top of your class to define the name of your message bundle, and then you use the descriptionKey attribute instead of description on all the @Parameters that require translations. This descriptionKey is the key to the string into your message bundle:

    I18N.java

    -@ResourceBundle("MessageBundle")
    +@Parameters(resourceBundle = "MessageBundle")
     public class ArgsI18N2 {
       @Parameter(names = "-host", description = "Host", descriptionKey = "host")
       String hostName;
    -- 
    cgit v1.2.3
    
    
    From 4c6b53f8cfec18751e7fcda94def2eed4b50ccbb Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 11:56:44 -0700
    Subject: Preparing for release
    
    ---
     doc/index.html | 2 +-
     pom.xml        | 2 +-
     release        | 2 +-
     3 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/doc/index.html b/doc/index.html
    index 1982643..3364dde 100644
    --- a/doc/index.html
    +++ b/doc/index.html
    @@ -285,7 +285,7 @@ JCommander supports the @ syntax, which allows you to put all your options into
     
     

    -

    /tmp/parameters

    +
    /tmp/parameters
     -verbose
     file1
    diff --git a/pom.xml b/pom.xml
    index 0c4cbee..c62054c 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       jcommander
       jar
       JCommander
    -  1.2-SNAPSHOT
    +  1.1-SNAPSHOT
       A Java framework to parse command line options with annotations.
       http://beust.com/jcommander
       
    diff --git a/release b/release
    index edfcf91..90c102a 100644
    --- a/release
    +++ b/release
    @@ -3,4 +3,4 @@
     #
     # deploy without tagging: mvn deploy -DperformRelease
     
    -release:clean release:prepare
    +mvn release:clean release:prepare
    -- 
    cgit v1.2.3
    
    
    From 2ede26932e99cef83431d83c5d91753a310e46df Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 11:57:04 -0700
    Subject: Preparing for release
    
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index c62054c..0c4cbee 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       jcommander
       jar
       JCommander
    -  1.1-SNAPSHOT
    +  1.2-SNAPSHOT
       A Java framework to parse command line options with annotations.
       http://beust.com/jcommander
       
    -- 
    cgit v1.2.3
    
    
    From e16275b7a608a36d73671c319f0b8a2209f0e3ac Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 11:57:32 -0700
    Subject: [maven-release-plugin] prepare release jcommander-1.2
    
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index 0c4cbee..1ec6e08 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       jcommander
       jar
       JCommander
    -  1.2-SNAPSHOT
    +  1.2
       A Java framework to parse command line options with annotations.
       http://beust.com/jcommander
       
    -- 
    cgit v1.2.3
    
    
    From 6eff15de04b5afebbd30765decd57c04ee55fae9 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 11:57:38 -0700
    Subject: [maven-release-plugin] prepare for next development iteration
    
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index 1ec6e08..43fefea 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       jcommander
       jar
       JCommander
    -  1.2
    +  1.3-SNAPSHOT
       A Java framework to parse command line options with annotations.
       http://beust.com/jcommander
       
    -- 
    cgit v1.2.3
    
    
    From dfd10a6a78600d4a273c22078895cc14536ff26b Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 12:04:19 -0700
    Subject: Release
    
    ---
     release | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/release b/release
    index 90c102a..c9a263e 100644
    --- a/release
    +++ b/release
    @@ -2,5 +2,7 @@
     # Wiki: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
     #
     # deploy without tagging: mvn deploy -DperformRelease
    +# mvn release:clean release:prepare release:perform
    +
    +mvn release:perform
     
    -mvn release:clean release:prepare
    -- 
    cgit v1.2.3
    
    
    From e78248b969b0fa0f217ce85e43d39a1d7c055753 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 14:29:56 -0700
    Subject: 1.3
    
    ---
     src/main/java/com/beust/jcommander/JCommander.java    | 15 ++++++---------
     .../java/com/beust/jcommander/CommandLineArgs2.java   |  4 ++++
     .../java/com/beust/jcommander/JCommanderTest.java     | 19 ++++++++++++++++++-
     3 files changed, 28 insertions(+), 10 deletions(-)
    
    diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
    index 4b7b621..b32e293 100644
    --- a/src/main/java/com/beust/jcommander/JCommander.java
    +++ b/src/main/java/com/beust/jcommander/JCommander.java
    @@ -388,30 +388,27 @@ public class JCommander {
         for (ParameterDescription pd : m_fields.values()) {
           if (! pd.getParameter().hidden()) {
             sorted.add(pd);
    -        // +1 to have an extra space between the name and the description
    -        int length = pd.getNames().length() + 1;
    +        // + to have an extra space between the name and the description
    +        int length = pd.getNames().length() + 2;
             if (length > longestName) {
               longestName = length;
             }
           }
         }
     
    -    // Calculate the tab stop at which all the descriptions should be
    -    // aligned based on the longest option name found.
    -    int target = longestName %8 != 0 ? (((longestName + 8) / 8) * 8): longestName;
         Collections.sort(sorted, new Comparator() {
           @Override
           public int compare(ParameterDescription arg0, ParameterDescription arg1) {
    -        return arg0.getNames().compareTo(arg1.getNames());
    +        return arg0.getNames().toLowerCase().compareTo(arg1.getNames().toLowerCase());
           }
         });
     
         // Display all the names and descriptions at the right tab position
         for (ParameterDescription pd : sorted) {
    -      int l = target - pd.getNames().length();
    -      int tabCount = l / 8 + (l % 8 == 0 ? 0 : 1);
    +      int l = pd.getNames().length();
    +      int spaceCount = longestName - l;
           StringBuilder tabs = new StringBuilder();
    -      for (int i = 0; i < tabCount; i++) tabs.append("\t");
    +      for (int i = 0; i < spaceCount; i++) tabs.append(" ");
           System.out.println("    " + pd.getNames() + tabs + pd.getDescription());
         }
       }
    diff --git a/src/test/java/com/beust/jcommander/CommandLineArgs2.java b/src/test/java/com/beust/jcommander/CommandLineArgs2.java
    index 50f8ec7..75e345f 100644
    --- a/src/test/java/com/beust/jcommander/CommandLineArgs2.java
    +++ b/src/test/java/com/beust/jcommander/CommandLineArgs2.java
    @@ -3,8 +3,12 @@ package com.beust.jcommander;
     import com.beust.jcommander.converters.FileConverter;
     
     import java.io.File;
    +import java.util.List;
     
     public class CommandLineArgs2 {
    +  @Parameter(description = "list of files")
    +  List list;
    +
       @Parameter(names = { "-v", "--verbose" }, description = "print verbose log messages.", arity = 1)
       public boolean verbose = false;
     
    diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
    index 7f87d62..17f8b2e 100644
    --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
    +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
    @@ -1,6 +1,7 @@
     package com.beust.jcommander;
     
     import org.testng.Assert;
    +import org.testng.annotations.DataProvider;
     import org.testng.annotations.Test;
     
     import java.util.Arrays;
    @@ -239,8 +240,24 @@ public class JCommanderTest {
         Assert.assertEquals(s.level.intValue(), 42);
       }
     
    +  @DataProvider
    +  public static Object[][] f() {
    +    return new Integer[][] {
    +      new Integer[] { 3, 5, 1 },
    +      new Integer[] { 3, 8, 1 },
    +      new Integer[] { 3, 12, 2 },
    +      new Integer[] { 8, 12, 2 },
    +      new Integer[] { 9, 10, 1 },
    +    };
    +  }
    +
       public static void main(String[] args) {
    -    new JCommanderTest().separatorMixed1();
    +//    for (Object[] p : f()) {
    +//      int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]);
    +//      Assert.assertEquals(tc, ((Integer) p[2]).intValue());
    +//    }
    +//    new JCommanderTest().formatting();
    +    new JCommander(new CommandLineArgs2()).usage();
     //    Separator a = new Separator();
     //    String[] argv = new String[] { "-n", "foo" };
     //    String[] argv = new String[] { "-v", "t" };
    -- 
    cgit v1.2.3
    
    
    From d75b81810031f49f77c59d0fe65f7ff7045ea9e9 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 14:30:57 -0700
    Subject: [maven-release-plugin] prepare release jcommander-1.3
    
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index 43fefea..bad6faf 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       jcommander
       jar
       JCommander
    -  1.3-SNAPSHOT
    +  1.3
       A Java framework to parse command line options with annotations.
       http://beust.com/jcommander
       
    -- 
    cgit v1.2.3
    
    
    From 236e48dd2d1dd18ea8644d0024f5ba11a252bef9 Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sat, 24 Jul 2010 14:31:03 -0700
    Subject: [maven-release-plugin] prepare for next development iteration
    
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index bad6faf..7ec4f44 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       jcommander
       jar
       JCommander
    -  1.3
    +  1.4-SNAPSHOT
       A Java framework to parse command line options with annotations.
       http://beust.com/jcommander
       
    -- 
    cgit v1.2.3
    
    
    From bc108076cf3dc506d4e87e004d8c2e413b995ada Mon Sep 17 00:00:00 2001
    From: Cedric Beust 
    Date: Sun, 25 Jul 2010 07:41:05 -0700
    Subject: 1.3
    
    ---
     doc/index.html                                         | 2 +-
     src/test/java/com/beust/jcommander/JCommanderTest.java | 3 ++-
     src/test/java/com/beust/jcommander/SeparatorEqual.java | 3 +++
     3 files changed, 6 insertions(+), 2 deletions(-)
    
    diff --git a/doc/index.html b/doc/index.html
    index 3364dde..4b78b3d 100644
    --- a/doc/index.html
    +++ b/doc/index.html
    @@ -432,7 +432,7 @@ You can download JCommander from the following locations:
     
       com.beust
       jcommander
    -  1.1
    +  1.3
     
       
    diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 17f8b2e..81e53c0 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -208,9 +208,10 @@ public class JCommanderTest { @Test public void separatorEqual() { SeparatorEqual s = new SeparatorEqual(); - String[] argv = { "-log=3" }; + String[] argv = { "-log=3", "--longoption=10" }; new JCommander(s, argv); Assert.assertEquals(s.log.intValue(), 3); + Assert.assertEquals(s.longOption.intValue(), 10); } @Test diff --git a/src/test/java/com/beust/jcommander/SeparatorEqual.java b/src/test/java/com/beust/jcommander/SeparatorEqual.java index 64dd08c..b507501 100644 --- a/src/test/java/com/beust/jcommander/SeparatorEqual.java +++ b/src/test/java/com/beust/jcommander/SeparatorEqual.java @@ -5,4 +5,7 @@ public class SeparatorEqual { @Parameter(names = "-log") public Integer log = 2; + + @Parameter(names = "--longoption") + public Integer longOption; } -- cgit v1.2.3 From 78fcfb77f843f4636b50d40f69ce60cb0c2ae7bd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 26 Jul 2010 22:15:02 -0700 Subject: Support for IDefaultProvider --- .../com/beust/jcommander/IDefaultProvider.java | 17 +++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 28 ++++++++++++++++++++-- .../java/com/beust/jcommander/ArgsDefault.java | 23 ++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 24 +++++++++++++++++-- 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/IDefaultProvider.java create mode 100644 src/test/java/com/beust/jcommander/ArgsDefault.java diff --git a/src/main/java/com/beust/jcommander/IDefaultProvider.java b/src/main/java/com/beust/jcommander/IDefaultProvider.java new file mode 100644 index 0000000..5ea0bc1 --- /dev/null +++ b/src/main/java/com/beust/jcommander/IDefaultProvider.java @@ -0,0 +1,17 @@ +package com.beust.jcommander; + +/** + * Allows the specification of default values. + * + * @author cbeust + */ +public interface IDefaultProvider { + + /** + * @param optionName The name of the option as specified in the names() attribute + * of the @Parameter option (e.g. "-file"). + * + * @return the default value for this option. + */ + String getDefaultValueFor(String optionName); +} diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index b32e293..7c95d32 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -74,6 +74,8 @@ public class JCommander { private ResourceBundle m_bundle; + private IDefaultProvider m_defaultProvider; + public JCommander(Object object) { init(object, null); } @@ -189,7 +191,7 @@ public class JCommander { } } } - throw new ParameterException("Couldn't find a description for " + arg); + throw new ParameterException("Unknown parameter: " + arg); } private String getSeparatorFor(String arg) { @@ -206,7 +208,7 @@ public class JCommander { * @param fileName the command line filename * @return the file content as a string. */ - public static List readFile(String fileName) { + private static List readFile(String fileName) { List result = Lists.newArrayList(); try { @@ -274,6 +276,7 @@ public class JCommander { ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle); m_fields.put(f, pd); m_descriptions.put(name, pd); + if (p.required()) m_requiredFields.put(f, pd); } } @@ -282,6 +285,15 @@ public class JCommander { } } + private void initializeDefaultValue(ParameterDescription pd) { + String optionName = pd.getParameter().names()[0]; + String def = m_defaultProvider.getDefaultValueFor(optionName); + if (def != null) { + p("Initializing " + optionName + " with default value:" + def); + pd.addValue(def); + } + } + /** * Main method that parses the values and initializes the fields accordingly. */ @@ -427,5 +439,17 @@ public class JCommander { System.out.println("[JCommander] " + string); } } + + /** + * Define the default provider for this instance. + */ + public void setDefaultProvider(IDefaultProvider defaultProvider) { + m_defaultProvider = defaultProvider; + if (m_defaultProvider != null) { + for (ParameterDescription pd : m_descriptions.values()) { + initializeDefaultValue(pd); + } + } + } } diff --git a/src/test/java/com/beust/jcommander/ArgsDefault.java b/src/test/java/com/beust/jcommander/ArgsDefault.java new file mode 100644 index 0000000..60fd553 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsDefault.java @@ -0,0 +1,23 @@ +package com.beust.jcommander; + +import org.testng.collections.Lists; + +import java.util.List; + +public class ArgsDefault { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = "-log", description = "Level of verbosity") + public Integer log = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + + @Parameter(names = "-long", description = "A long number") + public long l; + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 81e53c0..9d6bb83 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -252,13 +252,33 @@ public class JCommanderTest { }; } + @Test + public void defaultProvider1() { + ArgsDefault a = new ArgsDefault(); + JCommander jc = new JCommander(a); + jc.setDefaultProvider(new IDefaultProvider() { + + @Override + public String getDefaultValueFor(String optionName) { + return "-debug".equals(optionName) ? "false" : "42"; + } + + }); + + jc.parse("f"); + + Assert.assertEquals(a.groups, "42"); + Assert.assertEquals(a.l, 42); + Assert.assertEquals(a.log.intValue(), 42); + } + public static void main(String[] args) { // for (Object[] p : f()) { // int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } -// new JCommanderTest().formatting(); - new JCommander(new CommandLineArgs2()).usage(); + new JCommanderTest().defaultProvider1(); +// new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; -- cgit v1.2.3 From 35435b045d8f218d0202c53ea76e316442c6eccc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 26 Jul 2010 22:25:36 -0700 Subject: More tests for default providers --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../com/beust/jcommander/ParameterDescription.java | 15 +++++--- .../java/com/beust/jcommander/ArgsDefault.java | 4 +-- .../java/com/beust/jcommander/JCommanderTest.java | 42 +++++++++++++++++++--- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 7c95d32..16ec4f6 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -290,7 +290,7 @@ public class JCommander { String def = m_defaultProvider.getDefaultValueFor(optionName); if (def != null) { p("Initializing " + optionName + " with default value:" + def); - pd.addValue(def); + pd.addValue(def, false /* don't mark as assigned */); } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index f990208..007c3bb 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -38,7 +38,7 @@ public class ParameterDescription { private Parameter m_parameterAnnotation; private Field m_field; /** Keep track of whether a value was added to flag an error */ - private boolean m_added = false; + private boolean m_assigned = false; private ResourceBundle m_bundle; private String m_description; @@ -123,14 +123,20 @@ public class ParameterDescription { return fieldType.equals(List.class) || fieldType.equals(Set.class); } + public void addValue(String value) { + addValue(value, true /* mark as assigned */); + } + /** * Add the specified value to the field. First look up any field converter, then * any type converter, and if we can't find any, throw an exception. + * + * @param markAdded if true, mark this parameter as assigned */ - public void addValue(String value) { + public void addValue(String value, boolean markAssigned) { log("Adding value:" + value + " to parameter:" + m_field); boolean isCollection = false; - if (m_added && ! isMultiOption()) { + if (m_assigned && ! isMultiOption()) { throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] + " once."); } @@ -151,7 +157,8 @@ public class ParameterDescription { + " to type " + m_field.getType() + " (field: " + m_field.getName() + ")"); } - m_added = true; + if (markAssigned) m_assigned = true; + IStringConverter converter; try { converter = instantiateConverter(converterClass); diff --git a/src/test/java/com/beust/jcommander/ArgsDefault.java b/src/test/java/com/beust/jcommander/ArgsDefault.java index 60fd553..acf71bb 100644 --- a/src/test/java/com/beust/jcommander/ArgsDefault.java +++ b/src/test/java/com/beust/jcommander/ArgsDefault.java @@ -17,7 +17,7 @@ public class ArgsDefault { @Parameter(names = "-debug", description = "Debug mode") public boolean debug = false; - @Parameter(names = "-long", description = "A long number") - public long l; + @Parameter(names = "-level", description = "A long number") + public long level; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9d6bb83..a48441e 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -252,8 +252,7 @@ public class JCommanderTest { }; } - @Test - public void defaultProvider1() { + private ArgsDefault defaultProvider(String... args) { ArgsDefault a = new ArgsDefault(); JCommander jc = new JCommander(a); jc.setDefaultProvider(new IDefaultProvider() { @@ -265,19 +264,52 @@ public class JCommanderTest { }); - jc.parse("f"); + jc.parse(args); + return a; + } + + @Test + public void defaultProvider1() { + ArgsDefault a = defaultProvider("f"); Assert.assertEquals(a.groups, "42"); - Assert.assertEquals(a.l, 42); + Assert.assertEquals(a.level, 42); + Assert.assertEquals(a.log.intValue(), 42); + } + + @Test + public void defaultProvider2() { + ArgsDefault a = defaultProvider("-groups", "foo", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 42); + Assert.assertEquals(a.log.intValue(), 42); + } + + @Test + public void defaultProvider3() { + ArgsDefault a = defaultProvider("-groups", "foo", "-level", "13", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 13); Assert.assertEquals(a.log.intValue(), 42); } + @Test + public void defaultProvider4() { + ArgsDefault a = defaultProvider("-log", "19", "-groups", "foo", "-level", "13", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 13); + Assert.assertEquals(a.log.intValue(), 19); + } + public static void main(String[] args) { // for (Object[] p : f()) { // int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } - new JCommanderTest().defaultProvider1(); + new JCommanderTest().defaultProvider2(); // new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; -- cgit v1.2.3 From eca9dc8ab293c10f16a104e107b402b61c4c76de Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 27 Jul 2010 07:44:31 -0700 Subject: Added PropertyFileDefaultProvider --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../com/beust/jcommander/ParameterDescription.java | 9 ++-- .../PropertyFileDefaultProvider.java | 53 ++++++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 25 ++++++++-- src/test/resources/jcommander.properties | 3 ++ 5 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java create mode 100644 src/test/resources/jcommander.properties diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 16ec4f6..1619e62 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -290,7 +290,7 @@ public class JCommander { String def = m_defaultProvider.getDefaultValueFor(optionName); if (def != null) { p("Initializing " + optionName + " with default value:" + def); - pd.addValue(def, false /* don't mark as assigned */); + pd.addValue(def, true /* default */); } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 007c3bb..69a87f1 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -124,7 +124,7 @@ public class ParameterDescription { } public void addValue(String value) { - addValue(value, true /* mark as assigned */); + addValue(value, false /* not default */); } /** @@ -133,8 +133,9 @@ public class ParameterDescription { * * @param markAdded if true, mark this parameter as assigned */ - public void addValue(String value, boolean markAssigned) { - log("Adding value:" + value + " to parameter:" + m_field); + public void addValue(String value, boolean isDefault) { + log("Adding " + (isDefault ? "default " : "") + "value:" + value + + " to parameter:" + m_field.getName()); boolean isCollection = false; if (m_assigned && ! isMultiOption()) { throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] @@ -157,7 +158,7 @@ public class ParameterDescription { + " to type " + m_field.getType() + " (field: " + m_field.getName() + ")"); } - if (markAssigned) m_assigned = true; + if (! isDefault) m_assigned = true; IStringConverter converter; try { diff --git a/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java b/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java new file mode 100644 index 0000000..50f33a4 --- /dev/null +++ b/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java @@ -0,0 +1,53 @@ +package com.beust.jcommander.defaultprovider; + +import com.beust.jcommander.IDefaultProvider; +import com.beust.jcommander.ParameterException; + +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +/** + * A default provider that reads its default values from a property file. + * + * @author cbeust + */ +public class PropertyFileDefaultProvider implements IDefaultProvider { + public static final String DEFAULT_FILE_NAME = "jcommander.properties"; + private Properties m_properties; + + public PropertyFileDefaultProvider() { + init(DEFAULT_FILE_NAME); + } + + public PropertyFileDefaultProvider(String fileName) { + init(fileName); + } + + private void init(String fileName) { + try { + m_properties = new Properties(); + URL url = ClassLoader.getSystemResource(fileName); + if (url != null) { + m_properties.load(url.openStream()); + } else { + throw new ParameterException("Could not find property file: " + fileName + + " on the class path"); + } + } + catch (IOException e) { + throw new ParameterException("Could not open property file: " + fileName); + } + } + + @Override + public String getDefaultValueFor(String optionName) { + int index = 0; + while (index < optionName.length() && ! Character.isLetterOrDigit(optionName.charAt(index))) { + index++; + } + String key = optionName.substring(index); + return m_properties.getProperty(key); + } + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index a48441e..603cf59 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -1,5 +1,7 @@ package com.beust.jcommander; +import com.beust.jcommander.defaultprovider.PropertyFileDefaultProvider; + import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -253,16 +255,20 @@ public class JCommanderTest { } private ArgsDefault defaultProvider(String... args) { - ArgsDefault a = new ArgsDefault(); - JCommander jc = new JCommander(a); - jc.setDefaultProvider(new IDefaultProvider() { + return defaultProvider(new IDefaultProvider() { @Override public String getDefaultValueFor(String optionName) { return "-debug".equals(optionName) ? "false" : "42"; } - }); + }, args); + } + + private ArgsDefault defaultProvider(IDefaultProvider provider, String... args) { + ArgsDefault a = new ArgsDefault(); + JCommander jc = new JCommander(a); + jc.setDefaultProvider(provider); jc.parse(args); return a; @@ -304,12 +310,21 @@ public class JCommanderTest { Assert.assertEquals(a.log.intValue(), 19); } + @Test + public void propertyFileDefaultProvider1() { + ArgsDefault a = defaultProvider(new PropertyFileDefaultProvider(), "f"); + + Assert.assertEquals(a.groups, "unit"); + Assert.assertEquals(a.level, 17); + Assert.assertEquals(a.log.intValue(), 18); + } + public static void main(String[] args) { // for (Object[] p : f()) { // int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } - new JCommanderTest().defaultProvider2(); + new JCommanderTest().propertyFileDefaultProvider1(); // new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; diff --git a/src/test/resources/jcommander.properties b/src/test/resources/jcommander.properties new file mode 100644 index 0000000..5b47e32 --- /dev/null +++ b/src/test/resources/jcommander.properties @@ -0,0 +1,3 @@ +groups=unit +level=17 +log=18 \ No newline at end of file -- cgit v1.2.3 From c63fd2224e04bc4c02b416da83b8e210abfe35c4 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 27 Jul 2010 11:05:19 -0700 Subject: More DefaultProvider tests --- CHANGELOG | 6 ++ .../com/beust/jcommander/DefaultProviderTest.java | 102 +++++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 67 +------------- 3 files changed, 109 insertions(+), 66 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/DefaultProviderTest.java diff --git a/CHANGELOG b/CHANGELOG index cd99fdb..6dd46ba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,10 @@ +1.4 + +Added IDefaultProvider +Added PropertyFileDefaultProvider + 1.2 +2010/08/25 Usage is now aligned and alphabetically sorted Added the hidden attribute diff --git a/src/test/java/com/beust/jcommander/DefaultProviderTest.java b/src/test/java/com/beust/jcommander/DefaultProviderTest.java new file mode 100644 index 0000000..d2492db --- /dev/null +++ b/src/test/java/com/beust/jcommander/DefaultProviderTest.java @@ -0,0 +1,102 @@ +package com.beust.jcommander; + +import com.beust.jcommander.defaultprovider.PropertyFileDefaultProvider; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class DefaultProviderTest { + private static final IDefaultProvider DEFAULT_PROVIDER = new IDefaultProvider() { + + @Override + public String getDefaultValueFor(String optionName) { + return "-debug".equals(optionName) ? "false" : "42"; + } + + }; + + private ArgsDefault defaultProvider(IDefaultProvider provider, String... args) { + ArgsDefault a = new ArgsDefault(); + JCommander jc = new JCommander(a); + jc.setDefaultProvider(provider); + + jc.parse(args); + return a; + } + + @Test + public void defaultProvider1() { + ArgsDefault a = defaultProvider(DEFAULT_PROVIDER, "f"); + + Assert.assertEquals(a.groups, "42"); + Assert.assertEquals(a.level, 42); + Assert.assertEquals(a.log.intValue(), 42); + } + + @Test + public void defaultProvider2() { + ArgsDefault a = defaultProvider(DEFAULT_PROVIDER, "-groups", "foo", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 42); + Assert.assertEquals(a.log.intValue(), 42); + } + + @Test + public void defaultProvider3() { + ArgsDefault a = defaultProvider(DEFAULT_PROVIDER, "-groups", "foo", "-level", "13", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 13); + Assert.assertEquals(a.log.intValue(), 42); + } + + @Test + public void defaultProvider4() { + ArgsDefault a = defaultProvider(DEFAULT_PROVIDER, + "-log", "19", "-groups", "foo", "-level", "13", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 13); + Assert.assertEquals(a.log.intValue(), 19); + } + + @Test + public void propertyFileDefaultProvider1() { + ArgsDefault a = defaultProvider(new PropertyFileDefaultProvider(), "f"); + + Assert.assertEquals(a.groups, "unit"); + Assert.assertEquals(a.level, 17); + Assert.assertEquals(a.log.intValue(), 18); + } + + @Test + public void propertyFileDefaultProvider2() { + ArgsDefault a = defaultProvider(new PropertyFileDefaultProvider(), "-groups", "foo", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 17); + Assert.assertEquals(a.log.intValue(), 18); + } + + @Test + public void propertyFileDefaultProvider3() { + ArgsDefault a = defaultProvider(new PropertyFileDefaultProvider(), + "-groups", "foo", "-level", "13", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 13); + Assert.assertEquals(a.log.intValue(), 18); + } + + @Test + public void propertyFileDefaultProvider4() { + ArgsDefault a = defaultProvider(new PropertyFileDefaultProvider(), + "-log", "19", "-groups", "foo", "-level", "13", "f"); + + Assert.assertEquals(a.groups, "foo"); + Assert.assertEquals(a.level, 13); + Assert.assertEquals(a.log.intValue(), 19); + } + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 603cf59..971ac80 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -254,77 +254,12 @@ public class JCommanderTest { }; } - private ArgsDefault defaultProvider(String... args) { - return defaultProvider(new IDefaultProvider() { - - @Override - public String getDefaultValueFor(String optionName) { - return "-debug".equals(optionName) ? "false" : "42"; - } - - }, args); - } - - private ArgsDefault defaultProvider(IDefaultProvider provider, String... args) { - ArgsDefault a = new ArgsDefault(); - JCommander jc = new JCommander(a); - jc.setDefaultProvider(provider); - - jc.parse(args); - return a; - } - - @Test - public void defaultProvider1() { - ArgsDefault a = defaultProvider("f"); - - Assert.assertEquals(a.groups, "42"); - Assert.assertEquals(a.level, 42); - Assert.assertEquals(a.log.intValue(), 42); - } - - @Test - public void defaultProvider2() { - ArgsDefault a = defaultProvider("-groups", "foo", "f"); - - Assert.assertEquals(a.groups, "foo"); - Assert.assertEquals(a.level, 42); - Assert.assertEquals(a.log.intValue(), 42); - } - - @Test - public void defaultProvider3() { - ArgsDefault a = defaultProvider("-groups", "foo", "-level", "13", "f"); - - Assert.assertEquals(a.groups, "foo"); - Assert.assertEquals(a.level, 13); - Assert.assertEquals(a.log.intValue(), 42); - } - - @Test - public void defaultProvider4() { - ArgsDefault a = defaultProvider("-log", "19", "-groups", "foo", "-level", "13", "f"); - - Assert.assertEquals(a.groups, "foo"); - Assert.assertEquals(a.level, 13); - Assert.assertEquals(a.log.intValue(), 19); - } - - @Test - public void propertyFileDefaultProvider1() { - ArgsDefault a = defaultProvider(new PropertyFileDefaultProvider(), "f"); - - Assert.assertEquals(a.groups, "unit"); - Assert.assertEquals(a.level, 17); - Assert.assertEquals(a.log.intValue(), 18); - } - public static void main(String[] args) { // for (Object[] p : f()) { // int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } - new JCommanderTest().propertyFileDefaultProvider1(); + new DefaultProviderTest().propertyFileDefaultProvider1(); // new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; -- cgit v1.2.3 From 5f57e62a9aad979f2fe17e6d61ce5d05136661db Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 27 Jul 2010 15:02:56 -0700 Subject: Added support for -- --- src/main/java/com/beust/jcommander/JCommander.java | 65 +++++++++++++++++----- .../com/beust/jcommander/ParameterDescription.java | 6 ++ .../java/com/beust/jcommander/JCommanderTest.java | 16 +++++- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 1619e62..0026d0a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -165,15 +165,20 @@ public class JCommander { for (int i = 0; i < vResult1.size(); i++) { String arg = vResult1.get(i); // TODO: make sure it's really an option and not that it starts with "-" - if (arg.startsWith("-")) { - String sep = getSeparatorFor(arg); - if (! " ".equals(sep)) { - String[] sp = arg.split("[" + sep + "]"); - for (String ssp : sp) { - vResult2.add(ssp); - } - } else { + if (isOption(arg)) { + if ("--".equals(arg)) { vResult2.add(arg); + vResult2.add(vResult1.get(++i)); + } else { + String sep = getSeparatorFor(arg); + if (! " ".equals(sep)) { + String[] sp = arg.split("[" + sep + "]"); + for (String ssp : sp) { + vResult2.add(ssp); + } + } else { + vResult2.add(arg); + } } } else { vResult2.add(arg); @@ -183,6 +188,10 @@ public class JCommander { return vResult2.toArray(new String[vResult2.size()]); } + private boolean isOption(String arg) { + return arg.startsWith("-"); + } + private ParameterDescription getDescriptionFor(String arg) { for (ParameterDescription p : m_descriptions.values()) { for (String n : p.getParameter().names()) { @@ -301,8 +310,35 @@ public class JCommander { for (int i = 0; i < args.length; i++) { String a = trim(args[i]); p("Parsing arg:" + a); - if (a.startsWith("-")) { - ParameterDescription pd = m_descriptions.get(a); +// ParameterDescription previousDescription = null; + + if (isOption(a)) { + ParameterDescription pd = m_descriptions.get(a); +// ParameterDescription pd = null; +// +// if ("--".equals(a)) { +// pd = previousDescription; +// i++; +// } else { +// } +// previousDescription = pd; + + // If we don't find any description, see if the previous parameter is an int + // or a long, and if it is, check to see if the current arg can be parsed + // into a negative integer +// if (pd == null && pd.isNumber()) { +// try { +// Long l = Long.parseLong(a); +// pd = previousDescription; +// i--; +// } +// catch(NumberFormatException ex) { +// // Do nothing, we'll fall through and throw a parameter exception +// } +// } +// +// previousDescription = pd; + if (pd != null) { if (pd.getParameter().password()) { // @@ -331,13 +367,16 @@ public class JCommander { // 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); + int n = (arity != -1 ? arity : 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])); + pd.addValue(trim(args[i + j + offset])); m_requiredFields.remove(pd.getField()); } - i += n; + i += n + offset; } else { throw new ParameterException(n + " parameters expected after " + args[i]); } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 69a87f1..a15f643 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -186,6 +186,12 @@ public class ParameterDescription { } } + public boolean isNumber() { + Class type = m_field.getType(); + return type.equals(Integer.class) || type.equals(int.class) + || type.equals(Long.class) || type.equals(long.class); + } + private IStringConverter instantiateConverter( Class> converterClass) throws IllegalArgumentException, InstantiationException, IllegalAccessException, diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 971ac80..8929d0d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -243,6 +243,20 @@ public class JCommanderTest { Assert.assertEquals(s.level.intValue(), 42); } + @Test + public void negativeNumbers() { + Args1 a = new Args1(); + String[] argv = { "-verbose", "--", "-3", "-long", "--", "-4" }; + new JCommander(a, argv); + Assert.assertEquals(a.verbose.intValue(), -3); + Assert.assertEquals(a.l, -4); + } + + @Test + public void requiredMainParameters() { + // + } + @DataProvider public static Object[][] f() { return new Integer[][] { @@ -259,7 +273,7 @@ public class JCommanderTest { // int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } - new DefaultProviderTest().propertyFileDefaultProvider1(); + new JCommanderTest().negativeNumbers(); // new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; -- cgit v1.2.3 From 7e185fed573b35ea0769f59348e640514da392b0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 27 Jul 2010 22:26:37 -0700 Subject: Showing required parameters in usage --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 4 +++- src/test/java/com/beust/jcommander/JCommanderTest.java | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6dd46ba..a22022b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Added IDefaultProvider Added PropertyFileDefaultProvider +Showing required parameters in the usage 1.2 2010/08/25 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 1619e62..b9c912d 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -421,7 +421,9 @@ public class JCommander { int spaceCount = longestName - l; StringBuilder tabs = new StringBuilder(); for (int i = 0; i < spaceCount; i++) tabs.append(" "); - System.out.println(" " + pd.getNames() + tabs + pd.getDescription()); + System.out.println(" " + + (pd.getParameter().required() ? "* " : " ") + + pd.getNames() + tabs + pd.getDescription()); } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 971ac80..7817651 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -259,8 +259,8 @@ public class JCommanderTest { // int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } - new DefaultProviderTest().propertyFileDefaultProvider1(); -// new JCommander(new CommandLineArgs2()).usage(); +// new DefaultProviderTest().propertyFileDefaultProvider1(); + new JCommander(new Args1()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; -- cgit v1.2.3 From ff21d677513a8fc628476d926a7f9c7a6dec9570 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 27 Jul 2010 22:41:00 -0700 Subject: Usage is now showing required parameters and default value --- CHANGELOG | 2 +- src/main/java/com/beust/jcommander/JCommander.java | 14 +++++++++++++- src/test/java/com/beust/jcommander/JCommanderTest.java | 6 +++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index eb40945..e73ea5f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,7 +2,7 @@ Added IDefaultProvider Added PropertyFileDefaultProvider -Showing required parameters in the usage +Usage is now showing required parameters and default value Added "--" 1.2 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index ee45111..e36e120 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -455,15 +455,27 @@ public class JCommander { }); // Display all the names and descriptions at the right tab position + StringBuilder out = new StringBuilder(); for (ParameterDescription pd : sorted) { int l = pd.getNames().length(); int spaceCount = longestName - l; StringBuilder tabs = new StringBuilder(); for (int i = 0; i < spaceCount; i++) tabs.append(" "); - System.out.println(" " + out.append(" " + (pd.getParameter().required() ? "* " : " ") + pd.getNames() + tabs + pd.getDescription()); + try { + Object def = pd.getField().get(pd.getObject()); + if (def != null) out.append(" (default: " + def + ")"); + } catch (IllegalArgumentException e) { + // ignore + } catch (IllegalAccessException e) { + // ignore + } + out.append("\n"); } + + System.out.println(out); } /** diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index e44e92e..be2fdc8 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -274,9 +274,9 @@ public class JCommanderTest { // Assert.assertEquals(tc, ((Integer) p[2]).intValue()); // } // new DefaultProviderTest().propertyFileDefaultProvider1(); -// new JCommander(new Args1()).usage(); - new JCommanderTest().negativeNumbers(); -// new JCommander(new CommandLineArgs2()).usage(); +// new JCommander(new Args1(), "foo"); +// new JCommanderTest().negativeNumbers(); + new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; -- cgit v1.2.3 From 4ddd0bb457c9fc2ffbc5693142b2f451dbc4d15d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 07:40:30 -0700 Subject: Added addConverterFactory --- .../beust/jcommander/IStringConverterFactory.java | 12 +++++ src/main/java/com/beust/jcommander/JCommander.java | 41 ++++++++++++++--- .../com/beust/jcommander/ParameterDescription.java | 52 ++++++++++++---------- .../internal/DefaultConverterFactory.java | 33 ++++++++++++++ .../com/beust/jcommander/ArgsConverterFactory.java | 12 +++++ .../java/com/beust/jcommander/JCommanderTest.java | 32 +++++++++++-- 6 files changed, 150 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/IStringConverterFactory.java create mode 100644 src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java create mode 100644 src/test/java/com/beust/jcommander/ArgsConverterFactory.java diff --git a/src/main/java/com/beust/jcommander/IStringConverterFactory.java b/src/main/java/com/beust/jcommander/IStringConverterFactory.java new file mode 100644 index 0000000..8a514d7 --- /dev/null +++ b/src/main/java/com/beust/jcommander/IStringConverterFactory.java @@ -0,0 +1,12 @@ +package com.beust.jcommander; + +/** + * A factory for IStringConverter. This interface lets you specify your + * converters in one place instead of having them repeated all over + * your argument classes. + * + * @author cbeust + */ +public interface IStringConverterFactory { + Class> getConverter(Class forType); +} diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index e36e120..d7b2e9d 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,5 +1,6 @@ package com.beust.jcommander; +import com.beust.jcommander.internal.DefaultConverterFactory; import com.beust.jcommander.internal.Lists; import com.beust.jcommander.internal.Maps; @@ -10,6 +11,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -74,8 +76,18 @@ public class JCommander { private ResourceBundle m_bundle; + /** + * A default provider returns default values for the parameters. + */ private IDefaultProvider m_defaultProvider; + /** + * The factories used to look up string converters. + */ + private List m_converterFactories = new ArrayList() {{ + add(new DefaultConverterFactory()); + }}; + public JCommander(Object object) { init(object, null); } @@ -108,17 +120,26 @@ public class JCommander { m_objects.add(object); } - createDescriptions(); } /** * Parse the command line parameters. */ public void parse(String... args) { + createDescriptions(); + initializeDefaultValues(); parseValues(expandArgs(args)); validateOptions(); } + private void initializeDefaultValues() { + if (m_defaultProvider != null) { + for (ParameterDescription pd : m_descriptions.values()) { + initializeDefaultValue(pd); + } + } + } + /** * Make sure that all the required parameters have received a value. */ @@ -282,7 +303,7 @@ public class JCommander { throw new ParameterException("Found the option " + name + " multiple times"); } p("Adding description for " + name); - ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle); + ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle, this); m_fields.put(f, pd); m_descriptions.put(name, pd); @@ -498,11 +519,19 @@ public class JCommander { */ public void setDefaultProvider(IDefaultProvider defaultProvider) { m_defaultProvider = defaultProvider; - if (m_defaultProvider != null) { - for (ParameterDescription pd : m_descriptions.values()) { - initializeDefaultValue(pd); - } + } + + public void addConverterFactory(IStringConverterFactory converterFactory) { + m_converterFactories.add(converterFactory); + } + + public Class> findConverter(Class cls) { + for (IStringConverterFactory f : m_converterFactories) { + Class> result = f.getConverter(cls); + if (result != null) return result; } + + return null; } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index a15f643..186c330 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -20,20 +20,6 @@ import java.util.ResourceBundle; import java.util.Set; public class ParameterDescription { - /** - * A map of converters per class. - */ - private static Map, Class>> m_classConverters - = new HashMap() {{ - put(String.class, StringConverter.class); - put(Integer.class, IntegerConverter.class); - put(int.class, IntegerConverter.class); - put(Long.class, LongConverter.class); - put(long.class, LongConverter.class); - put(Boolean.class, BooleanConverter.class); - put(boolean.class, BooleanConverter.class); - }}; - private Object m_object; private Parameter m_parameterAnnotation; private Field m_field; @@ -41,10 +27,11 @@ public class ParameterDescription { private boolean m_assigned = false; private ResourceBundle m_bundle; private String m_description; + private JCommander m_jCommander; public ParameterDescription(Object object, Parameter annotation, Field field, - ResourceBundle bundle) { - init(object, annotation, field, bundle); + ResourceBundle bundle, JCommander jc) { + init(object, annotation, field, bundle, jc); } /** @@ -72,7 +59,8 @@ public class ParameterDescription { return s == null || "".equals(s); } - private void init(Object object, Parameter annotation, Field field, ResourceBundle bundle) { + private void init(Object object, Parameter annotation, Field field, ResourceBundle bundle, + JCommander jCommander) { m_object = object; m_parameterAnnotation = annotation; m_field = field; @@ -80,6 +68,7 @@ public class ParameterDescription { if (m_bundle == null) { m_bundle = findResourceBundle(object); } + m_jCommander = jCommander; m_description = annotation.description(); if (! "".equals(annotation.descriptionKey())) { @@ -141,28 +130,45 @@ public class ParameterDescription { throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] + " once."); } - Class> converterClass = m_parameterAnnotation.converter(); + + Class type = m_field.getType(); + Class> converterClass = null; + + // + // Try to find a converter on the annotation + // + converterClass = m_parameterAnnotation.converter(); if (converterClass == NoConverter.class) { - converterClass = m_classConverters.get(m_field.getType()); + converterClass = m_jCommander.findConverter(type); } if (converterClass == null && m_parameterAnnotation.arity() >= 2) { converterClass = StringConverter.class; isCollection = true; } - if (converterClass == null && Collection.class.isAssignableFrom(m_field.getType())) { + if (converterClass == null && Collection.class.isAssignableFrom(type)) { converterClass = StringConverter.class; isCollection = true; } + + // +// // +// // Try to find a converter in the factory +// // +// IStringConverter converter = null; +// if (converterClass == null && m_converterFactories != null) { +// // Mmmh, javac requires a cast here +// converter = (IStringConverter) m_converterFactories.getConverter(type); +// } + if (converterClass == null) { throw new ParameterException("Don't know how to convert " + value - + " to type " + m_field.getType() + " (field: " + m_field.getName() + ")"); + + " to type " + type + " (field: " + m_field.getName() + ")"); } if (! isDefault) m_assigned = true; - IStringConverter converter; try { - converter = instantiateConverter(converterClass); + IStringConverter converter = instantiateConverter(converterClass); Object convertedValue = converter.convert(value); if (isCollection) { @SuppressWarnings("unchecked") diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java new file mode 100644 index 0000000..5d9da70 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java @@ -0,0 +1,33 @@ +package com.beust.jcommander.internal; + +import com.beust.jcommander.IStringConverter; +import com.beust.jcommander.IStringConverterFactory; +import com.beust.jcommander.converters.BooleanConverter; +import com.beust.jcommander.converters.IntegerConverter; +import com.beust.jcommander.converters.LongConverter; +import com.beust.jcommander.converters.StringConverter; + +import java.util.Map; + +public class DefaultConverterFactory implements IStringConverterFactory { + /** + * A map of converters per class. + */ + private static Map>> m_classConverters; + + static { + m_classConverters = Maps.newHashMap(); + m_classConverters.put(String.class, StringConverter.class); + m_classConverters.put(Integer.class, IntegerConverter.class); + m_classConverters.put(int.class, IntegerConverter.class); + m_classConverters.put(Long.class, LongConverter.class); + m_classConverters.put(long.class, LongConverter.class); + m_classConverters.put(Boolean.class, BooleanConverter.class); + m_classConverters.put(boolean.class, BooleanConverter.class); + } + + public Class> getConverter(Class forType) { + return m_classConverters.get(forType); + } + +} diff --git a/src/test/java/com/beust/jcommander/ArgsConverterFactory.java b/src/test/java/com/beust/jcommander/ArgsConverterFactory.java new file mode 100644 index 0000000..90c2a5d --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsConverterFactory.java @@ -0,0 +1,12 @@ +package com.beust.jcommander; + +import java.io.File; + +public class ArgsConverterFactory { + + @Parameter(names = "-file") + File file; + + @Parameter(names = "-integer") + Integer integer; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index be2fdc8..751c504 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -1,13 +1,16 @@ package com.beust.jcommander; -import com.beust.jcommander.defaultprovider.PropertyFileDefaultProvider; +import com.beust.jcommander.converters.FileConverter; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.io.File; import java.util.Arrays; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; import java.util.ResourceBundle; public class JCommanderTest { @@ -252,6 +255,29 @@ public class JCommanderTest { Assert.assertEquals(a.l, -4); } + private static final Map>> MAP = new HashMap() {{ + put(File.class, FileConverter.class); + }}; + + private static final IStringConverterFactory CONVERTER_FACTORY = new IStringConverterFactory() { + + @Override + public Class> getConverter(Class forType) { + return MAP.get(forType); + } + + }; + + @Test + public void converterFactory() { + ArgsConverterFactory a = new ArgsConverterFactory(); + JCommander jc = new JCommander(a); + jc.addConverterFactory(CONVERTER_FACTORY); + jc.parse("-file", "/tmp/a"); + + Assert.assertEquals(a.file.getName(), "a"); + } + @Test public void requiredMainParameters() { // @@ -275,8 +301,8 @@ public class JCommanderTest { // } // new DefaultProviderTest().propertyFileDefaultProvider1(); // new JCommander(new Args1(), "foo"); -// new JCommanderTest().negativeNumbers(); - new JCommander(new CommandLineArgs2()).usage(); + new DefaultProviderTest().defaultProvider1(); +// new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; -- cgit v1.2.3 From 103fe3e72907f6f221dda8688e6e6d1b69ddeb73 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 09:16:55 -0700 Subject: Moved tests around --- src/test/java/com/beust/jcommander/Args1.java | 22 ----- src/test/java/com/beust/jcommander/Args2.java | 23 ----- .../com/beust/jcommander/ArgsArityInteger.java | 17 ---- .../java/com/beust/jcommander/ArgsArityString.java | 17 ---- .../com/beust/jcommander/ArgsBooleanArity.java | 6 -- .../java/com/beust/jcommander/ArgsConverter.java | 16 ---- .../com/beust/jcommander/ArgsConverterFactory.java | 12 --- .../java/com/beust/jcommander/ArgsDefault.java | 23 ----- src/test/java/com/beust/jcommander/ArgsI18N1.java | 7 -- src/test/java/com/beust/jcommander/ArgsI18N2.java | 8 -- .../java/com/beust/jcommander/ArgsI18N2New.java | 8 -- src/test/java/com/beust/jcommander/ArgsMaster.java | 11 --- .../com/beust/jcommander/ArgsMultipleUnparsed.java | 15 --- .../java/com/beust/jcommander/ArgsPassword.java | 6 -- .../java/com/beust/jcommander/ArgsPrivate.java | 10 -- src/test/java/com/beust/jcommander/ArgsSlave.java | 11 --- .../java/com/beust/jcommander/ArgsSlaveBogus.java | 11 --- .../java/com/beust/jcommander/CommandLineArgs.java | 101 -------------------- .../com/beust/jcommander/CommandLineArgs2.java | 53 ----------- .../com/beust/jcommander/DefaultProviderTest.java | 1 + .../java/com/beust/jcommander/JCommanderTest.java | 17 ++++ .../java/com/beust/jcommander/SeparatorColon.java | 8 -- .../java/com/beust/jcommander/SeparatorEqual.java | 11 --- .../java/com/beust/jcommander/SeparatorMixed.java | 11 --- src/test/java/com/beust/jcommander/args/Args1.java | 24 +++++ src/test/java/com/beust/jcommander/args/Args2.java | 24 +++++ .../beust/jcommander/args/ArgsArityInteger.java | 19 ++++ .../com/beust/jcommander/args/ArgsArityString.java | 19 ++++ .../beust/jcommander/args/ArgsBooleanArity.java | 8 ++ .../com/beust/jcommander/args/ArgsConverter.java | 17 ++++ .../jcommander/args/ArgsConverterFactory.java | 14 +++ .../com/beust/jcommander/args/ArgsDefault.java | 25 +++++ .../java/com/beust/jcommander/args/ArgsI18N1.java | 9 ++ .../java/com/beust/jcommander/args/ArgsI18N2.java | 11 +++ .../com/beust/jcommander/args/ArgsI18N2New.java | 11 +++ .../java/com/beust/jcommander/args/ArgsMaster.java | 13 +++ .../jcommander/args/ArgsMultipleUnparsed.java | 17 ++++ .../com/beust/jcommander/args/ArgsPassword.java | 8 ++ .../com/beust/jcommander/args/ArgsPrivate.java | 12 +++ .../java/com/beust/jcommander/args/ArgsSlave.java | 13 +++ .../com/beust/jcommander/args/ArgsSlaveBogus.java | 13 +++ .../com/beust/jcommander/args/CommandLineArgs.java | 102 +++++++++++++++++++++ .../beust/jcommander/args/CommandLineArgs2.java | 54 +++++++++++ .../com/beust/jcommander/args/SeparatorColon.java | 11 +++ .../com/beust/jcommander/args/SeparatorEqual.java | 14 +++ .../com/beust/jcommander/args/SeparatorMixed.java | 14 +++ 46 files changed, 470 insertions(+), 407 deletions(-) delete mode 100644 src/test/java/com/beust/jcommander/Args1.java delete mode 100644 src/test/java/com/beust/jcommander/Args2.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsArityInteger.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsArityString.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsBooleanArity.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsConverter.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsConverterFactory.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsDefault.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsI18N1.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsI18N2.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsI18N2New.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsMaster.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsPassword.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsPrivate.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsSlave.java delete mode 100644 src/test/java/com/beust/jcommander/ArgsSlaveBogus.java delete mode 100644 src/test/java/com/beust/jcommander/CommandLineArgs.java delete mode 100644 src/test/java/com/beust/jcommander/CommandLineArgs2.java delete mode 100644 src/test/java/com/beust/jcommander/SeparatorColon.java delete mode 100644 src/test/java/com/beust/jcommander/SeparatorEqual.java delete mode 100644 src/test/java/com/beust/jcommander/SeparatorMixed.java create mode 100644 src/test/java/com/beust/jcommander/args/Args1.java create mode 100644 src/test/java/com/beust/jcommander/args/Args2.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsArityInteger.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsArityString.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsConverter.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsDefault.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsI18N1.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsI18N2.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsI18N2New.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsMaster.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsPassword.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsPrivate.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsSlave.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java create mode 100644 src/test/java/com/beust/jcommander/args/CommandLineArgs.java create mode 100644 src/test/java/com/beust/jcommander/args/CommandLineArgs2.java create mode 100644 src/test/java/com/beust/jcommander/args/SeparatorColon.java create mode 100644 src/test/java/com/beust/jcommander/args/SeparatorEqual.java create mode 100644 src/test/java/com/beust/jcommander/args/SeparatorMixed.java diff --git a/src/test/java/com/beust/jcommander/Args1.java b/src/test/java/com/beust/jcommander/Args1.java deleted file mode 100644 index 6e6074f..0000000 --- a/src/test/java/com/beust/jcommander/Args1.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.beust.jcommander; - -import org.testng.collections.Lists; - -import java.util.List; - -public class Args1 { - @Parameter - public List parameters = Lists.newArrayList(); - - @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity", required = true) - public Integer verbose = 1; - - @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; - - @Parameter(names = "-debug", description = "Debug mode") - public boolean debug = false; - - @Parameter(names = "-long", description = "A long number") - public long l; -} diff --git a/src/test/java/com/beust/jcommander/Args2.java b/src/test/java/com/beust/jcommander/Args2.java deleted file mode 100644 index 3acf610..0000000 --- a/src/test/java/com/beust/jcommander/Args2.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.beust.jcommander; - -import com.beust.jcommander.internal.Lists; - -import java.util.ArrayList; -import java.util.List; - -public class Args2 { - @Parameter(description = "List of parameters") - public List parameters = Lists.newArrayList(); - - @Parameter(names = {"-log", "-verbose"}, description = "Level of verbosity") - public Integer verbose = 1; - - @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; - - @Parameter(names = "-debug", description = "Debug mode") - public boolean debug = false; - - @Parameter(names = "-host", description = "The host") - public List hosts = new ArrayList(); -} diff --git a/src/test/java/com/beust/jcommander/ArgsArityInteger.java b/src/test/java/com/beust/jcommander/ArgsArityInteger.java deleted file mode 100644 index 36d8749..0000000 --- a/src/test/java/com/beust/jcommander/ArgsArityInteger.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.beust.jcommander; - -import java.util.List; - -/** - * Test parameter arity. - * - * @author cbeust - */ -public class ArgsArityInteger { - - @Parameter(names = "-pairs", arity = 2, description = "Pairs") - public List pairs; - - @Parameter(description = "Rest") - public List rest; -} diff --git a/src/test/java/com/beust/jcommander/ArgsArityString.java b/src/test/java/com/beust/jcommander/ArgsArityString.java deleted file mode 100644 index 281d7d2..0000000 --- a/src/test/java/com/beust/jcommander/ArgsArityString.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.beust.jcommander; - -import java.util.List; - -/** - * Test parameter arity. - * - * @author cbeust - */ -public class ArgsArityString { - - @Parameter(names = "-pairs", arity = 2, description = "Pairs") - public List pairs; - - @Parameter(description = "Rest") - public List rest; -} diff --git a/src/test/java/com/beust/jcommander/ArgsBooleanArity.java b/src/test/java/com/beust/jcommander/ArgsBooleanArity.java deleted file mode 100644 index a352a51..0000000 --- a/src/test/java/com/beust/jcommander/ArgsBooleanArity.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.beust.jcommander; - -public class ArgsBooleanArity { - @Parameter(names = "-debug", arity = 1) - Boolean debug = false; -} diff --git a/src/test/java/com/beust/jcommander/ArgsConverter.java b/src/test/java/com/beust/jcommander/ArgsConverter.java deleted file mode 100644 index 9ccd2e3..0000000 --- a/src/test/java/com/beust/jcommander/ArgsConverter.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.beust.jcommander; - -import com.beust.jcommander.converters.CommaSeparatedConverter; -import com.beust.jcommander.converters.FileConverter; - -import java.io.File; -import java.util.List; - -public class ArgsConverter { - - @Parameter(names = "-file", converter = FileConverter.class) - File file; - - @Parameter(names = "-days", converter = CommaSeparatedConverter.class) - List days; -} diff --git a/src/test/java/com/beust/jcommander/ArgsConverterFactory.java b/src/test/java/com/beust/jcommander/ArgsConverterFactory.java deleted file mode 100644 index 90c2a5d..0000000 --- a/src/test/java/com/beust/jcommander/ArgsConverterFactory.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beust.jcommander; - -import java.io.File; - -public class ArgsConverterFactory { - - @Parameter(names = "-file") - File file; - - @Parameter(names = "-integer") - Integer integer; -} diff --git a/src/test/java/com/beust/jcommander/ArgsDefault.java b/src/test/java/com/beust/jcommander/ArgsDefault.java deleted file mode 100644 index acf71bb..0000000 --- a/src/test/java/com/beust/jcommander/ArgsDefault.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.beust.jcommander; - -import org.testng.collections.Lists; - -import java.util.List; - -public class ArgsDefault { - @Parameter - public List parameters = Lists.newArrayList(); - - @Parameter(names = "-log", description = "Level of verbosity") - public Integer log = 1; - - @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; - - @Parameter(names = "-debug", description = "Debug mode") - public boolean debug = false; - - @Parameter(names = "-level", description = "A long number") - public long level; - -} diff --git a/src/test/java/com/beust/jcommander/ArgsI18N1.java b/src/test/java/com/beust/jcommander/ArgsI18N1.java deleted file mode 100644 index bda4ed1..0000000 --- a/src/test/java/com/beust/jcommander/ArgsI18N1.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.beust.jcommander; - -public class ArgsI18N1 { - - @Parameter(names = "-host", description = "Host", descriptionKey = "host") - String hostName; -} diff --git a/src/test/java/com/beust/jcommander/ArgsI18N2.java b/src/test/java/com/beust/jcommander/ArgsI18N2.java deleted file mode 100644 index cd608e0..0000000 --- a/src/test/java/com/beust/jcommander/ArgsI18N2.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.beust.jcommander; - -@ResourceBundle("MessageBundle") -public class ArgsI18N2 { - - @Parameter(names = "-host", description = "Host", descriptionKey = "host") - String hostName; -} diff --git a/src/test/java/com/beust/jcommander/ArgsI18N2New.java b/src/test/java/com/beust/jcommander/ArgsI18N2New.java deleted file mode 100644 index a12f121..0000000 --- a/src/test/java/com/beust/jcommander/ArgsI18N2New.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.beust.jcommander; - -@Parameters(resourceBundle = "MessageBundle") -public class ArgsI18N2New { - - @Parameter(names = "-host", description = "Host", descriptionKey = "host") - String hostName; -} diff --git a/src/test/java/com/beust/jcommander/ArgsMaster.java b/src/test/java/com/beust/jcommander/ArgsMaster.java deleted file mode 100644 index 98e5228..0000000 --- a/src/test/java/com/beust/jcommander/ArgsMaster.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.beust.jcommander; - -/** - * Test multi-object parsing, along with ArgsSlave. - * - * @author cbeust - */ -public class ArgsMaster { - @Parameter(names = "-master") - public String master; -} diff --git a/src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java b/src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java deleted file mode 100644 index a3222f2..0000000 --- a/src/test/java/com/beust/jcommander/ArgsMultipleUnparsed.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.beust.jcommander; - -/** - * Error case if multiple unparsed (without a names attribute) arguments are defined. - * - * @author cbeust - */ -public class ArgsMultipleUnparsed { - - @Parameter(description = "Bogus1") - public String unparsed1; - - @Parameter(description = "Bogus2") - public String unparsed2; -} diff --git a/src/test/java/com/beust/jcommander/ArgsPassword.java b/src/test/java/com/beust/jcommander/ArgsPassword.java deleted file mode 100644 index 1a598a4..0000000 --- a/src/test/java/com/beust/jcommander/ArgsPassword.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.beust.jcommander; - -public class ArgsPassword { - @Parameter(names = "-password", description = "Connection password", password = true) - public String password; -} diff --git a/src/test/java/com/beust/jcommander/ArgsPrivate.java b/src/test/java/com/beust/jcommander/ArgsPrivate.java deleted file mode 100644 index 87ebe5b..0000000 --- a/src/test/java/com/beust/jcommander/ArgsPrivate.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.beust.jcommander; - -public class ArgsPrivate { - @Parameter(names = "-verbose") - private Integer verbose = 1; - - public Integer getVerbose() { - return verbose; - } -} diff --git a/src/test/java/com/beust/jcommander/ArgsSlave.java b/src/test/java/com/beust/jcommander/ArgsSlave.java deleted file mode 100644 index 8f43cc7..0000000 --- a/src/test/java/com/beust/jcommander/ArgsSlave.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.beust.jcommander; - -/** - * Test multi-object parsing, along with ArgsSlave. - * - * @author cbeust - */ -public class ArgsSlave { - @Parameter(names = "-slave") - public String slave; -} diff --git a/src/test/java/com/beust/jcommander/ArgsSlaveBogus.java b/src/test/java/com/beust/jcommander/ArgsSlaveBogus.java deleted file mode 100644 index ed72174..0000000 --- a/src/test/java/com/beust/jcommander/ArgsSlaveBogus.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.beust.jcommander; - -/** - * Same as ArgsMaster class, should cause an error. - * - * @author cbeust - */ -public class ArgsSlaveBogus extends ArgsSlave { - @Parameter(names = "-master") - public String master; -} diff --git a/src/test/java/com/beust/jcommander/CommandLineArgs.java b/src/test/java/com/beust/jcommander/CommandLineArgs.java deleted file mode 100644 index 5adae0f..0000000 --- a/src/test/java/com/beust/jcommander/CommandLineArgs.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.beust.jcommander; - -import com.beust.jcommander.internal.Lists; - -import java.util.List; - -public class CommandLineArgs { - - @Parameter(description = "The XML suite files to run") - public List suiteFiles = Lists.newArrayList(); - - @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") - public Integer verbose; - - @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; - - @Parameter(names = "-excludedgroups", description ="Comma-separated list of group names to be " + - "run") - public String excludedGroups; - - @Parameter(names = "-d", description ="Output directory") - public String outputDirectory; - - @Parameter(names = "-junit", description ="JUnit mode") - public Boolean junit = Boolean.FALSE; - - @Parameter(names = "-listener", description = "List of .class files or list of class names" + - " implementing ITestListener or ISuiteListener") - public String listener; - - @Parameter(names = "-methodselectors", description = "List of .class files or list of class " + - "names implementing IMethodSelector") - public String methodSelectors; - - @Parameter(names = "-objectfactory", description = "List of .class files or list of class " + - "names implementing ITestRunnerFactory") - public String objectFactory; - - @Parameter(names = "-parallel", description = "Parallel mode (methods, tests or classes)") - public String parallelMode; - - @Parameter(names = "-configfailurepolicy", description = "Configuration failure policy (skip or continue)") - public String configFailurePolicy; - - @Parameter(names = "-threadcount", description = "Number of threads to use when running tests " + - "in parallel") - public Integer threadCount; - - @Parameter(names = "-dataproviderthreadcount", description = "Number of threads to use when " + - "running data providers") - public Integer dataProviderThreadCount; - - @Parameter(names = "-suitename", description = "Default name of test suite, if not specified " + - "in suite definition file or source code") - public String suiteName; - - @Parameter(names = "-testname", description = "Default name of test, if not specified in suite" + - "definition file or source code") - public String testName; - - @Parameter(names = "-reporter", description = "Extended configuration for custom report listener") - public String reporter; - - /** - * Used as map key for the complete list of report listeners provided with the above argument - */ - @Parameter(names = "-reporterslist") - public String reportersList; - - @Parameter(names = "-usedefaultlisteners", description = "Whether to use the default listeners") - public String useDefaultListeners = "true"; - - @Parameter(names = "-skipfailedinvocationcounts") - public Boolean skipFailedInvocationCounts; - - @Parameter(names = "-testclass", description = "The list of test classes") - public String testClass; - - @Parameter(names = "-testnames", description = "The list of test names to run") - public String testNames; - - @Parameter(names = "-testjar", description = "") - public String testJar; - - @Parameter(names = "-testRunFactory", description = "") - public String testRunFactory; - - @Parameter(names = "-port", description = "The port") - public Integer port; - - @Parameter(names = "-host", description = "The host") - public String host; - - @Parameter(names = "-master", description ="Host where the master is") - public String master; - - @Parameter(names = "-slave", description ="Host where the slave is") - public String slave; - -} diff --git a/src/test/java/com/beust/jcommander/CommandLineArgs2.java b/src/test/java/com/beust/jcommander/CommandLineArgs2.java deleted file mode 100644 index 75e345f..0000000 --- a/src/test/java/com/beust/jcommander/CommandLineArgs2.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.beust.jcommander; - -import com.beust.jcommander.converters.FileConverter; - -import java.io.File; -import java.util.List; - -public class CommandLineArgs2 { - @Parameter(description = "list of files") - List list; - - @Parameter(names = { "-v", "--verbose" }, description = "print verbose log messages.", arity = 1) - public boolean verbose = false; - - @Parameter(names = { "-h", "--help" }, description = "show this help.") - public boolean showHelp = false; - - @Parameter(names = { "-F", "--flush-preferences" }, description = "flush gui preferences.") - public boolean flushPreferences = false; - - @Parameter(names = { "-L", "--flush-licensed" }, description = "flush licensed.") - public boolean flushLicensed = false; - - @Parameter(names = { "-I", "--index-file" }, description = "indexes the given file.") - public Long indexFile; - - @Parameter(names = { "-b", "--bonjour" }, description = "enable Bonjour.") - public boolean enableBonjour = false; - - @Parameter(names = { "-m", "--md5" }, description = "create an MD5 checksum for the given file.", converter = FileConverter.class) - public File md5File; - - @Parameter(names = { "-c", "--cat" }, description = "'cat' the given Lilith logfile.", converter = FileConverter.class) - public File catFile; - - @Parameter(names = { "-t", "--tail" }, description = "'tail' the given Lilith logfile.", converter = FileConverter.class) - public File tailFile; - - @Parameter(names = { "-p", "--pattern" }, description = "pattern used by 'cat' or 'tail'.") - public String pattern; - - @Parameter(names = { "-f", "--keep-running" }, description = "keep tailing the given Lilith logfile.") - public boolean keepRunning = false; - - @Parameter(names = { "-n", "--number-of-lines" }, description = "number of entries printed by cat or tail") - public Integer numberOfLines = -1; - - @Parameter(names = { "-e", "--export-preferences" }, description = "export preferences into the given file.") - public String exportPreferencesFile; - - @Parameter(names = { "-i", "--import-preferences" }, description = "import preferences from the given file.") - public String importPreferencesFile; -} diff --git a/src/test/java/com/beust/jcommander/DefaultProviderTest.java b/src/test/java/com/beust/jcommander/DefaultProviderTest.java index d2492db..e185b77 100644 --- a/src/test/java/com/beust/jcommander/DefaultProviderTest.java +++ b/src/test/java/com/beust/jcommander/DefaultProviderTest.java @@ -1,5 +1,6 @@ package com.beust.jcommander; +import com.beust.jcommander.args.ArgsDefault; import com.beust.jcommander.defaultprovider.PropertyFileDefaultProvider; import org.testng.Assert; diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 751c504..bd51148 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -1,5 +1,22 @@ package com.beust.jcommander; +import com.beust.jcommander.args.Args1; +import com.beust.jcommander.args.Args2; +import com.beust.jcommander.args.ArgsArityString; +import com.beust.jcommander.args.ArgsBooleanArity; +import com.beust.jcommander.args.ArgsConverter; +import com.beust.jcommander.args.ArgsConverterFactory; +import com.beust.jcommander.args.ArgsI18N1; +import com.beust.jcommander.args.ArgsI18N2; +import com.beust.jcommander.args.ArgsI18N2New; +import com.beust.jcommander.args.ArgsMaster; +import com.beust.jcommander.args.ArgsMultipleUnparsed; +import com.beust.jcommander.args.ArgsPrivate; +import com.beust.jcommander.args.ArgsSlave; +import com.beust.jcommander.args.ArgsSlaveBogus; +import com.beust.jcommander.args.SeparatorColon; +import com.beust.jcommander.args.SeparatorEqual; +import com.beust.jcommander.args.SeparatorMixed; import com.beust.jcommander.converters.FileConverter; import org.testng.Assert; diff --git a/src/test/java/com/beust/jcommander/SeparatorColon.java b/src/test/java/com/beust/jcommander/SeparatorColon.java deleted file mode 100644 index 8dc8421..0000000 --- a/src/test/java/com/beust/jcommander/SeparatorColon.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.beust.jcommander; - -@Parameters(separators = ":") -public class SeparatorColon { - - @Parameter(names = "-verbose", arity = 1) - public boolean verbose = false; -} diff --git a/src/test/java/com/beust/jcommander/SeparatorEqual.java b/src/test/java/com/beust/jcommander/SeparatorEqual.java deleted file mode 100644 index b507501..0000000 --- a/src/test/java/com/beust/jcommander/SeparatorEqual.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.beust.jcommander; - -@Parameters(separators = "=") -public class SeparatorEqual { - - @Parameter(names = "-log") - public Integer log = 2; - - @Parameter(names = "--longoption") - public Integer longOption; -} diff --git a/src/test/java/com/beust/jcommander/SeparatorMixed.java b/src/test/java/com/beust/jcommander/SeparatorMixed.java deleted file mode 100644 index 8229e1f..0000000 --- a/src/test/java/com/beust/jcommander/SeparatorMixed.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.beust.jcommander; - -@Parameters(separators = ":=") -public class SeparatorMixed { - - @Parameter(names = "-level") - public Integer level = 0; - - @Parameter(names = "-long") - public Long l = 0l; -} diff --git a/src/test/java/com/beust/jcommander/args/Args1.java b/src/test/java/com/beust/jcommander/args/Args1.java new file mode 100644 index 0000000..d89ad96 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/Args1.java @@ -0,0 +1,24 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +import org.testng.collections.Lists; + +import java.util.List; + +public class Args1 { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity", required = true) + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + + @Parameter(names = "-long", description = "A long number") + public long l; +} diff --git a/src/test/java/com/beust/jcommander/args/Args2.java b/src/test/java/com/beust/jcommander/args/Args2.java new file mode 100644 index 0000000..dbcb80c --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/Args2.java @@ -0,0 +1,24 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.internal.Lists; + +import java.util.ArrayList; +import java.util.List; + +public class Args2 { + @Parameter(description = "List of parameters") + public List parameters = Lists.newArrayList(); + + @Parameter(names = {"-log", "-verbose"}, description = "Level of verbosity") + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + + @Parameter(names = "-host", description = "The host") + public List hosts = new ArrayList(); +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java b/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java new file mode 100644 index 0000000..cb21cd3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java @@ -0,0 +1,19 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +import java.util.List; + +/** + * Test parameter arity. + * + * @author cbeust + */ +public class ArgsArityInteger { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public List pairs; + + @Parameter(description = "Rest") + public List rest; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsArityString.java b/src/test/java/com/beust/jcommander/args/ArgsArityString.java new file mode 100644 index 0000000..709290b --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsArityString.java @@ -0,0 +1,19 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +import java.util.List; + +/** + * Test parameter arity. + * + * @author cbeust + */ +public class ArgsArityString { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public List pairs; + + @Parameter(description = "Rest") + public List rest; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java b/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java new file mode 100644 index 0000000..8b3c77d --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java @@ -0,0 +1,8 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class ArgsBooleanArity { + @Parameter(names = "-debug", arity = 1) + public Boolean debug = false; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java new file mode 100644 index 0000000..04c98cc --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java @@ -0,0 +1,17 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.converters.CommaSeparatedConverter; +import com.beust.jcommander.converters.FileConverter; + +import java.io.File; +import java.util.List; + +public class ArgsConverter { + + @Parameter(names = "-file", converter = FileConverter.class) + public File file; + + @Parameter(names = "-days", converter = CommaSeparatedConverter.class) + public List days; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java b/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java new file mode 100644 index 0000000..3c5d1d5 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java @@ -0,0 +1,14 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +import java.io.File; + +public class ArgsConverterFactory { + + @Parameter(names = "-file") + public File file; + + @Parameter(names = "-integer") + Integer integer; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsDefault.java b/src/test/java/com/beust/jcommander/args/ArgsDefault.java new file mode 100644 index 0000000..6a853a1 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsDefault.java @@ -0,0 +1,25 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +import org.testng.collections.Lists; + +import java.util.List; + +public class ArgsDefault { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = "-log", description = "Level of verbosity") + public Integer log = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; + + @Parameter(names = "-level", description = "A long number") + public long level; + +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N1.java b/src/test/java/com/beust/jcommander/args/ArgsI18N1.java new file mode 100644 index 0000000..ba9018b --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N1.java @@ -0,0 +1,9 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class ArgsI18N1 { + + @Parameter(names = "-host", description = "Host", descriptionKey = "host") + String hostName; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N2.java b/src/test/java/com/beust/jcommander/args/ArgsI18N2.java new file mode 100644 index 0000000..dd4baf5 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N2.java @@ -0,0 +1,11 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.ResourceBundle; + +@ResourceBundle("MessageBundle") +public class ArgsI18N2 { + + @Parameter(names = "-host", description = "Host", descriptionKey = "host") + String hostName; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java b/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java new file mode 100644 index 0000000..4265160 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java @@ -0,0 +1,11 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(resourceBundle = "MessageBundle") +public class ArgsI18N2New { + + @Parameter(names = "-host", description = "Host", descriptionKey = "host") + String hostName; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsMaster.java b/src/test/java/com/beust/jcommander/args/ArgsMaster.java new file mode 100644 index 0000000..ba78fe5 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsMaster.java @@ -0,0 +1,13 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +/** + * Test multi-object parsing, along with ArgsSlave. + * + * @author cbeust + */ +public class ArgsMaster { + @Parameter(names = "-master") + public String master; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java b/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java new file mode 100644 index 0000000..91583db --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java @@ -0,0 +1,17 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +/** + * Error case if multiple unparsed (without a names attribute) arguments are defined. + * + * @author cbeust + */ +public class ArgsMultipleUnparsed { + + @Parameter(description = "Bogus1") + public String unparsed1; + + @Parameter(description = "Bogus2") + public String unparsed2; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsPassword.java b/src/test/java/com/beust/jcommander/args/ArgsPassword.java new file mode 100644 index 0000000..6fefa17 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsPassword.java @@ -0,0 +1,8 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class ArgsPassword { + @Parameter(names = "-password", description = "Connection password", password = true) + public String password; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsPrivate.java b/src/test/java/com/beust/jcommander/args/ArgsPrivate.java new file mode 100644 index 0000000..885418c --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsPrivate.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class ArgsPrivate { + @Parameter(names = "-verbose") + private Integer verbose = 1; + + public Integer getVerbose() { + return verbose; + } +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsSlave.java b/src/test/java/com/beust/jcommander/args/ArgsSlave.java new file mode 100644 index 0000000..4c5d318 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsSlave.java @@ -0,0 +1,13 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +/** + * Test multi-object parsing, along with ArgsSlave. + * + * @author cbeust + */ +public class ArgsSlave { + @Parameter(names = "-slave") + public String slave; +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java b/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java new file mode 100644 index 0000000..5615984 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java @@ -0,0 +1,13 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +/** + * Same as ArgsMaster class, should cause an error. + * + * @author cbeust + */ +public class ArgsSlaveBogus extends ArgsSlave { + @Parameter(names = "-master") + public String master; +} diff --git a/src/test/java/com/beust/jcommander/args/CommandLineArgs.java b/src/test/java/com/beust/jcommander/args/CommandLineArgs.java new file mode 100644 index 0000000..6374a72 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/CommandLineArgs.java @@ -0,0 +1,102 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.internal.Lists; + +import java.util.List; + +public class CommandLineArgs { + + @Parameter(description = "The XML suite files to run") + public List suiteFiles = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") + public Integer verbose; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-excludedgroups", description ="Comma-separated list of group names to be " + + "run") + public String excludedGroups; + + @Parameter(names = "-d", description ="Output directory") + public String outputDirectory; + + @Parameter(names = "-junit", description ="JUnit mode") + public Boolean junit = Boolean.FALSE; + + @Parameter(names = "-listener", description = "List of .class files or list of class names" + + " implementing ITestListener or ISuiteListener") + public String listener; + + @Parameter(names = "-methodselectors", description = "List of .class files or list of class " + + "names implementing IMethodSelector") + public String methodSelectors; + + @Parameter(names = "-objectfactory", description = "List of .class files or list of class " + + "names implementing ITestRunnerFactory") + public String objectFactory; + + @Parameter(names = "-parallel", description = "Parallel mode (methods, tests or classes)") + public String parallelMode; + + @Parameter(names = "-configfailurepolicy", description = "Configuration failure policy (skip or continue)") + public String configFailurePolicy; + + @Parameter(names = "-threadcount", description = "Number of threads to use when running tests " + + "in parallel") + public Integer threadCount; + + @Parameter(names = "-dataproviderthreadcount", description = "Number of threads to use when " + + "running data providers") + public Integer dataProviderThreadCount; + + @Parameter(names = "-suitename", description = "Default name of test suite, if not specified " + + "in suite definition file or source code") + public String suiteName; + + @Parameter(names = "-testname", description = "Default name of test, if not specified in suite" + + "definition file or source code") + public String testName; + + @Parameter(names = "-reporter", description = "Extended configuration for custom report listener") + public String reporter; + + /** + * Used as map key for the complete list of report listeners provided with the above argument + */ + @Parameter(names = "-reporterslist") + public String reportersList; + + @Parameter(names = "-usedefaultlisteners", description = "Whether to use the default listeners") + public String useDefaultListeners = "true"; + + @Parameter(names = "-skipfailedinvocationcounts") + public Boolean skipFailedInvocationCounts; + + @Parameter(names = "-testclass", description = "The list of test classes") + public String testClass; + + @Parameter(names = "-testnames", description = "The list of test names to run") + public String testNames; + + @Parameter(names = "-testjar", description = "") + public String testJar; + + @Parameter(names = "-testRunFactory", description = "") + public String testRunFactory; + + @Parameter(names = "-port", description = "The port") + public Integer port; + + @Parameter(names = "-host", description = "The host") + public String host; + + @Parameter(names = "-master", description ="Host where the master is") + public String master; + + @Parameter(names = "-slave", description ="Host where the slave is") + public String slave; + +} diff --git a/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java b/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java new file mode 100644 index 0000000..ce1b4cf --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java @@ -0,0 +1,54 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.converters.FileConverter; + +import java.io.File; +import java.util.List; + +public class CommandLineArgs2 { + @Parameter(description = "list of files") + List list; + + @Parameter(names = { "-v", "--verbose" }, description = "print verbose log messages.", arity = 1) + public boolean verbose = false; + + @Parameter(names = { "-h", "--help" }, description = "show this help.") + public boolean showHelp = false; + + @Parameter(names = { "-F", "--flush-preferences" }, description = "flush gui preferences.") + public boolean flushPreferences = false; + + @Parameter(names = { "-L", "--flush-licensed" }, description = "flush licensed.") + public boolean flushLicensed = false; + + @Parameter(names = { "-I", "--index-file" }, description = "indexes the given file.") + public Long indexFile; + + @Parameter(names = { "-b", "--bonjour" }, description = "enable Bonjour.") + public boolean enableBonjour = false; + + @Parameter(names = { "-m", "--md5" }, description = "create an MD5 checksum for the given file.", converter = FileConverter.class) + public File md5File; + + @Parameter(names = { "-c", "--cat" }, description = "'cat' the given Lilith logfile.", converter = FileConverter.class) + public File catFile; + + @Parameter(names = { "-t", "--tail" }, description = "'tail' the given Lilith logfile.", converter = FileConverter.class) + public File tailFile; + + @Parameter(names = { "-p", "--pattern" }, description = "pattern used by 'cat' or 'tail'.") + public String pattern; + + @Parameter(names = { "-f", "--keep-running" }, description = "keep tailing the given Lilith logfile.") + public boolean keepRunning = false; + + @Parameter(names = { "-n", "--number-of-lines" }, description = "number of entries printed by cat or tail") + public Integer numberOfLines = -1; + + @Parameter(names = { "-e", "--export-preferences" }, description = "export preferences into the given file.") + public String exportPreferencesFile; + + @Parameter(names = { "-i", "--import-preferences" }, description = "import preferences from the given file.") + public String importPreferencesFile; +} diff --git a/src/test/java/com/beust/jcommander/args/SeparatorColon.java b/src/test/java/com/beust/jcommander/args/SeparatorColon.java new file mode 100644 index 0000000..7ef2e98 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/SeparatorColon.java @@ -0,0 +1,11 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(separators = ":") +public class SeparatorColon { + + @Parameter(names = "-verbose", arity = 1) + public boolean verbose = false; +} diff --git a/src/test/java/com/beust/jcommander/args/SeparatorEqual.java b/src/test/java/com/beust/jcommander/args/SeparatorEqual.java new file mode 100644 index 0000000..42b47f3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/SeparatorEqual.java @@ -0,0 +1,14 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(separators = "=") +public class SeparatorEqual { + + @Parameter(names = "-log") + public Integer log = 2; + + @Parameter(names = "--longoption") + public Integer longOption; +} diff --git a/src/test/java/com/beust/jcommander/args/SeparatorMixed.java b/src/test/java/com/beust/jcommander/args/SeparatorMixed.java new file mode 100644 index 0000000..4717b1e --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/SeparatorMixed.java @@ -0,0 +1,14 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(separators = ":=") +public class SeparatorMixed { + + @Parameter(names = "-level") + public Integer level = 0; + + @Parameter(names = "-long") + public Long l = 0l; +} -- cgit v1.2.3 From 67b245733f986c6b514f9121702d0c4289e3ae2d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 09:23:50 -0700 Subject: Converter factory test with HostPort --- src/main/java/com/beust/jcommander/JCommander.java | 6 +-- .../internal/DefaultConverterFactory.java | 3 ++ .../com/beust/jcommander/ConverterFactoryTest.java | 54 ++++++++++++++++++++++ src/test/java/com/beust/jcommander/HostPort.java | 6 +++ .../java/com/beust/jcommander/JCommanderTest.java | 23 --------- .../jcommander/args/ArgsConverterFactory.java | 10 ++-- 6 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/ConverterFactoryTest.java create mode 100644 src/test/java/com/beust/jcommander/HostPort.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index d7b2e9d..f2f1fcc 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -84,7 +84,7 @@ public class JCommander { /** * The factories used to look up string converters. */ - private List m_converterFactories = new ArrayList() {{ + private static List CONVERTER_FACTORIES = new ArrayList() {{ add(new DefaultConverterFactory()); }}; @@ -522,11 +522,11 @@ public class JCommander { } public void addConverterFactory(IStringConverterFactory converterFactory) { - m_converterFactories.add(converterFactory); + CONVERTER_FACTORIES.add(converterFactory); } public Class> findConverter(Class cls) { - for (IStringConverterFactory f : m_converterFactories) { + for (IStringConverterFactory f : CONVERTER_FACTORIES) { Class> result = f.getConverter(cls); if (result != null) return result; } diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java index 5d9da70..6781aa6 100644 --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java @@ -3,10 +3,12 @@ package com.beust.jcommander.internal; import com.beust.jcommander.IStringConverter; import com.beust.jcommander.IStringConverterFactory; import com.beust.jcommander.converters.BooleanConverter; +import com.beust.jcommander.converters.FileConverter; import com.beust.jcommander.converters.IntegerConverter; import com.beust.jcommander.converters.LongConverter; import com.beust.jcommander.converters.StringConverter; +import java.io.File; import java.util.Map; public class DefaultConverterFactory implements IStringConverterFactory { @@ -24,6 +26,7 @@ public class DefaultConverterFactory implements IStringConverterFactory { m_classConverters.put(long.class, LongConverter.class); m_classConverters.put(Boolean.class, BooleanConverter.class); m_classConverters.put(boolean.class, BooleanConverter.class); + m_classConverters.put(File.class, FileConverter.class); } public Class> getConverter(Class forType) { diff --git a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java new file mode 100644 index 0000000..0081926 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java @@ -0,0 +1,54 @@ +package com.beust.jcommander; + +import com.beust.jcommander.args.ArgsConverterFactory; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * Test the converter factory feature. + * + * @author cbeust + */ +public class ConverterFactoryTest { + private static final Map>> MAP = new HashMap() {{ + put(HostPort.class, HostPortConverter.class); + }}; + + private static final IStringConverterFactory CONVERTER_FACTORY = new IStringConverterFactory() { + + @Override + public Class> getConverter(Class forType) { + return MAP.get(forType); + } + + }; + + @Test + public void converterFactory() { + ArgsConverterFactory a = new ArgsConverterFactory(); + JCommander jc = new JCommander(a); + jc.addConverterFactory(CONVERTER_FACTORY); + jc.parse("-hostport", "example.com:8080"); + + Assert.assertEquals(a.hostPort.host, "example.com"); + Assert.assertEquals(a.hostPort.port.intValue(), 8080); + } + +} + +class HostPortConverter implements IStringConverter { + + @Override + public HostPort convert(String value) { + HostPort result = new HostPort(); + String[] s = value.split(":"); + result.host = s[0]; + result.port = Integer.parseInt(s[1]); + + return result; + } +} \ No newline at end of file diff --git a/src/test/java/com/beust/jcommander/HostPort.java b/src/test/java/com/beust/jcommander/HostPort.java new file mode 100644 index 0000000..6737d7c --- /dev/null +++ b/src/test/java/com/beust/jcommander/HostPort.java @@ -0,0 +1,6 @@ +package com.beust.jcommander; + +public class HostPort { + public String host; + public Integer port; +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index bd51148..0d4e2ca 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -272,29 +272,6 @@ public class JCommanderTest { Assert.assertEquals(a.l, -4); } - private static final Map>> MAP = new HashMap() {{ - put(File.class, FileConverter.class); - }}; - - private static final IStringConverterFactory CONVERTER_FACTORY = new IStringConverterFactory() { - - @Override - public Class> getConverter(Class forType) { - return MAP.get(forType); - } - - }; - - @Test - public void converterFactory() { - ArgsConverterFactory a = new ArgsConverterFactory(); - JCommander jc = new JCommander(a); - jc.addConverterFactory(CONVERTER_FACTORY); - jc.parse("-file", "/tmp/a"); - - Assert.assertEquals(a.file.getName(), "a"); - } - @Test public void requiredMainParameters() { // diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java b/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java index 3c5d1d5..56f29c0 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java +++ b/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java @@ -1,14 +1,10 @@ package com.beust.jcommander.args; +import com.beust.jcommander.HostPort; import com.beust.jcommander.Parameter; -import java.io.File; - public class ArgsConverterFactory { - @Parameter(names = "-file") - public File file; - - @Parameter(names = "-integer") - Integer integer; + @Parameter(names = "-hostport") + public HostPort hostPort; } -- cgit v1.2.3 From d556f4a527306a9769776d1cbb2fccac98618bc9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 09:49:20 -0700 Subject: Dash dash tests --- src/main/java/com/beust/jcommander/JCommander.java | 35 +++++++++++++--------- src/main/java/com/beust/jcommander/Parameters.java | 7 +++++ .../java/com/beust/jcommander/JCommanderTest.java | 13 ++++---- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index f2f1fcc..32844b9 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -186,20 +186,18 @@ public class JCommander { for (int i = 0; i < vResult1.size(); i++) { String arg = vResult1.get(i); // TODO: make sure it's really an option and not that it starts with "-" - if (isOption(arg)) { - if ("--".equals(arg)) { - vResult2.add(arg); - vResult2.add(vResult1.get(++i)); - } else { - String sep = getSeparatorFor(arg); - if (! " ".equals(sep)) { - String[] sp = arg.split("[" + sep + "]"); - for (String ssp : sp) { - vResult2.add(ssp); - } - } else { - vResult2.add(arg); + if ("--".equals(arg)) { + vResult2.add(arg); + vResult2.add(vResult1.get(++i)); + } else if (isOption(arg)) { + String sep = getSeparatorFor(arg); + if (! " ".equals(sep)) { + String[] sp = arg.split("[" + sep + "]"); + for (String ssp : sp) { + vResult2.add(ssp); } + } else { + vResult2.add(arg); } } else { vResult2.add(arg); @@ -210,7 +208,10 @@ public class JCommander { } private boolean isOption(String arg) { - return arg.startsWith("-"); + if ("--".equals(arg)) return false; + + String prefixes = getOptionPrefixes(); + return prefixes.indexOf(arg.charAt(0)) >= 0; } private ParameterDescription getDescriptionFor(String arg) { @@ -231,6 +232,12 @@ public class JCommander { else return " "; } + private String getOptionPrefixes() { + Parameters p = m_objects.get(0).getClass().getAnnotation(Parameters.class); + if (p != null) return p.optionPrefixes(); + else return Parameters.DEFAULT_OPTION_PREFIXES; + } + /** * Reads the file specified by filename and returns the file content as a string. * End of lines are replaced by a space. diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index 1feb224..07751a4 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -14,6 +14,8 @@ import java.lang.annotation.Target; @Target({ TYPE }) public @interface Parameters { + public static final String DEFAULT_OPTION_PREFIXES = "-"; + /** * The name of the resource bundle to use for this class. */ @@ -23,4 +25,9 @@ public @interface Parameters { * The character(s) that separate options. */ String separators() default " "; + + /** + * What characters an option starts with. + */ + String optionPrefixes() default DEFAULT_OPTION_PREFIXES; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 0d4e2ca..5f9718f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -17,6 +17,7 @@ import com.beust.jcommander.args.ArgsSlaveBogus; import com.beust.jcommander.args.SeparatorColon; import com.beust.jcommander.args.SeparatorEqual; import com.beust.jcommander.args.SeparatorMixed; +import com.beust.jcommander.args.SlashSeparator; import com.beust.jcommander.converters.FileConverter; import org.testng.Assert; @@ -264,12 +265,12 @@ public class JCommanderTest { } @Test - public void negativeNumbers() { - Args1 a = new Args1(); - String[] argv = { "-verbose", "--", "-3", "-long", "--", "-4" }; + public void dashDash() { + SlashSeparator a = new SlashSeparator(); + String[] argv = { "/verbose", "/file", "--", "/tmp/a" }; new JCommander(a, argv); - Assert.assertEquals(a.verbose.intValue(), -3); - Assert.assertEquals(a.l, -4); + Assert.assertTrue(a.verbose); + Assert.assertEquals(a.file, "/tmp/a"); } @Test @@ -295,7 +296,7 @@ public class JCommanderTest { // } // new DefaultProviderTest().propertyFileDefaultProvider1(); // new JCommander(new Args1(), "foo"); - new DefaultProviderTest().defaultProvider1(); + new JCommanderTest().converterArgs(); // new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; -- cgit v1.2.3 From f14a46abd32b378ec56a672a2da0b926c5d7276d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 10:13:55 -0700 Subject: Flexible prefixes --- src/main/java/com/beust/jcommander/JCommander.java | 82 ++++++++++++++++------ .../java/com/beust/jcommander/JCommanderTest.java | 8 +-- 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 32844b9..d003512 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -126,12 +126,25 @@ public class JCommander { * Parse the command line parameters. */ public void parse(String... args) { + StringBuilder sb = new StringBuilder("Parsing \""); + sb.append(join(args).append("\"\n with:").append(join(m_objects.toArray()))); + p(sb.toString()); + createDescriptions(); initializeDefaultValues(); parseValues(expandArgs(args)); validateOptions(); } + private StringBuilder join(Object[] args) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < args.length; i++) { + if (i > 0) result.append(" "); + result.append(args[i]); + } + return result; + } + private void initializeDefaultValues() { if (m_defaultProvider != null) { for (ParameterDescription pd : m_descriptions.values()) { @@ -185,12 +198,13 @@ public class JCommander { List vResult2 = Lists.newArrayList(); for (int i = 0; i < vResult1.size(); i++) { String arg = vResult1.get(i); + String[] v1 = vResult1.toArray(new String[0]); // TODO: make sure it's really an option and not that it starts with "-" if ("--".equals(arg)) { vResult2.add(arg); vResult2.add(vResult1.get(++i)); - } else if (isOption(arg)) { - String sep = getSeparatorFor(arg); + } else if (isOption(v1, arg)) { + String sep = getSeparatorFor(v1, arg); if (! " ".equals(sep)) { String[] sp = arg.split("[" + sep + "]"); for (String ssp : sp) { @@ -207,35 +221,61 @@ public class JCommander { return vResult2.toArray(new String[vResult2.size()]); } - private boolean isOption(String arg) { + private boolean isOption(String[] args, String arg) { if ("--".equals(arg)) return false; - String prefixes = getOptionPrefixes(); + String prefixes = getOptionPrefixes(args, arg); return prefixes.indexOf(arg.charAt(0)) >= 0; } - private ParameterDescription getDescriptionFor(String arg) { - for (ParameterDescription p : m_descriptions.values()) { - for (String n : p.getParameter().names()) { - if (arg.startsWith(n)) { - return p; - } - } + private ParameterDescription getPrefixDescriptionFor(String arg) { + for (Map.Entry es : m_descriptions.entrySet()) { + if (arg.startsWith(es.getKey())) return es.getValue(); + } + + return null; + } + + /** + * If arg is an option, we can look it up directly, but if it's a value, + * we need to find the description for the option that precedes it. + */ + private ParameterDescription getDescriptionFor(String[] args, String arg) { + ParameterDescription result = getPrefixDescriptionFor(arg); + if (result != null) return result; + + for (String a : args) { + ParameterDescription pd = getPrefixDescriptionFor(arg); + if (pd != null) result = pd; + if (a.equals(arg)) return result; } + throw new ParameterException("Unknown parameter: " + arg); } - private String getSeparatorFor(String arg) { - ParameterDescription pd = getDescriptionFor(arg); - Parameters p = pd.getObject().getClass().getAnnotation(Parameters.class); - if (p != null) return p.separators(); - else return " "; + private String getSeparatorFor(String[] args, String arg) { + ParameterDescription pd = getDescriptionFor(args, 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.separators(); + } + + return " "; } - private String getOptionPrefixes() { - Parameters p = m_objects.get(0).getClass().getAnnotation(Parameters.class); - if (p != null) return p.optionPrefixes(); - else return Parameters.DEFAULT_OPTION_PREFIXES; + private String getOptionPrefixes(String[] args, String arg) { + ParameterDescription pd = getDescriptionFor(args, 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(); + } + + return Parameters.DEFAULT_OPTION_PREFIXES; } /** @@ -340,7 +380,7 @@ public class JCommander { p("Parsing arg:" + a); // ParameterDescription previousDescription = null; - if (isOption(a)) { + if (isOption(args, a)) { ParameterDescription pd = m_descriptions.get(a); // ParameterDescription pd = null; // diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 5f9718f..bb3fd4d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -290,13 +290,9 @@ public class JCommanderTest { } public static void main(String[] args) { -// for (Object[] p : f()) { -// int tc = JCommander.getTabCount((Integer) p[0], (Integer) p[1]); -// Assert.assertEquals(tc, ((Integer) p[2]).intValue()); -// } -// new DefaultProviderTest().propertyFileDefaultProvider1(); + new JCommanderTest().separatorBoth(); +// new DefaultProviderTest().defaultProvider1(); // new JCommander(new Args1(), "foo"); - new JCommanderTest().converterArgs(); // new JCommander(new CommandLineArgs2()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; -- cgit v1.2.3 From 858c0e61453c4b3a8663d9094f38b6aba493d753 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 10:20:46 -0700 Subject: Better tests, updated CHANGELOG --- CHANGELOG | 3 +- src/main/java/com/beust/jcommander/JCommander.java | 36 ++-------------------- .../java/com/beust/jcommander/JCommanderTest.java | 12 ++++++-- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e73ea5f..84174b2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,10 @@ 1.4 +Added string converter factories Added IDefaultProvider Added PropertyFileDefaultProvider Usage is now showing required parameters and default value -Added "--" +Support for values that look like parameters ("-integer -3", "/file /tmp/a") 1.2 2010/08/25 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index d003512..d5c21ab 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -11,7 +11,6 @@ import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -199,11 +198,7 @@ public class JCommander { for (int i = 0; i < vResult1.size(); i++) { String arg = vResult1.get(i); String[] v1 = vResult1.toArray(new String[0]); - // TODO: make sure it's really an option and not that it starts with "-" - if ("--".equals(arg)) { - vResult2.add(arg); - vResult2.add(vResult1.get(++i)); - } else if (isOption(v1, arg)) { + if (isOption(v1, arg)) { String sep = getSeparatorFor(v1, arg); if (! " ".equals(sep)) { String[] sp = arg.split("[" + sep + "]"); @@ -222,8 +217,6 @@ public class JCommander { } private boolean isOption(String[] args, String arg) { - if ("--".equals(arg)) return false; - String prefixes = getOptionPrefixes(args, arg); return prefixes.indexOf(arg.charAt(0)) >= 0; } @@ -378,34 +371,9 @@ public class JCommander { for (int i = 0; i < args.length; i++) { String a = trim(args[i]); p("Parsing arg:" + a); -// ParameterDescription previousDescription = null; if (isOption(args, a)) { - ParameterDescription pd = m_descriptions.get(a); -// ParameterDescription pd = null; -// -// if ("--".equals(a)) { -// pd = previousDescription; -// i++; -// } else { -// } -// previousDescription = pd; - - // If we don't find any description, see if the previous parameter is an int - // or a long, and if it is, check to see if the current arg can be parsed - // into a negative integer -// if (pd == null && pd.isNumber()) { -// try { -// Long l = Long.parseLong(a); -// pd = previousDescription; -// i--; -// } -// catch(NumberFormatException ex) { -// // Do nothing, we'll fall through and throw a parameter exception -// } -// } -// -// previousDescription = pd; + ParameterDescription pd = m_descriptions.get(a); if (pd != null) { if (pd.getParameter().password()) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index bb3fd4d..64ab738 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -267,12 +267,20 @@ public class JCommanderTest { @Test public void dashDash() { SlashSeparator a = new SlashSeparator(); - String[] argv = { "/verbose", "/file", "--", "/tmp/a" }; + String[] argv = { "/verbose", "/file", "/tmp/a" }; new JCommander(a, argv); Assert.assertTrue(a.verbose); Assert.assertEquals(a.file, "/tmp/a"); } + @Test + public void negativeNumber() { + Args1 a = new Args1(); + String[] argv = { "-verbose", "-3" }; + new JCommander(a, argv); + Assert.assertEquals(a.verbose.intValue(), -3); + } + @Test public void requiredMainParameters() { // @@ -290,7 +298,7 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().separatorBoth(); + new JCommanderTest().negativeNumber(); // new DefaultProviderTest().defaultProvider1(); // new JCommander(new Args1(), "foo"); // new JCommander(new CommandLineArgs2()).usage(); -- cgit v1.2.3 From 788450fd1d9535fda9e9051dbe2c9c180faa8df4 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 10:20:59 -0700 Subject: SlashSeparator update --- .../java/com/beust/jcommander/args/SlashSeparator.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/java/com/beust/jcommander/args/SlashSeparator.java diff --git a/src/test/java/com/beust/jcommander/args/SlashSeparator.java b/src/test/java/com/beust/jcommander/args/SlashSeparator.java new file mode 100644 index 0000000..d212956 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/SlashSeparator.java @@ -0,0 +1,14 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(optionPrefixes = "/") +public class SlashSeparator { + + @Parameter(names = "/verbose") + public boolean verbose = false; + + @Parameter(names = "/file") + public String file; +} -- cgit v1.2.3 From 4d25ee9b2a535be771217e36eda0b45afa0753da Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 10:22:27 -0700 Subject: Documented @Parameters(optionPrefixes) --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 84174b2..b31c9c4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ Added IDefaultProvider Added PropertyFileDefaultProvider Usage is now showing required parameters and default value Support for values that look like parameters ("-integer -3", "/file /tmp/a") +Added @Parameters(optionPrefixes) to allow for different prefixes than "-" 1.2 2010/08/25 -- cgit v1.2.3 From 426bf32155b30f5c1819a00d88c16944c01e5a52 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 10:24:38 -0700 Subject: Test rename --- src/test/java/com/beust/jcommander/JCommanderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 64ab738..f37666d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -265,7 +265,7 @@ public class JCommanderTest { } @Test - public void dashDash() { + public void slashParameters() { SlashSeparator a = new SlashSeparator(); String[] argv = { "/verbose", "/file", "/tmp/a" }; new JCommander(a, argv); -- cgit v1.2.3 From 0c6350b606a1f72156f3564402c75dc11454ecf1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 12:53:31 -0700 Subject: Fixed a few generics warnings --- .../java/com/beust/jcommander/IStringConverterFactory.java | 2 +- src/main/java/com/beust/jcommander/JCommander.java | 12 +++++++----- src/main/java/com/beust/jcommander/ParameterDescription.java | 5 ----- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/beust/jcommander/IStringConverterFactory.java b/src/main/java/com/beust/jcommander/IStringConverterFactory.java index 8a514d7..5a3b3b2 100644 --- a/src/main/java/com/beust/jcommander/IStringConverterFactory.java +++ b/src/main/java/com/beust/jcommander/IStringConverterFactory.java @@ -8,5 +8,5 @@ package com.beust.jcommander; * @author cbeust */ public interface IStringConverterFactory { - Class> getConverter(Class forType); + Class> getConverter(Class forType); } diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index d5c21ab..1f36d1a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -83,9 +83,11 @@ public class JCommander { /** * The factories used to look up string converters. */ - private static List CONVERTER_FACTORIES = new ArrayList() {{ - add(new DefaultConverterFactory()); - }}; + private static List CONVERTER_FACTORIES = Lists.newArrayList(); + + static { + CONVERTER_FACTORIES.add(new DefaultConverterFactory()); + }; public JCommander(Object object) { init(object, null); @@ -540,9 +542,9 @@ public class JCommander { CONVERTER_FACTORIES.add(converterFactory); } - public Class> findConverter(Class cls) { + public Class> findConverter(Class cls) { for (IStringConverterFactory f : CONVERTER_FACTORIES) { - Class> result = f.getConverter(cls); + Class> result = f.getConverter(cls); if (result != null) return result; } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 186c330..7ff6e02 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -1,9 +1,6 @@ package com.beust.jcommander; -import com.beust.jcommander.converters.BooleanConverter; -import com.beust.jcommander.converters.IntegerConverter; -import com.beust.jcommander.converters.LongConverter; import com.beust.jcommander.converters.NoConverter; import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.Lists; @@ -12,10 +9,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.ResourceBundle; import java.util.Set; -- cgit v1.2.3 From 0ec1bf37ff92ef52d0c37dfbd50a3a7284d5b460 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 20:24:28 -0700 Subject: Replace log() with p() --- src/main/java/com/beust/jcommander/ParameterDescription.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 7ff6e02..963e094 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -118,7 +118,7 @@ public class ParameterDescription { * @param markAdded if true, mark this parameter as assigned */ public void addValue(String value, boolean isDefault) { - log("Adding " + (isDefault ? "default " : "") + "value:" + value + p("Adding " + (isDefault ? "default " : "") + "value:" + value + " to parameter:" + m_field.getName()); boolean isCollection = false; if (m_assigned && ! isMultiOption()) { @@ -217,7 +217,7 @@ public class ParameterDescription { return result; } - private void log(String string) { + private void p(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { System.out.println("[ParameterDescription] " + string); } -- cgit v1.2.3 From 0235dc8adeed6c78d7f65a5766cd1886ef6e7b18 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 22:12:26 -0700 Subject: Documented the new features --- doc/index.html | 140 +++++++++++++++++++-- src/main/java/com/beust/jcommander/JCommander.java | 2 + .../java/com/beust/jcommander/JCommanderTest.java | 10 +- 3 files changed, 138 insertions(+), 14 deletions(-) diff --git a/doc/index.html b/doc/index.html index 4b78b3d..a089b0a 100644 --- a/doc/index.html +++ b/doc/index.html @@ -145,7 +145,9 @@ Value for -password (Connection password): You will need to type the value at this point before JCommander resumes. -

    Custom types

    +

    Custom types

    + +

    By annotation

    By default, JCommander parses the command line into basic types only (strings, booleans, integers and longs). Very often, your application actually needs more complex types, such as files, host names, lists, etc... To achieve this, you can write a type converter by implementing the following interface: @@ -175,7 +177,84 @@ File file; JCommander ships with a few common converters (e.g. one that turns a comma separated list into a List<String>). -

    Main parameter

    +

    By factory

    + +If the custom types you use appear multiple times in your application, having to specify the converter in each annotation can become tedious. To address this, you can use an IStringConverterFactory: + +
    +public interface IStringConverterFactory {
    +  <T> Class<? extends IStringConverter<T>> getConverter(Class<T> forType);
    +}
    +
    + +For example, suppose you need to parse a string representing a host and a port: + +
    +java App -target example.com:8080
    +
    + +You define the holder class : + +
    +public class HostPort {
    +  public String host;
    +  public Integer port;
    +}
    +
    + +and the string converter to create instances of this class: + +
    +class HostPortConverter implements IStringConverter<HostPort> {
    +  @Override
    +  public HostPort convert(String value) {
    +    HostPort result = new HostPort();
    +    String[] s = value.split(":");
    +    result.host = s[0];
    +    result.port = Integer.parseInt(s[1]);
    +
    +    return result;
    +  }
    +}
    +
    + +The factory is straightforward: + +
    +public class Factory implements IStringConverterFactory {
    +  public Class> getConverter(Class forType) {
    +    if (forType.equals(HostPort.class)) return HostPortConverter.class;
    +    else return null;
    +  }
    +
    + +You can now use the type HostPort as a parameter without any converterClass attribute: + +
    +public class ArgsConverterFactory {
    +  @Parameter(names = "-hostport")
    +  public HostPort hostPort;
    +}
    +
    + + +All you need to do is add the factory to your JCommander object: + +
    +  ArgsConverterFactory a = new ArgsConverterFactory();
    +  JCommander jc = new JCommander(a);
    +  jc.addConverterFactory(new Factory());
    +  jc.parse("-hostport", "example.com:8080");
    +
    +  Assert.assertEquals(a.hostPort.host, "example.com");
    +  Assert.assertEquals(a.hostPort.port.intValue(), 8080);
    +
    + + +Another advantage of using string converter factories is that your factories can come from a dependency injection framework. + + +

    Main parameter

    So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a List<String> and it will contain all the parameters that are not options:
    @@ -357,6 +436,49 @@ If some of your parameters are mandatory, you can use the
     If this parameter is not specified, JCommander will throw an exception
     telling you which options are missing.
     
    +

    Default values

    + +The most common way to specify a default value for your parameters is to initialize the field at declaration time: + +
    +private Integer logLevel = 3;
    +
    + +For more complicated cases, you might want to be able to reuse identical default values across several main classes or be able to specify these default values in a centralized location such as a .properties or an XML fie. In this case, you can use an IDefaultProvider + +
    +public interface IDefaultProvider {
    +  /**
    +   * @param optionName The name of the option as specified in the names() attribute
    +   * of the @Parameter option (e.g. "-file").
    +   * 
    +   * @return the default value for this option.
    +   */
    +  String getDefaultValueFor(String optionName);
    +}
    +
    + +By passing an implementation of this interface to your JCommander object, you can now control which default value will be used for your options. Note that the value returned by this method will then be passed to a string converter, if any is applicable, thereby allowing you to specify default values for any types you need. + +

    + +For example, here is a default provider that will assign a default value of 42 for all your parameters except "-debug": + +

    +private static final IDefaultProvider DEFAULT_PROVIDER = new IDefaultProvider() {
    +  @Override
    +  public String getDefaultValueFor(String optionName) {
    +    return "-debug".equals(optionName) ? "false" : "42";
    +  }
    +};
    +
    +// ...
    +
    +JCommander jc = new JCommander(new Args());
    +jc.setDefaultProvider(DEFAULT_PROVIDER);
    +
    + +

    Exception

    Whenever JCommander detects an error, it will throw a @@ -370,13 +492,17 @@ point. You can invoke usage() on the JCommander instance that you used to parse your command line in order to generate a summary of all the options that your program understands:
    -Usage:
    -	-port			The port number
    -	-debug			Debug mode
    -	-src, --sources The source directory
    -	-testclass		List of classes
    +
    +Usage: <main class> [options] 
    +  Options:
    +    -debug          Debug mode (default: false)
    +    -groups         Comma-separated list of group names to be run
    +  * -log, -verbose  Level of verbosity (default: 1)
    +    -long           A long number (default: 0)
     
    +Options preceded by an asterisk are required. +

    Hiding parameters

    If you don't want certain parameters to appear in the usage, you can mark them as "hidden": diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 1f36d1a..11b14b5 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -464,6 +464,8 @@ public class JCommander { * Display a the help on System.out. */ public void usage() { + if (m_descriptions == null) createDescriptions(); + StringBuilder sb = new StringBuilder("Usage:
    [options]"); if (m_mainParameterAnnotation != null) { sb.append(" " + m_mainParameterAnnotation.description()); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index f37666d..b318b5f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -5,7 +5,6 @@ import com.beust.jcommander.args.Args2; import com.beust.jcommander.args.ArgsArityString; import com.beust.jcommander.args.ArgsBooleanArity; import com.beust.jcommander.args.ArgsConverter; -import com.beust.jcommander.args.ArgsConverterFactory; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; @@ -18,17 +17,14 @@ import com.beust.jcommander.args.SeparatorColon; import com.beust.jcommander.args.SeparatorEqual; import com.beust.jcommander.args.SeparatorMixed; import com.beust.jcommander.args.SlashSeparator; -import com.beust.jcommander.converters.FileConverter; import org.testng.Assert; +import org.testng.CommandLineArgs; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.io.File; import java.util.Arrays; -import java.util.HashMap; import java.util.Locale; -import java.util.Map; import java.util.ResourceBundle; public class JCommanderTest { @@ -298,10 +294,10 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().negativeNumber(); +// new JCommanderTest().negativeNumber(); // new DefaultProviderTest().defaultProvider1(); // new JCommander(new Args1(), "foo"); -// new JCommander(new CommandLineArgs2()).usage(); + new JCommander(new Args1()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; -- cgit v1.2.3 From cbcfeaa4b5ad13774579c8a4c2f230ee1362b67a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 22:21:05 -0700 Subject: Removed unused import --- src/test/java/com/beust/jcommander/JCommanderTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index b318b5f..3d3a7ff 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -19,7 +19,6 @@ import com.beust.jcommander.args.SeparatorMixed; import com.beust.jcommander.args.SlashSeparator; import org.testng.Assert; -import org.testng.CommandLineArgs; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -- cgit v1.2.3 From c332827673a7e61b8ec3fa66d20673155038a4a6 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 22:21:35 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7ec4f44..072de63 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jcommander jar JCommander - 1.4-SNAPSHOT + 1.4 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 99382985135cbca5c4b9a82211132145e59f961b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 28 Jul 2010 22:21:40 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 072de63..49f01de 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ jcommander jar JCommander - 1.4 + 1.5-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 1eb22b901f731760a479740312337471363febff Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 29 Jul 2010 12:57:34 -0700 Subject: Moved findConverter to JCommander --- CHANGELOG | 1 + doc/index.html | 33 ++++--- src/main/java/com/beust/jcommander/JCommander.java | 103 ++++++++++++++++++++- .../com/beust/jcommander/ParameterDescription.java | 97 +++++++------------ .../java/com/beust/jcommander/JCommanderTest.java | 10 +- .../beust/jcommander/args/ArgsMainParameter.java | 18 ++++ 6 files changed, 174 insertions(+), 88 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/args/ArgsMainParameter.java diff --git a/CHANGELOG b/CHANGELOG index b31c9c4..d95bbfe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ 1.4 +2010/08/28 Added string converter factories Added IDefaultProvider diff --git a/doc/index.html b/doc/index.html index a089b0a..5420f3e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -97,13 +97,13 @@ When a Parameter annotation is found on a field of type String public Integer verbose = 1;
    -
    +
     java Main -log 3
     
    will cause the field verbose to receive the value 3, however: -
    +
     java Main -log test
     
    @@ -120,7 +120,7 @@ public List<String> hosts = new ArrayList<String>(); will allow you to parse the following command line: -
    +
     java Main -host host1 -verbose -host host2
     
    @@ -139,7 +139,7 @@ public class ArgsPassword { When you run your program, you will get the following prompt: -
    +
     Value for -password (Connection password):
     
    @@ -189,7 +189,7 @@ public interface IStringConverterFactory { For example, suppose you need to parse a string representing a host and a port: -
    +
     java App -target example.com:8080
     
    @@ -267,7 +267,7 @@ public Integer debug = 1; will allow you to parse: -
    +
     java Main -debug file1 file2
     
    @@ -298,13 +298,13 @@ Assert.assertEquals(args.getVerbose().intValue(), 3); By default, parameters are separated by spaces, but you can change this setting to allow different separators: -
    +
     java Main -log:3
     
    or -
    +
     java Main -level=42
     
    @@ -365,13 +365,13 @@ JCommander supports the @ syntax, which allows you to put all your options into

    /tmp/parameters
    -
    +
     -verbose
     file1
     file2
     file3
     
    -
    +
     java Main @/tmp/parameters
     
    @@ -380,7 +380,7 @@ java Main @/tmp/parameters If some of your parameters require more than one value, such as the following example where two values are expected after -pairs: -
    +
     java Main -pairs slave master foo.xml
     
    @@ -416,7 +416,7 @@ You can specify more than one option name: will allow both following syntaxes: -
    +
     java Main -d /tmp
     java Main --outputDirectory /tmp
     
    @@ -491,8 +491,7 @@ point. You can invoke usage() on the JCommander instance that you used to parse your command line in order to generate a summary of all the options that your program understands: -
    -
    +
     Usage: <main class> [options] 
       Options:
         -debug          Debug mode (default: false)
    @@ -534,7 +533,7 @@ Your bundle needs to define this key:
     

    MessageBundle_fr_FR.properties

    -
    +
     host: Hôte
     
    @@ -550,7 +549,7 @@ You can download JCommander from the following locations:
    • Source on github
    • -
    • Jar file
    • +
    • Jar file
    • Or if you are using Maven, add the following dependency to your pom.xml:
      @@ -558,7 +557,7 @@ You can download JCommander from the following locations:
       
         com.beust
         jcommander
      -  1.3
      +  1.4
       
         
      diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 11b14b5..aa6a4f6 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,5 +1,7 @@ package com.beust.jcommander; +import com.beust.jcommander.converters.NoConverter; +import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.DefaultConverterFactory; import com.beust.jcommander.internal.Lists; import com.beust.jcommander.internal.Maps; @@ -9,8 +11,12 @@ import java.io.Console; import java.io.FileReader; import java.io.IOException; import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.ParameterizedType; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -98,6 +104,7 @@ public class JCommander { parse(args); } + public JCommander(Object object, String... args) { init(object, null); parse(args); @@ -425,7 +432,17 @@ public class JCommander { } } else { - if (! isStringEmpty(args[i])) getMainParameter(args[i]).add(args[i]); + if (! isStringEmpty(args[i])) { + List mp = getMainParameter(args[i]); + Object value = args[i]; + + if (m_mainParameterField.getGenericType() instanceof ParameterizedType) { + ParameterizedType p = (ParameterizedType) m_mainParameterField.getGenericType(); + System.out.println("Generic type:" + p.getActualTypeArguments()[0]); + } + + mp.add(value); + } } } } @@ -440,7 +457,7 @@ public class JCommander { * @param arg the arg that we're about to add (only passed here to ouput a meaningful * error message). */ - private List getMainParameter(String arg) { + private List getMainParameter(String arg) { if (m_mainParameterField == null) { throw new ParameterException( "Was passed main parameter '" + arg + "' but no main parameter was defined"); @@ -448,7 +465,7 @@ public class JCommander { try { @SuppressWarnings("unchecked") - List result = (List) m_mainParameterField.get(m_mainParameterObject); + List result = (List) m_mainParameterField.get(m_mainParameterObject); if (result == null) { result = Lists.newArrayList(); m_mainParameterField.set(m_mainParameterObject, result); @@ -552,5 +569,85 @@ public class JCommander { return null; } + + public Object convertValue(ParameterDescription pd, String value) { + Parameter annotation = pd.getParameter(); + Class type = pd.getField().getType(); + Class> converterClass = annotation.converter(); + + // + // Try to find a converter on the annotation + // + boolean isCollection = false; + + if (converterClass == null || converterClass == NoConverter.class) { + converterClass = findConverter(type); + } + if (converterClass == null) { + converterClass = StringConverter.class; + isCollection = true; + } + if (converterClass == null && Collection.class.isAssignableFrom(type)) { + converterClass = StringConverter.class; + isCollection = true; + } + + // +// // +// // Try to find a converter in the factory +// // +// IStringConverter converter = null; +// if (converterClass == null && m_converterFactories != null) { +// // Mmmh, javac requires a cast here +// converter = (IStringConverter) m_converterFactories.getConverter(type); +// } + + if (converterClass == null) { + throw new ParameterException("Don't know how to convert " + value + + " to type " + type + " (field: " + pd.getField().getName() + ")"); + } + + IStringConverter converter; + Object result = null; + try { + String optionName = annotation.names()[0]; + converter = instantiateConverter(optionName, converterClass); + result = converter.convert(value); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + + return result; + } + + private IStringConverter instantiateConverter(String optionName, + Class> converterClass) + throws IllegalArgumentException, InstantiationException, IllegalAccessException, + InvocationTargetException { + Constructor> ctor = null; + Constructor> stringCtor = null; + Constructor>[] ctors + = (Constructor>[]) converterClass.getDeclaredConstructors(); + for (Constructor> c : ctors) { + Class[] types = c.getParameterTypes(); + if (types.length == 1 && types[0].equals(String.class)) { + stringCtor = c; + } else if (types.length == 0) { + ctor = c; + } + } + + IStringConverter result = stringCtor != null + ? stringCtor.newInstance(optionName) + : ctor.newInstance(); + + return result; + } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 963e094..ffe9c95 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -120,51 +120,41 @@ public class ParameterDescription { public void addValue(String value, boolean isDefault) { p("Adding " + (isDefault ? "default " : "") + "value:" + value + " to parameter:" + m_field.getName()); - boolean isCollection = false; if (m_assigned && ! isMultiOption()) { throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0] + " once."); } Class type = m_field.getType(); - Class> converterClass = null; - - // - // Try to find a converter on the annotation - // - converterClass = m_parameterAnnotation.converter(); - if (converterClass == NoConverter.class) { - converterClass = m_jCommander.findConverter(type); - } - if (converterClass == null && m_parameterAnnotation.arity() >= 2) { - converterClass = StringConverter.class; - isCollection = true; - } - if (converterClass == null && Collection.class.isAssignableFrom(type)) { - converterClass = StringConverter.class; - isCollection = true; - } - - // +// Class> converterClass = null; +// // // -// // Try to find a converter in the factory +// // Try to find a converter on the annotation // // -// IStringConverter converter = null; -// if (converterClass == null && m_converterFactories != null) { -// // Mmmh, javac requires a cast here -// converter = (IStringConverter) m_converterFactories.getConverter(type); +// converterClass = m_parameterAnnotation.converter(); +// if (converterClass == NoConverter.class) { +// converterClass = m_jCommander.findConverter(type); +// } +// if (converterClass == null && m_parameterAnnotation.arity() >= 2) { +// converterClass = StringConverter.class; +// isCollection = true; +// } +// if (converterClass == null && Collection.class.isAssignableFrom(type)) { +// converterClass = StringConverter.class; +// isCollection = true; +// } +// +// if (converterClass == null) { +// throw new ParameterException("Don't know how to convert " + value +// + " to type " + type + " (field: " + m_field.getName() + ")"); // } - - if (converterClass == null) { - throw new ParameterException("Don't know how to convert " + value - + " to type " + type + " (field: " + m_field.getName() + ")"); - } if (! isDefault) m_assigned = true; + Object convertedValue = m_jCommander.convertValue(this, value); + boolean isCollection = Collection.class.isAssignableFrom(type); + boolean isMainParameter = m_parameterAnnotation.names().length == 0; try { - IStringConverter converter = instantiateConverter(converterClass); - Object convertedValue = converter.convert(value); if (isCollection) { @SuppressWarnings("unchecked") List l = (List) m_field.get(m_object); @@ -172,18 +162,19 @@ public class ParameterDescription { l = Lists.newArrayList(); m_field.set(m_object, l); } - l.add(convertedValue); + if (convertedValue instanceof Collection) { + l.addAll((Collection) convertedValue); + } else { // if (isMainParameter || m_parameterAnnotation.arity() > 1) { + l.add(convertedValue); +// } else { +// l. + } } else { m_field.set(m_object, convertedValue); } - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); + } + catch(IllegalAccessException ex) { + ex.printStackTrace(); } } @@ -193,30 +184,6 @@ public class ParameterDescription { || type.equals(Long.class) || type.equals(long.class); } - private IStringConverter instantiateConverter( - Class> converterClass) - throws IllegalArgumentException, InstantiationException, IllegalAccessException, - InvocationTargetException { - Constructor> ctor = null; - Constructor> stringCtor = null; - Constructor>[] ctors - = (Constructor>[]) converterClass.getDeclaredConstructors(); - for (Constructor> c : ctors) { - Class[] types = c.getParameterTypes(); - if (types.length == 1 && types[0].equals(String.class)) { - stringCtor = c; - } else if (types.length == 0) { - ctor = c; - } - } - - IStringConverter result = stringCtor != null - ? stringCtor.newInstance(m_parameterAnnotation.names()[0]) - : ctor.newInstance(); - - return result; - } - private void p(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { System.out.println("[ParameterDescription] " + string); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 3d3a7ff..9a9d7f1 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -8,6 +8,7 @@ import com.beust.jcommander.args.ArgsConverter; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; +import com.beust.jcommander.args.ArgsMainParameter; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; @@ -293,10 +294,13 @@ public class JCommanderTest { } public static void main(String[] args) { -// new JCommanderTest().negativeNumber(); + new JCommanderTest().listParameters(); + new JCommanderTest().converterArgs(); // new DefaultProviderTest().defaultProvider1(); -// new JCommander(new Args1(), "foo"); - new JCommander(new Args1()).usage(); +// ArgsMainParameter a = new ArgsMainParameter(); +// new JCommander(a, "ex1:10", "ex2:20"); +// System.out.println(a.parameters.get(0).host); +// new JCommander(new Args1()).usage(); // Separator a = new Separator(); // String[] argv = new String[] { "-n", "foo" }; // String[] argv = new String[] { "-v", "t" }; diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter.java new file mode 100644 index 0000000..78a1510 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter.java @@ -0,0 +1,18 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.HostPort; +import com.beust.jcommander.Parameter; + +import org.testng.collections.Lists; + +import java.util.List; + +/** + * A class with main parameter that is not a List + * + * @author cbeust + */ +public class ArgsMainParameter { + @Parameter + public List parameters = Lists.newArrayList(); +} -- cgit v1.2.3 From 484d81b494104aa2b684dab7825466c7b98b744b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 29 Jul 2010 13:59:22 -0700 Subject: Main parameters now use converters --- src/main/java/com/beust/jcommander/JCommander.java | 32 ++++++++++++++-------- .../com/beust/jcommander/ConverterFactoryTest.java | 13 +++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 3 +- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index aa6a4f6..7dd05fe 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -15,6 +15,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -434,14 +435,18 @@ public class JCommander { else { if (! isStringEmpty(args[i])) { List mp = getMainParameter(args[i]); - Object value = args[i]; + String value = args[i]; + Object convertedValue = value; if (m_mainParameterField.getGenericType() instanceof ParameterizedType) { ParameterizedType p = (ParameterizedType) m_mainParameterField.getGenericType(); - System.out.println("Generic type:" + p.getActualTypeArguments()[0]); + Type cls = p.getActualTypeArguments()[0]; + if (cls instanceof Class) { + convertedValue = convertValue(m_mainParameterField, (Class) cls, value); + } } - mp.add(value); + mp.add(convertedValue); } } } @@ -571,25 +576,29 @@ public class JCommander { } public Object convertValue(ParameterDescription pd, String value) { - Parameter annotation = pd.getParameter(); - Class type = pd.getField().getType(); + return convertValue(pd.getField(), pd.getField().getType(), value); + } + + /** + * @param type The class of the field + * @param annotation The annotation + * @param value The value to convert + */ + public Object convertValue(Field field, Class type, String value) { + Parameter annotation = field.getAnnotation(Parameter.class); Class> converterClass = annotation.converter(); // // Try to find a converter on the annotation // - boolean isCollection = false; - if (converterClass == null || converterClass == NoConverter.class) { converterClass = findConverter(type); } if (converterClass == null) { converterClass = StringConverter.class; - isCollection = true; } if (converterClass == null && Collection.class.isAssignableFrom(type)) { converterClass = StringConverter.class; - isCollection = true; } // @@ -604,13 +613,14 @@ public class JCommander { if (converterClass == null) { throw new ParameterException("Don't know how to convert " + value - + " to type " + type + " (field: " + pd.getField().getName() + ")"); + + " to type " + type + " (field: " + field.getName() + ")"); } IStringConverter converter; Object result = null; try { - String optionName = annotation.names()[0]; + String[] names = annotation.names(); + String optionName = names.length > 0 ? names[0] : "[Main class]"; converter = instantiateConverter(optionName, converterClass); result = converter.convert(value); } catch (IllegalArgumentException e) { diff --git a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java index 0081926..2db3c73 100644 --- a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java +++ b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java @@ -1,6 +1,7 @@ package com.beust.jcommander; import com.beust.jcommander.args.ArgsConverterFactory; +import com.beust.jcommander.args.ArgsMainParameter; import org.testng.Assert; import org.testng.annotations.Test; @@ -38,6 +39,18 @@ public class ConverterFactoryTest { Assert.assertEquals(a.hostPort.port.intValue(), 8080); } + @Test + public void mainWithHostPortParameters() { + ArgsMainParameter a = new ArgsMainParameter(); + JCommander jc = new JCommander(a); + jc.addConverterFactory(CONVERTER_FACTORY); + jc.parse("a.com:10", "b.com:20"); + Assert.assertEquals(a.parameters.get(0).host, "a.com"); + Assert.assertEquals(a.parameters.get(0).port.intValue(), 10); + Assert.assertEquals(a.parameters.get(1).host, "b.com"); + Assert.assertEquals(a.parameters.get(1).port.intValue(), 20); + } + } class HostPortConverter implements IStringConverter { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9a9d7f1..ee07155 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -294,8 +294,7 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().listParameters(); - new JCommanderTest().converterArgs(); + new ConverterFactoryTest().mainWithHostPortParameters(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); // new JCommander(a, "ex1:10", "ex2:20"); -- cgit v1.2.3 From 6f6f43684c3079b1590139a3bc01213977e8a82c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 29 Jul 2010 17:18:24 -0700 Subject: More tests for main parametesr with converters --- CHANGELOG | 4 ++ .../com/beust/jcommander/ConverterFactoryTest.java | 44 +++++++++++----------- .../com/beust/jcommander/HostPortConverter.java | 14 +++++++ .../java/com/beust/jcommander/JCommanderTest.java | 4 +- .../beust/jcommander/args/ArgsMainParameter.java | 18 --------- .../beust/jcommander/args/ArgsMainParameter1.java | 23 +++++++++++ .../beust/jcommander/args/ArgsMainParameter2.java | 24 ++++++++++++ .../java/com/beust/jcommander/args/IHostPorts.java | 9 +++++ 8 files changed, 99 insertions(+), 41 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/HostPortConverter.java delete mode 100644 src/test/java/com/beust/jcommander/args/ArgsMainParameter.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java create mode 100644 src/test/java/com/beust/jcommander/args/IHostPorts.java diff --git a/CHANGELOG b/CHANGELOG index d95bbfe..5b32398 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +1.5 + +Added support for converters for main parameters (e.g. List). + 1.4 2010/08/28 diff --git a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java index 2db3c73..5dc613d 100644 --- a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java +++ b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java @@ -1,7 +1,9 @@ package com.beust.jcommander; import com.beust.jcommander.args.ArgsConverterFactory; -import com.beust.jcommander.args.ArgsMainParameter; +import com.beust.jcommander.args.ArgsMainParameter1; +import com.beust.jcommander.args.ArgsMainParameter2; +import com.beust.jcommander.args.IHostPorts; import org.testng.Assert; import org.testng.annotations.Test; @@ -29,7 +31,7 @@ public class ConverterFactoryTest { }; @Test - public void converterFactory() { + public void parameterWithHostPortParameters() { ArgsConverterFactory a = new ArgsConverterFactory(); JCommander jc = new JCommander(a); jc.addConverterFactory(CONVERTER_FACTORY); @@ -39,29 +41,29 @@ public class ConverterFactoryTest { Assert.assertEquals(a.hostPort.port.intValue(), 8080); } - @Test - public void mainWithHostPortParameters() { - ArgsMainParameter a = new ArgsMainParameter(); + /** + * Test that main parameters can be used with string converters, + * either with a factory or from the annotation. + */ + private void mainWithHostPortParameters(IStringConverterFactory f, IHostPorts a) { JCommander jc = new JCommander(a); - jc.addConverterFactory(CONVERTER_FACTORY); + if (f != null) jc.addConverterFactory(f); jc.parse("a.com:10", "b.com:20"); - Assert.assertEquals(a.parameters.get(0).host, "a.com"); - Assert.assertEquals(a.parameters.get(0).port.intValue(), 10); - Assert.assertEquals(a.parameters.get(1).host, "b.com"); - Assert.assertEquals(a.parameters.get(1).port.intValue(), 20); + Assert.assertEquals(a.getHostPorts().get(0).host, "a.com"); + Assert.assertEquals(a.getHostPorts().get(0).port.intValue(), 10); + Assert.assertEquals(a.getHostPorts().get(1).host, "b.com"); + Assert.assertEquals(a.getHostPorts().get(1).port.intValue(), 20); } -} + @Test + public void mainWithoutFactory() { + mainWithHostPortParameters(null, new ArgsMainParameter1()); + } -class HostPortConverter implements IStringConverter { + @Test + public void mainWithFactory() { + mainWithHostPortParameters(CONVERTER_FACTORY, new ArgsMainParameter2()); + } - @Override - public HostPort convert(String value) { - HostPort result = new HostPort(); - String[] s = value.split(":"); - result.host = s[0]; - result.port = Integer.parseInt(s[1]); +} - return result; - } -} \ No newline at end of file diff --git a/src/test/java/com/beust/jcommander/HostPortConverter.java b/src/test/java/com/beust/jcommander/HostPortConverter.java new file mode 100644 index 0000000..b718da4 --- /dev/null +++ b/src/test/java/com/beust/jcommander/HostPortConverter.java @@ -0,0 +1,14 @@ +package com.beust.jcommander; + +public class HostPortConverter implements IStringConverter { + + @Override + public HostPort convert(String value) { + HostPort result = new HostPort(); + String[] s = value.split(":"); + result.host = s[0]; + result.port = Integer.parseInt(s[1]); + + return result; + } +} \ No newline at end of file diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index ee07155..b8e8c64 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -8,7 +8,7 @@ import com.beust.jcommander.args.ArgsConverter; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; -import com.beust.jcommander.args.ArgsMainParameter; +import com.beust.jcommander.args.ArgsMainParameter1; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; @@ -294,7 +294,7 @@ public class JCommanderTest { } public static void main(String[] args) { - new ConverterFactoryTest().mainWithHostPortParameters(); +// new ConverterFactoryTest().mainWithHostPortParameters(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); // new JCommander(a, "ex1:10", "ex2:20"); diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter.java deleted file mode 100644 index 78a1510..0000000 --- a/src/test/java/com/beust/jcommander/args/ArgsMainParameter.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.beust.jcommander.args; - -import com.beust.jcommander.HostPort; -import com.beust.jcommander.Parameter; - -import org.testng.collections.Lists; - -import java.util.List; - -/** - * A class with main parameter that is not a List - * - * @author cbeust - */ -public class ArgsMainParameter { - @Parameter - public List parameters = Lists.newArrayList(); -} diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java new file mode 100644 index 0000000..19d17e3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java @@ -0,0 +1,23 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.HostPort; +import com.beust.jcommander.Parameter; + +import org.testng.collections.Lists; + +import java.util.List; + +/** + * A class with main parameter that is not a List + * + * @author cbeust + */ +public class ArgsMainParameter1 implements IHostPorts { + @Parameter + public List parameters = Lists.newArrayList(); + + @Override + public List getHostPorts() { + return parameters; + } +} diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java new file mode 100644 index 0000000..332e47e --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java @@ -0,0 +1,24 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.HostPort; +import com.beust.jcommander.HostPortConverter; +import com.beust.jcommander.Parameter; + +import org.testng.collections.Lists; + +import java.util.List; + +/** + * A class with main parameter that is not a List + * + * @author cbeust + */ +public class ArgsMainParameter2 implements IHostPorts { + @Parameter(converter = HostPortConverter.class) + public List parameters = Lists.newArrayList(); + + @Override + public List getHostPorts() { + return parameters; + } +} diff --git a/src/test/java/com/beust/jcommander/args/IHostPorts.java b/src/test/java/com/beust/jcommander/args/IHostPorts.java new file mode 100644 index 0000000..ba48734 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/IHostPorts.java @@ -0,0 +1,9 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.HostPort; + +import java.util.List; + +public interface IHostPorts { + List getHostPorts(); +} -- cgit v1.2.3 From 5187242fcad293107312ef97c0d6552dfa5e3574 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 31 Jul 2010 09:44:36 -0700 Subject: Implemented commands. --- src/main/java/com/beust/jcommander/JCommander.java | 95 ++++++++++++++++++---- .../java/com/beust/jcommander/JCommanderTest.java | 37 ++++++++- .../java/com/beust/jcommander/args/CommandAdd.java | 15 ++++ .../com/beust/jcommander/args/CommandCommit.java | 19 +++++ .../com/beust/jcommander/args/CommandMain.java | 9 ++ 5 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/args/CommandAdd.java create mode 100644 src/test/java/com/beust/jcommander/args/CommandCommit.java create mode 100644 src/test/java/com/beust/jcommander/args/CommandMain.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 7dd05fe..3110fe4 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -87,6 +87,16 @@ public class JCommander { */ private IDefaultProvider m_defaultProvider; + /** + * List of commands and their instance. + */ + private Map m_commands = Maps.newHashMap(); + + /** + * The name of the command after the parsing has run. + */ + private String m_parsedCommand; + /** * The factories used to look up string converters. */ @@ -331,6 +341,12 @@ public class JCommander { m_descriptions = Maps.newHashMap(); for (Object object : m_objects) { + addDescription(object); + } + } + + private void addDescription(Object object) { + { Class cls = object.getClass(); for (Field f : cls.getDeclaredFields()) { p("Field:" + f.getName()); @@ -378,11 +394,20 @@ public class JCommander { * Main method that parses the values and initializes the fields accordingly. */ private void parseValues(String[] args) { - for (int i = 0; i < args.length; i++) { - String a = trim(args[i]); + // 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) + boolean commandParsed = false; + int i = 0; + while (i < args.length && ! commandParsed) { + String arg = args[i]; + String a = trim(arg); p("Parsing arg:" + a); if (isOption(args, a)) { + // + // Option + // ParameterDescription pd = m_descriptions.get(a); if (pd != null) { @@ -424,7 +449,7 @@ public class JCommander { } i += n + offset; } else { - throw new ParameterException(n + " parameters expected after " + args[i]); + throw new ParameterException(n + " parameters expected after " + arg); } } } @@ -433,25 +458,53 @@ public class JCommander { } } else { - if (! isStringEmpty(args[i])) { - List mp = getMainParameter(args[i]); - String value = args[i]; - Object convertedValue = value; - - if (m_mainParameterField.getGenericType() instanceof ParameterizedType) { - ParameterizedType p = (ParameterizedType) m_mainParameterField.getGenericType(); - Type cls = p.getActualTypeArguments()[0]; - if (cls instanceof Class) { - convertedValue = convertValue(m_mainParameterField, (Class) cls, value); + // + // Main parameter + // + if (! isStringEmpty(arg)) { + if (m_commands.isEmpty()) { + // + // Regular (non-command) parsing + // + List mp = getMainParameter(arg); + String value = arg; + Object convertedValue = value; + + if (m_mainParameterField.getGenericType() instanceof ParameterizedType) { + ParameterizedType p = (ParameterizedType) m_mainParameterField.getGenericType(); + Type cls = p.getActualTypeArguments()[0]; + if (cls instanceof Class) { + convertedValue = convertValue(m_mainParameterField, (Class) cls, value); + } } + + mp.add(convertedValue); + } + else { + // + // Command parsing + // + Object o = m_commands.get(arg); + if (o == null) throw new ParameterException("Expected a command, got " + arg); + m_parsedCommand = arg; + JCommander jc = new JCommander(o); + jc.parse(subArray(args, i + 1)); + commandParsed = true; } - - mp.add(convertedValue); } } + i++; } } + private String[] subArray(String[] args, int index) { + int l = args.length - index; + String[] result = new String[l]; + System.arraycopy(args, index, result, 0, l); + + return result; + } + private static boolean isStringEmpty(String s) { return s == null || "".equals(s); } @@ -659,5 +712,17 @@ public class JCommander { return result; } + + /** + * Add a command object. + */ + public void addCommand(String string, Object object) { + m_commands.put(string, object); + } + + public String getParsedCommand() { + return m_parsedCommand; + } + } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index b8e8c64..cab1d7a 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -8,12 +8,14 @@ import com.beust.jcommander.args.ArgsConverter; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; -import com.beust.jcommander.args.ArgsMainParameter1; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; import com.beust.jcommander.args.ArgsSlave; import com.beust.jcommander.args.ArgsSlaveBogus; +import com.beust.jcommander.args.CommandAdd; +import com.beust.jcommander.args.CommandCommit; +import com.beust.jcommander.args.CommandMain; import com.beust.jcommander.args.SeparatorColon; import com.beust.jcommander.args.SeparatorEqual; import com.beust.jcommander.args.SeparatorMixed; @@ -277,6 +279,38 @@ public class JCommanderTest { Assert.assertEquals(a.verbose.intValue(), -3); } + @Test + public void commandTest1() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit); + jc.parse("add", "-i", "A.java"); + + Assert.assertEquals(jc.getParsedCommand(), "add"); + Assert.assertEquals(add.interactive.booleanValue(), true); + Assert.assertEquals(add.patterns, Arrays.asList("A.java")); + } + + @Test + public void commandTest2() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit); + jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); + + Assert.assertTrue(cm.verbose); + Assert.assertEquals(jc.getParsedCommand(), "commit"); + Assert.assertTrue(commit.amend); + Assert.assertEquals(commit.author, "cbeust"); + Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); + } + @Test public void requiredMainParameters() { // @@ -294,6 +328,7 @@ public class JCommanderTest { } public static void main(String[] args) { + new JCommanderTest().commandTest2(); // new ConverterFactoryTest().mainWithHostPortParameters(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); diff --git a/src/test/java/com/beust/jcommander/args/CommandAdd.java b/src/test/java/com/beust/jcommander/args/CommandAdd.java new file mode 100644 index 0000000..1ff2c85 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/CommandAdd.java @@ -0,0 +1,15 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +import java.util.List; + +public class CommandAdd { + + @Parameter + public List patterns; + + @Parameter(names = "-i") + public Boolean interactive = false; + +} diff --git a/src/test/java/com/beust/jcommander/args/CommandCommit.java b/src/test/java/com/beust/jcommander/args/CommandCommit.java new file mode 100644 index 0000000..dd55ae6 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/CommandCommit.java @@ -0,0 +1,19 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +import java.util.List; + +@Parameters(separators = "=") +public class CommandCommit { + + @Parameter + public List files; + + @Parameter(names = "--amend", description = "Amend") + public Boolean amend = false; + + @Parameter(names = "--author") + public String author; +} diff --git a/src/test/java/com/beust/jcommander/args/CommandMain.java b/src/test/java/com/beust/jcommander/args/CommandMain.java new file mode 100644 index 0000000..1ba8812 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/CommandMain.java @@ -0,0 +1,9 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class CommandMain { + + @Parameter(names = "-v") + public Boolean verbose = false; +} -- cgit v1.2.3 From d9912518ee6f7aeb843c4977f780fee30fad32d7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 31 Jul 2010 09:59:30 -0700 Subject: Moved command tests --- src/main/java/com/beust/jcommander/JCommander.java | 5 +++ .../java/com/beust/jcommander/JCommanderTest.java | 37 +------------------ .../java/com/beust/jcommander/args/CommandAdd.java | 15 -------- .../com/beust/jcommander/args/CommandCommit.java | 19 ---------- .../com/beust/jcommander/args/CommandMain.java | 9 ----- .../com/beust/jcommander/command/CommandAdd.java | 15 ++++++++ .../beust/jcommander/command/CommandCommit.java | 19 ++++++++++ .../com/beust/jcommander/command/CommandMain.java | 9 +++++ .../com/beust/jcommander/command/CommandTest.java | 43 ++++++++++++++++++++++ 9 files changed, 92 insertions(+), 79 deletions(-) delete mode 100644 src/test/java/com/beust/jcommander/args/CommandAdd.java delete mode 100644 src/test/java/com/beust/jcommander/args/CommandCommit.java delete mode 100644 src/test/java/com/beust/jcommander/args/CommandMain.java create mode 100644 src/test/java/com/beust/jcommander/command/CommandAdd.java create mode 100644 src/test/java/com/beust/jcommander/command/CommandCommit.java create mode 100644 src/test/java/com/beust/jcommander/command/CommandMain.java create mode 100644 src/test/java/com/beust/jcommander/command/CommandTest.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3110fe4..a0aeda3 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -487,6 +487,11 @@ public class JCommander { Object o = m_commands.get(arg); if (o == null) throw new ParameterException("Expected a command, got " + arg); m_parsedCommand = arg; + + // Found a valid command, create a new JCommander object with its + // description object and ask it to parse the remainder of the arguments. + // Setting the boolean commandParsed to true will force the current + // loop to end. JCommander jc = new JCommander(o); jc.parse(subArray(args, i + 1)); commandParsed = true; diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index cab1d7a..c413e34 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -13,9 +13,6 @@ import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; import com.beust.jcommander.args.ArgsSlave; import com.beust.jcommander.args.ArgsSlaveBogus; -import com.beust.jcommander.args.CommandAdd; -import com.beust.jcommander.args.CommandCommit; -import com.beust.jcommander.args.CommandMain; import com.beust.jcommander.args.SeparatorColon; import com.beust.jcommander.args.SeparatorEqual; import com.beust.jcommander.args.SeparatorMixed; @@ -279,38 +276,6 @@ public class JCommanderTest { Assert.assertEquals(a.verbose.intValue(), -3); } - @Test - public void commandTest1() { - CommandMain cm = new CommandMain(); - JCommander jc = new JCommander(cm); - CommandAdd add = new CommandAdd(); - jc.addCommand("add", add); - CommandCommit commit = new CommandCommit(); - jc.addCommand("commit", commit); - jc.parse("add", "-i", "A.java"); - - Assert.assertEquals(jc.getParsedCommand(), "add"); - Assert.assertEquals(add.interactive.booleanValue(), true); - Assert.assertEquals(add.patterns, Arrays.asList("A.java")); - } - - @Test - public void commandTest2() { - CommandMain cm = new CommandMain(); - JCommander jc = new JCommander(cm); - CommandAdd add = new CommandAdd(); - jc.addCommand("add", add); - CommandCommit commit = new CommandCommit(); - jc.addCommand("commit", commit); - jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); - - Assert.assertTrue(cm.verbose); - Assert.assertEquals(jc.getParsedCommand(), "commit"); - Assert.assertTrue(commit.amend); - Assert.assertEquals(commit.author, "cbeust"); - Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); - } - @Test public void requiredMainParameters() { // @@ -328,7 +293,7 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().commandTest2(); +// new JCommanderTest().commandTest2(); // new ConverterFactoryTest().mainWithHostPortParameters(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); diff --git a/src/test/java/com/beust/jcommander/args/CommandAdd.java b/src/test/java/com/beust/jcommander/args/CommandAdd.java deleted file mode 100644 index 1ff2c85..0000000 --- a/src/test/java/com/beust/jcommander/args/CommandAdd.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.beust.jcommander.args; - -import com.beust.jcommander.Parameter; - -import java.util.List; - -public class CommandAdd { - - @Parameter - public List patterns; - - @Parameter(names = "-i") - public Boolean interactive = false; - -} diff --git a/src/test/java/com/beust/jcommander/args/CommandCommit.java b/src/test/java/com/beust/jcommander/args/CommandCommit.java deleted file mode 100644 index dd55ae6..0000000 --- a/src/test/java/com/beust/jcommander/args/CommandCommit.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.beust.jcommander.args; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; - -import java.util.List; - -@Parameters(separators = "=") -public class CommandCommit { - - @Parameter - public List files; - - @Parameter(names = "--amend", description = "Amend") - public Boolean amend = false; - - @Parameter(names = "--author") - public String author; -} diff --git a/src/test/java/com/beust/jcommander/args/CommandMain.java b/src/test/java/com/beust/jcommander/args/CommandMain.java deleted file mode 100644 index 1ba8812..0000000 --- a/src/test/java/com/beust/jcommander/args/CommandMain.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.beust.jcommander.args; - -import com.beust.jcommander.Parameter; - -public class CommandMain { - - @Parameter(names = "-v") - public Boolean verbose = false; -} diff --git a/src/test/java/com/beust/jcommander/command/CommandAdd.java b/src/test/java/com/beust/jcommander/command/CommandAdd.java new file mode 100644 index 0000000..227a8f2 --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/CommandAdd.java @@ -0,0 +1,15 @@ +package com.beust.jcommander.command; + +import com.beust.jcommander.Parameter; + +import java.util.List; + +public class CommandAdd { + + @Parameter + public List patterns; + + @Parameter(names = "-i") + public Boolean interactive = false; + +} diff --git a/src/test/java/com/beust/jcommander/command/CommandCommit.java b/src/test/java/com/beust/jcommander/command/CommandCommit.java new file mode 100644 index 0000000..c328756 --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/CommandCommit.java @@ -0,0 +1,19 @@ +package com.beust.jcommander.command; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +import java.util.List; + +@Parameters(separators = "=") +public class CommandCommit { + + @Parameter + public List files; + + @Parameter(names = "--amend", description = "Amend") + public Boolean amend = false; + + @Parameter(names = "--author") + public String author; +} diff --git a/src/test/java/com/beust/jcommander/command/CommandMain.java b/src/test/java/com/beust/jcommander/command/CommandMain.java new file mode 100644 index 0000000..aea3beb --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/CommandMain.java @@ -0,0 +1,9 @@ +package com.beust.jcommander.command; + +import com.beust.jcommander.Parameter; + +public class CommandMain { + + @Parameter(names = "-v") + public Boolean verbose = false; +} diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java new file mode 100644 index 0000000..ebdf1da --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -0,0 +1,43 @@ +package com.beust.jcommander.command; + +import com.beust.jcommander.JCommander; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Arrays; + +public class CommandTest { + @Test + public void commandTest1() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit); + jc.parse("add", "-i", "A.java"); + + Assert.assertEquals(jc.getParsedCommand(), "add"); + Assert.assertEquals(add.interactive.booleanValue(), true); + Assert.assertEquals(add.patterns, Arrays.asList("A.java")); + } + + @Test + public void commandTest2() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit); + jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); + + Assert.assertTrue(cm.verbose); + Assert.assertEquals(jc.getParsedCommand(), "commit"); + Assert.assertTrue(commit.amend); + Assert.assertEquals(commit.author, "cbeust"); + Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); + } + +} -- cgit v1.2.3 From 2283e84e55d9384aa7f61439ec17233c012b82ed Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 31 Jul 2010 10:06:39 -0700 Subject: Updated change log --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 5b32398..3322fb0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ 1.5 +Added support for commands (e.g. "main add --author=cbeust Foo.java") Added support for converters for main parameters (e.g. List). 1.4 -- cgit v1.2.3 From 3477b0f9a636d6e9be7dbc56d185cab426dc70bf Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 1 Aug 2010 15:15:57 -0700 Subject: Displaying correct usage for commands --- src/main/java/com/beust/jcommander/JCommander.java | 97 ++++++++++++++++++++-- .../com/beust/jcommander/ParameterDescription.java | 38 +++------ .../java/com/beust/jcommander/JCommanderTest.java | 2 +- .../com/beust/jcommander/command/CommandAdd.java | 2 +- .../beust/jcommander/command/CommandCommit.java | 2 +- .../com/beust/jcommander/command/CommandTest.java | 3 + 6 files changed, 107 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index a0aeda3..76ed929 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -97,6 +97,8 @@ public class JCommander { */ private String m_parsedCommand; + private String m_programName; + /** * The factories used to look up string converters. */ @@ -540,20 +542,68 @@ public class JCommander { } } + private String getMainParameterDescription() { + if (m_descriptions == null) createDescriptions(); + return m_mainParameterAnnotation != null ? m_mainParameterAnnotation.description() + : null; + } + + private int longestName(Collection objects) { + int result = 0; + for (Object o : objects) { + int l = o.toString().length(); + if (l > result) result = l; + } + + return result; + } + + public void usage(String commandName) { + Object o = m_commands.get(commandName); + Object object; + try { + // Create a new object since o might have received values + // and might therefore display default values that are incorrect. + object = o.getClass().newInstance(); + JCommander jc = new JCommander(object); + jc.setProgramName(commandName); + jc.usage(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + /** + * Set the program name (used only in the usage). + */ + public void setProgramName(String name) { + m_programName = name; + } + /** * Display a the help on System.out. */ public void usage() { if (m_descriptions == null) createDescriptions(); + boolean hasCommands = ! m_commands.isEmpty(); - StringBuilder sb = new StringBuilder("Usage:
      [options]"); + // + // First line of the usage + // + String programName = m_programName != null ? m_programName : "
      "; + StringBuilder sb = new StringBuilder("Usage: " + programName + " [options]"); + if (hasCommands) sb.append(" [command] [command options]"); if (m_mainParameterAnnotation != null) { sb.append(" " + m_mainParameterAnnotation.description()); } sb.append("\n Options:"); System.out.println(sb.toString()); - // Will contain the size of the longest option name + // + // Align the descriptions at the "longestName" column + // int longestName = 0; List sorted = Lists.newArrayList(); for (ParameterDescription pd : m_fields.values()) { @@ -567,6 +617,9 @@ public class JCommander { } } + // + // Sort the options + // Collections.sort(sorted, new Comparator() { @Override public int compare(ParameterDescription arg0, ParameterDescription arg1) { @@ -574,19 +627,21 @@ public class JCommander { } }); - // Display all the names and descriptions at the right tab position + // + // Display all the names and descriptions + // StringBuilder out = new StringBuilder(); for (ParameterDescription pd : sorted) { int l = pd.getNames().length(); int spaceCount = longestName - l; - StringBuilder tabs = new StringBuilder(); - for (int i = 0; i < spaceCount; i++) tabs.append(" "); out.append(" " + (pd.getParameter().required() ? "* " : " ") - + pd.getNames() + tabs + pd.getDescription()); + + pd.getNames() + s(spaceCount) + pd.getDescription()); try { - Object def = pd.getField().get(pd.getObject()); - if (def != null) out.append(" (default: " + def + ")"); + if (! pd.wasAssigned()) { + Object def = pd.getField().get(pd.getObject()); + if (def != null) out.append(" (default: " + def + ")"); + } } catch (IllegalArgumentException e) { // ignore } catch (IllegalAccessException e) { @@ -595,6 +650,21 @@ public class JCommander { out.append("\n"); } + // + // If commands were specified, show them as well + // + if (hasCommands) { + out.append(" Commands:\n"); + int ln = longestName(m_commands.keySet()) + 3; + for (Map.Entry commands : m_commands.entrySet()) { + String name = commands.getKey(); + int spaceCount = ln - name.length(); + Object o = commands.getValue(); + JCommander jc = new JCommander(o); + out.append(" " + name + s(spaceCount) + jc.getMainParameterDescription() + "\n"); + } + } + System.out.println(out); } @@ -729,5 +799,16 @@ public class JCommander { return m_parsedCommand; } + /** + * @return n spaces + */ + private String s(int count) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < count; i++) { + result.append(" "); + } + + return result.toString(); + } } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index ffe9c95..fdac1d8 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -1,13 +1,9 @@ package com.beust.jcommander; -import com.beust.jcommander.converters.NoConverter; -import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.Lists; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.List; import java.util.Locale; @@ -111,6 +107,13 @@ public class ParameterDescription { addValue(value, false /* not default */); } + /** + * @return true if this parameter received a value during the parsing phase. + */ + public boolean wasAssigned() { + return m_assigned; + } + /** * Add the specified value to the field. First look up any field converter, then * any type converter, and if we can't find any, throw an exception. @@ -126,28 +129,6 @@ public class ParameterDescription { } Class type = m_field.getType(); -// Class> converterClass = null; -// -// // -// // Try to find a converter on the annotation -// // -// converterClass = m_parameterAnnotation.converter(); -// if (converterClass == NoConverter.class) { -// converterClass = m_jCommander.findConverter(type); -// } -// if (converterClass == null && m_parameterAnnotation.arity() >= 2) { -// converterClass = StringConverter.class; -// isCollection = true; -// } -// if (converterClass == null && Collection.class.isAssignableFrom(type)) { -// converterClass = StringConverter.class; -// isCollection = true; -// } -// -// if (converterClass == null) { -// throw new ParameterException("Don't know how to convert " + value -// + " to type " + type + " (field: " + m_field.getName() + ")"); -// } if (! isDefault) m_assigned = true; Object convertedValue = m_jCommander.convertValue(this, value); @@ -189,4 +170,9 @@ public class ParameterDescription { System.out.println("[ParameterDescription] " + string); } } + + @Override + public String toString() { + return "[ParameterDescription " + m_field.getName() + "]"; + } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index c413e34..9146fd3 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -294,7 +294,7 @@ public class JCommanderTest { public static void main(String[] args) { // new JCommanderTest().commandTest2(); -// new ConverterFactoryTest().mainWithHostPortParameters(); +// new CommandTest().commandTest2(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); // new JCommander(a, "ex1:10", "ex2:20"); diff --git a/src/test/java/com/beust/jcommander/command/CommandAdd.java b/src/test/java/com/beust/jcommander/command/CommandAdd.java index 227a8f2..230b92b 100644 --- a/src/test/java/com/beust/jcommander/command/CommandAdd.java +++ b/src/test/java/com/beust/jcommander/command/CommandAdd.java @@ -6,7 +6,7 @@ import java.util.List; public class CommandAdd { - @Parameter + @Parameter(description = "Add file contents to the index") public List patterns; @Parameter(names = "-i") diff --git a/src/test/java/com/beust/jcommander/command/CommandCommit.java b/src/test/java/com/beust/jcommander/command/CommandCommit.java index c328756..1c22b72 100644 --- a/src/test/java/com/beust/jcommander/command/CommandCommit.java +++ b/src/test/java/com/beust/jcommander/command/CommandCommit.java @@ -8,7 +8,7 @@ import java.util.List; @Parameters(separators = "=") public class CommandCommit { - @Parameter + @Parameter(description = "Record changes to the repository") public List files; @Parameter(names = "--amend", description = "Amend") diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java index ebdf1da..f01a082 100644 --- a/src/test/java/com/beust/jcommander/command/CommandTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -32,6 +32,9 @@ public class CommandTest { CommandCommit commit = new CommandCommit(); jc.addCommand("commit", commit); jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); +// jc.usage(); +// jc.usage("add"); +// jc.usage("commit"); Assert.assertTrue(cm.verbose); Assert.assertEquals(jc.getParsedCommand(), "commit"); -- cgit v1.2.3 From 4baa286ba3e23c167a8ab3ed7926a06b46a5f617 Mon Sep 17 00:00:00 2001 From: Hiram Chirino Date: Tue, 3 Aug 2010 15:35:42 -0400 Subject: adding lic info --- license.txt | 203 ++++++++++++++++++++++++++++++++++++ notice.md | 6 ++ pom.xml | 42 ++++++++ src/main/license/license-header.txt | 15 +++ 4 files changed, 266 insertions(+) create mode 100755 license.txt create mode 100644 notice.md create mode 100644 src/main/license/license-header.txt diff --git a/license.txt b/license.txt new file mode 100755 index 0000000..6b0b127 --- /dev/null +++ b/license.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/notice.md b/notice.md new file mode 100644 index 0000000..c3c42e3 --- /dev/null +++ b/notice.md @@ -0,0 +1,6 @@ +JCommander Copyright Notices +============================ + +Copyright 2010 Cedric Beust + + diff --git a/pom.xml b/pom.xml index 49f01de..4632647 100644 --- a/pom.xml +++ b/pom.xml @@ -126,4 +126,46 @@ test + + + + + + license + + + + com.mycila.maven-license-plugin + maven-license-plugin + 1.7.0 + + false +
      src/main/license/license-header.txt
      + + src/** + pom.xml + + + **/.git/** + + **/target/** + + false +
      + + + + check + + + +
      +
      +
      +
      +
      + diff --git a/src/main/license/license-header.txt b/src/main/license/license-header.txt new file mode 100644 index 0000000..4cbe379 --- /dev/null +++ b/src/main/license/license-header.txt @@ -0,0 +1,15 @@ +Copyright (C) 2010 the original author or authors. +See the notice.md file distributed with this work for additional +information regarding copyright ownership. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. -- cgit v1.2.3 From b7e9d9cfe060b02437f867716a8902cc466b0776 Mon Sep 17 00:00:00 2001 From: Guillaume Sauthier Date: Wed, 4 Aug 2010 13:25:24 +0200 Subject: Add inheritance support --- src/main/java/com/beust/jcommander/JCommander.java | 9 ++++++--- src/test/java/com/beust/jcommander/JCommanderTest.java | 10 ++++++++++ src/test/java/com/beust/jcommander/args/ArgsInherited.java | 10 ++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/args/ArgsInherited.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 76ed929..fd2ff61 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -348,10 +348,11 @@ public class JCommander { } private void addDescription(Object object) { - { - Class cls = object.getClass(); + Class cls = object.getClass(); + + while (!Object.class.equals(cls)) { for (Field f : cls.getDeclaredFields()) { - p("Field:" + f.getName()); + p("Field:" + cls.getSimpleName() + "." + f.getName()); f.setAccessible(true); Annotation annotation = f.getAnnotation(Parameter.class); if (annotation != null) { @@ -380,6 +381,8 @@ public class JCommander { } } } + // Traverse the super class until we find Object.class + cls = cls.getSuperclass(); } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9146fd3..a9b6802 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -8,6 +8,7 @@ import com.beust.jcommander.args.ArgsConverter; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; +import com.beust.jcommander.args.ArgsInherited; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; @@ -268,6 +269,15 @@ public class JCommanderTest { Assert.assertEquals(a.file, "/tmp/a"); } + @Test + public void inheritance() { + ArgsInherited args = new ArgsInherited(); + String[] argv = { "-log", "3", "-child", "2" }; + new JCommander(args, argv); + Assert.assertEquals(args.child.intValue(), 2); + Assert.assertEquals(args.log.intValue(), 3); + } + @Test public void negativeNumber() { Args1 a = new Args1(); diff --git a/src/test/java/com/beust/jcommander/args/ArgsInherited.java b/src/test/java/com/beust/jcommander/args/ArgsInherited.java new file mode 100644 index 0000000..0a4a83c --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsInherited.java @@ -0,0 +1,10 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class ArgsInherited extends ArgsDefault { + + @Parameter(names = "-child", description = "Child parameter") + public Integer child = 1; + +} -- cgit v1.2.3 From 89eccf1687656dfd0870b4f033fffdd8638d51c5 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Aug 2010 21:27:15 -0700 Subject: Updated the pom --- notice.md | 3 +-- pom.xml | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/notice.md b/notice.md index c3c42e3..64fc84a 100644 --- a/notice.md +++ b/notice.md @@ -1,6 +1,5 @@ JCommander Copyright Notices ============================ -Copyright 2010 Cedric Beust +Copyright 2010 Cedric Beust - diff --git a/pom.xml b/pom.xml index 4632647..dd92ca8 100644 --- a/pom.xml +++ b/pom.xml @@ -126,12 +126,12 @@ test - + - license @@ -161,11 +161,11 @@ check - + - + -- cgit v1.2.3 From 58a4af720c30d8dba072a96e3713577c8d30aeae Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Aug 2010 21:28:33 -0700 Subject: Added license headers with mvn -P license license:format --- pom.xml | 20 ++++++++++++++++++++ .../java/com/beust/jcommander/IDefaultProvider.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/IStringConverter.java | 18 ++++++++++++++++++ .../beust/jcommander/IStringConverterFactory.java | 18 ++++++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 18 ++++++++++++++++++ src/main/java/com/beust/jcommander/Parameter.java | 18 ++++++++++++++++++ .../com/beust/jcommander/ParameterDescription.java | 18 ++++++++++++++++++ .../com/beust/jcommander/ParameterException.java | 18 ++++++++++++++++++ src/main/java/com/beust/jcommander/Parameters.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/ResourceBundle.java | 18 ++++++++++++++++++ .../beust/jcommander/converters/BaseConverter.java | 18 ++++++++++++++++++ .../jcommander/converters/BooleanConverter.java | 18 ++++++++++++++++++ .../converters/CommaSeparatedConverter.java | 18 ++++++++++++++++++ .../beust/jcommander/converters/FileConverter.java | 18 ++++++++++++++++++ .../jcommander/converters/IntegerConverter.java | 18 ++++++++++++++++++ .../beust/jcommander/converters/LongConverter.java | 18 ++++++++++++++++++ .../com/beust/jcommander/converters/NoConverter.java | 18 ++++++++++++++++++ .../beust/jcommander/converters/StringConverter.java | 18 ++++++++++++++++++ .../defaultprovider/PropertyFileDefaultProvider.java | 18 ++++++++++++++++++ .../jcommander/internal/DefaultConverterFactory.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/internal/Lists.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/internal/Maps.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/internal/Sets.java | 18 ++++++++++++++++++ .../com/beust/jcommander/ConverterFactoryTest.java | 18 ++++++++++++++++++ .../com/beust/jcommander/DefaultProviderTest.java | 18 ++++++++++++++++++ src/test/java/com/beust/jcommander/HostPort.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/HostPortConverter.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 18 ++++++++++++++++++ src/test/java/com/beust/jcommander/args/Args1.java | 18 ++++++++++++++++++ src/test/java/com/beust/jcommander/args/Args2.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/ArgsArityInteger.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/ArgsArityString.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/ArgsBooleanArity.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/ArgsConverter.java | 18 ++++++++++++++++++ .../beust/jcommander/args/ArgsConverterFactory.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsDefault.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsI18N1.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsI18N2.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsI18N2New.java | 18 ++++++++++++++++++ .../beust/jcommander/args/ArgsMainParameter1.java | 18 ++++++++++++++++++ .../beust/jcommander/args/ArgsMainParameter2.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsMaster.java | 18 ++++++++++++++++++ .../beust/jcommander/args/ArgsMultipleUnparsed.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsPassword.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsPrivate.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/ArgsSlave.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/ArgsSlaveBogus.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/CommandLineArgs.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/CommandLineArgs2.java | 18 ++++++++++++++++++ .../java/com/beust/jcommander/args/IHostPorts.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/SeparatorColon.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/SeparatorEqual.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/SeparatorMixed.java | 18 ++++++++++++++++++ .../com/beust/jcommander/args/SlashSeparator.java | 18 ++++++++++++++++++ .../com/beust/jcommander/command/CommandAdd.java | 18 ++++++++++++++++++ .../com/beust/jcommander/command/CommandCommit.java | 18 ++++++++++++++++++ .../com/beust/jcommander/command/CommandMain.java | 18 ++++++++++++++++++ .../com/beust/jcommander/command/CommandTest.java | 18 ++++++++++++++++++ src/test/resources/MessageBundle_en_US.properties | 18 ++++++++++++++++++ src/test/resources/MessageBundle_fr_FR.properties | 18 ++++++++++++++++++ src/test/resources/jcommander.properties | 18 ++++++++++++++++++ 61 files changed, 1100 insertions(+) diff --git a/pom.xml b/pom.xml index dd92ca8..82484ee 100644 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,23 @@ + + 4.0.0 com.beust diff --git a/src/main/java/com/beust/jcommander/IDefaultProvider.java b/src/main/java/com/beust/jcommander/IDefaultProvider.java index 5ea0bc1..0353928 100644 --- a/src/main/java/com/beust/jcommander/IDefaultProvider.java +++ b/src/main/java/com/beust/jcommander/IDefaultProvider.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; /** diff --git a/src/main/java/com/beust/jcommander/IStringConverter.java b/src/main/java/com/beust/jcommander/IStringConverter.java index 53cd35f..fb51a79 100644 --- a/src/main/java/com/beust/jcommander/IStringConverter.java +++ b/src/main/java/com/beust/jcommander/IStringConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; /** diff --git a/src/main/java/com/beust/jcommander/IStringConverterFactory.java b/src/main/java/com/beust/jcommander/IStringConverterFactory.java index 5a3b3b2..0e53ca0 100644 --- a/src/main/java/com/beust/jcommander/IStringConverterFactory.java +++ b/src/main/java/com/beust/jcommander/IStringConverterFactory.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; /** diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 76ed929..247de7f 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import com.beust.jcommander.converters.NoConverter; diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 741dbf5..24fa469 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import static java.lang.annotation.ElementType.FIELD; diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index fdac1d8..6adbc09 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; diff --git a/src/main/java/com/beust/jcommander/ParameterException.java b/src/main/java/com/beust/jcommander/ParameterException.java index 81353bf..8bf5a20 100644 --- a/src/main/java/com/beust/jcommander/ParameterException.java +++ b/src/main/java/com/beust/jcommander/ParameterException.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; public class ParameterException extends RuntimeException { diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index 07751a4..b716ebe 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import static java.lang.annotation.ElementType.TYPE; diff --git a/src/main/java/com/beust/jcommander/ResourceBundle.java b/src/main/java/com/beust/jcommander/ResourceBundle.java index 94df0ae..8309216 100644 --- a/src/main/java/com/beust/jcommander/ResourceBundle.java +++ b/src/main/java/com/beust/jcommander/ResourceBundle.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import static java.lang.annotation.ElementType.TYPE; diff --git a/src/main/java/com/beust/jcommander/converters/BaseConverter.java b/src/main/java/com/beust/jcommander/converters/BaseConverter.java index 94ceaf8..c560af3 100644 --- a/src/main/java/com/beust/jcommander/converters/BaseConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BaseConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; diff --git a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java index 30fdf1a..9ca299f 100644 --- a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java index 44c3455..252aa6e 100644 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; diff --git a/src/main/java/com/beust/jcommander/converters/FileConverter.java b/src/main/java/com/beust/jcommander/converters/FileConverter.java index 36364fc..a54ec83 100644 --- a/src/main/java/com/beust/jcommander/converters/FileConverter.java +++ b/src/main/java/com/beust/jcommander/converters/FileConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java index 4fdf77e..766bd11 100644 --- a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java index b3cec97..5dd8b6a 100644 --- a/src/main/java/com/beust/jcommander/converters/LongConverter.java +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; diff --git a/src/main/java/com/beust/jcommander/converters/NoConverter.java b/src/main/java/com/beust/jcommander/converters/NoConverter.java index bae1898..eac2ef5 100644 --- a/src/main/java/com/beust/jcommander/converters/NoConverter.java +++ b/src/main/java/com/beust/jcommander/converters/NoConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; diff --git a/src/main/java/com/beust/jcommander/converters/StringConverter.java b/src/main/java/com/beust/jcommander/converters/StringConverter.java index 05fec0e..2971a9c 100644 --- a/src/main/java/com/beust/jcommander/converters/StringConverter.java +++ b/src/main/java/com/beust/jcommander/converters/StringConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; diff --git a/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java b/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java index 50f33a4..47eeedb 100644 --- a/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java +++ b/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.defaultprovider; import com.beust.jcommander.IDefaultProvider; diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java index 6781aa6..bbe0cd1 100644 --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.internal; import com.beust.jcommander.IStringConverter; diff --git a/src/main/java/com/beust/jcommander/internal/Lists.java b/src/main/java/com/beust/jcommander/internal/Lists.java index 8cacc33..8666fe4 100644 --- a/src/main/java/com/beust/jcommander/internal/Lists.java +++ b/src/main/java/com/beust/jcommander/internal/Lists.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.internal; import java.util.ArrayList; diff --git a/src/main/java/com/beust/jcommander/internal/Maps.java b/src/main/java/com/beust/jcommander/internal/Maps.java index 6a0dba6..9b476d0 100644 --- a/src/main/java/com/beust/jcommander/internal/Maps.java +++ b/src/main/java/com/beust/jcommander/internal/Maps.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.internal; import java.util.HashMap; diff --git a/src/main/java/com/beust/jcommander/internal/Sets.java b/src/main/java/com/beust/jcommander/internal/Sets.java index ced1045..221376a 100644 --- a/src/main/java/com/beust/jcommander/internal/Sets.java +++ b/src/main/java/com/beust/jcommander/internal/Sets.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.internal; import java.util.HashSet; diff --git a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java index 5dc613d..a93f27c 100644 --- a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java +++ b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import com.beust.jcommander.args.ArgsConverterFactory; diff --git a/src/test/java/com/beust/jcommander/DefaultProviderTest.java b/src/test/java/com/beust/jcommander/DefaultProviderTest.java index e185b77..171d116 100644 --- a/src/test/java/com/beust/jcommander/DefaultProviderTest.java +++ b/src/test/java/com/beust/jcommander/DefaultProviderTest.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import com.beust.jcommander.args.ArgsDefault; diff --git a/src/test/java/com/beust/jcommander/HostPort.java b/src/test/java/com/beust/jcommander/HostPort.java index 6737d7c..e0e5289 100644 --- a/src/test/java/com/beust/jcommander/HostPort.java +++ b/src/test/java/com/beust/jcommander/HostPort.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; public class HostPort { diff --git a/src/test/java/com/beust/jcommander/HostPortConverter.java b/src/test/java/com/beust/jcommander/HostPortConverter.java index b718da4..5f55474 100644 --- a/src/test/java/com/beust/jcommander/HostPortConverter.java +++ b/src/test/java/com/beust/jcommander/HostPortConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; public class HostPortConverter implements IStringConverter { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9146fd3..ea41b9a 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander; import com.beust.jcommander.args.Args1; diff --git a/src/test/java/com/beust/jcommander/args/Args1.java b/src/test/java/com/beust/jcommander/args/Args1.java index d89ad96..5d5b1b0 100644 --- a/src/test/java/com/beust/jcommander/args/Args1.java +++ b/src/test/java/com/beust/jcommander/args/Args1.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/Args2.java b/src/test/java/com/beust/jcommander/args/Args2.java index dbcb80c..89f622b 100644 --- a/src/test/java/com/beust/jcommander/args/Args2.java +++ b/src/test/java/com/beust/jcommander/args/Args2.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java b/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java index cb21cd3..9c1611f 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java +++ b/src/test/java/com/beust/jcommander/args/ArgsArityInteger.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsArityString.java b/src/test/java/com/beust/jcommander/args/ArgsArityString.java index 709290b..056ae85 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsArityString.java +++ b/src/test/java/com/beust/jcommander/args/ArgsArityString.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java b/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java index 8b3c77d..242e347 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java +++ b/src/test/java/com/beust/jcommander/args/ArgsBooleanArity.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java index 04c98cc..8d88022 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsConverter.java +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java b/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java index 56f29c0..f8463a0 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java +++ b/src/test/java/com/beust/jcommander/args/ArgsConverterFactory.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.HostPort; diff --git a/src/test/java/com/beust/jcommander/args/ArgsDefault.java b/src/test/java/com/beust/jcommander/args/ArgsDefault.java index 6a853a1..1adcd73 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsDefault.java +++ b/src/test/java/com/beust/jcommander/args/ArgsDefault.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N1.java b/src/test/java/com/beust/jcommander/args/ArgsI18N1.java index ba9018b..80e29e2 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsI18N1.java +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N1.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N2.java b/src/test/java/com/beust/jcommander/args/ArgsI18N2.java index dd4baf5..772d041 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsI18N2.java +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N2.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java b/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java index 4265160..1f55306 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java index 19d17e3..b223fd9 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.HostPort; diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java index 332e47e..739c13e 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.HostPort; diff --git a/src/test/java/com/beust/jcommander/args/ArgsMaster.java b/src/test/java/com/beust/jcommander/args/ArgsMaster.java index ba78fe5..ebcba67 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsMaster.java +++ b/src/test/java/com/beust/jcommander/args/ArgsMaster.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java b/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java index 91583db..f7b0628 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java +++ b/src/test/java/com/beust/jcommander/args/ArgsMultipleUnparsed.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsPassword.java b/src/test/java/com/beust/jcommander/args/ArgsPassword.java index 6fefa17..06c468e 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsPassword.java +++ b/src/test/java/com/beust/jcommander/args/ArgsPassword.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsPrivate.java b/src/test/java/com/beust/jcommander/args/ArgsPrivate.java index 885418c..16e4b4e 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsPrivate.java +++ b/src/test/java/com/beust/jcommander/args/ArgsPrivate.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsSlave.java b/src/test/java/com/beust/jcommander/args/ArgsSlave.java index 4c5d318..dabeb57 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsSlave.java +++ b/src/test/java/com/beust/jcommander/args/ArgsSlave.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java b/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java index 5615984..1abdf1f 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java +++ b/src/test/java/com/beust/jcommander/args/ArgsSlaveBogus.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/CommandLineArgs.java b/src/test/java/com/beust/jcommander/args/CommandLineArgs.java index 6374a72..7c8414f 100644 --- a/src/test/java/com/beust/jcommander/args/CommandLineArgs.java +++ b/src/test/java/com/beust/jcommander/args/CommandLineArgs.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java b/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java index ce1b4cf..ac62792 100644 --- a/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java +++ b/src/test/java/com/beust/jcommander/args/CommandLineArgs2.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/IHostPorts.java b/src/test/java/com/beust/jcommander/args/IHostPorts.java index ba48734..2020c77 100644 --- a/src/test/java/com/beust/jcommander/args/IHostPorts.java +++ b/src/test/java/com/beust/jcommander/args/IHostPorts.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.HostPort; diff --git a/src/test/java/com/beust/jcommander/args/SeparatorColon.java b/src/test/java/com/beust/jcommander/args/SeparatorColon.java index 7ef2e98..ab454fc 100644 --- a/src/test/java/com/beust/jcommander/args/SeparatorColon.java +++ b/src/test/java/com/beust/jcommander/args/SeparatorColon.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/SeparatorEqual.java b/src/test/java/com/beust/jcommander/args/SeparatorEqual.java index 42b47f3..a135207 100644 --- a/src/test/java/com/beust/jcommander/args/SeparatorEqual.java +++ b/src/test/java/com/beust/jcommander/args/SeparatorEqual.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/SeparatorMixed.java b/src/test/java/com/beust/jcommander/args/SeparatorMixed.java index 4717b1e..aa2641f 100644 --- a/src/test/java/com/beust/jcommander/args/SeparatorMixed.java +++ b/src/test/java/com/beust/jcommander/args/SeparatorMixed.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/args/SlashSeparator.java b/src/test/java/com/beust/jcommander/args/SlashSeparator.java index d212956..64d3930 100644 --- a/src/test/java/com/beust/jcommander/args/SlashSeparator.java +++ b/src/test/java/com/beust/jcommander/args/SlashSeparator.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/command/CommandAdd.java b/src/test/java/com/beust/jcommander/command/CommandAdd.java index 230b92b..0e07da5 100644 --- a/src/test/java/com/beust/jcommander/command/CommandAdd.java +++ b/src/test/java/com/beust/jcommander/command/CommandAdd.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.command; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/command/CommandCommit.java b/src/test/java/com/beust/jcommander/command/CommandCommit.java index 1c22b72..52fcba3 100644 --- a/src/test/java/com/beust/jcommander/command/CommandCommit.java +++ b/src/test/java/com/beust/jcommander/command/CommandCommit.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.command; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/command/CommandMain.java b/src/test/java/com/beust/jcommander/command/CommandMain.java index aea3beb..b2c32f4 100644 --- a/src/test/java/com/beust/jcommander/command/CommandMain.java +++ b/src/test/java/com/beust/jcommander/command/CommandMain.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.command; import com.beust.jcommander.Parameter; diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java index f01a082..3f59e19 100644 --- a/src/test/java/com/beust/jcommander/command/CommandTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.command; import com.beust.jcommander.JCommander; diff --git a/src/test/resources/MessageBundle_en_US.properties b/src/test/resources/MessageBundle_en_US.properties index 65148aa..915c418 100644 --- a/src/test/resources/MessageBundle_en_US.properties +++ b/src/test/resources/MessageBundle_en_US.properties @@ -1 +1,19 @@ +# +# Copyright (C) 2010 the original author or authors. +# See the notice.md file distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + host = Host \ No newline at end of file diff --git a/src/test/resources/MessageBundle_fr_FR.properties b/src/test/resources/MessageBundle_fr_FR.properties index bdbaf57..f3b0144 100644 --- a/src/test/resources/MessageBundle_fr_FR.properties +++ b/src/test/resources/MessageBundle_fr_FR.properties @@ -1 +1,19 @@ +# +# Copyright (C) 2010 the original author or authors. +# See the notice.md file distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + host = Hôte \ No newline at end of file diff --git a/src/test/resources/jcommander.properties b/src/test/resources/jcommander.properties index 5b47e32..3cea84b 100644 --- a/src/test/resources/jcommander.properties +++ b/src/test/resources/jcommander.properties @@ -1,3 +1,21 @@ +# +# Copyright (C) 2010 the original author or authors. +# See the notice.md file distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + groups=unit level=17 log=18 \ No newline at end of file -- cgit v1.2.3 From bd5ce9c45c1c30dfed8a553602c127104f254c9f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Aug 2010 21:34:37 -0700 Subject: Added inheritance support (Guillaume Sauthier) --- CHANGELOG | 1 + .../java/com/beust/jcommander/args/ArgsInherited.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 3322fb0..8c7bbfe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ 1.5 +Added inheritance support (Guillaume Sauthier) Added support for commands (e.g. "main add --author=cbeust Foo.java") Added support for converters for main parameters (e.g. List). diff --git a/src/test/java/com/beust/jcommander/args/ArgsInherited.java b/src/test/java/com/beust/jcommander/args/ArgsInherited.java index 0a4a83c..abc0e82 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsInherited.java +++ b/src/test/java/com/beust/jcommander/args/ArgsInherited.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.beust.jcommander.args; import com.beust.jcommander.Parameter; -- cgit v1.2.3 From e6b03e45550ef19dd1067919e8be28f313bc2de7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Aug 2010 21:47:20 -0700 Subject: Documented commands --- doc/index.html | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/doc/index.html b/doc/index.html index 5420f3e..e376145 100644 --- a/doc/index.html +++ b/doc/index.html @@ -478,6 +478,61 @@ JCommander jc = new JCommander(new Args()); jc.setDefaultProvider(DEFAULT_PROVIDER); +

      More complex syntaxes

      + +Complex tools such as git or svn understand a whole set of commands, each of which with their own specific syntax: + +
      +  git commit --amend -m "Bug fix"
      +
      + +Words such as "commit" above are called "commands" in JCommander, and you can specify them by creating one arg object per command: + +
      +@Parameters(separators = "=")
      +public class CommandCommit {
      +
      +  @Parameter(description = "Record changes to the repository")
      +  public List<String> files;
      +
      +  @Parameter(names = "--amend", description = "Amend")
      +  public Boolean amend = false;
      +
      +  @Parameter(names = "--author")
      +  public String author;
      +}
      +
      + +
      +public class CommandAdd {
      +
      +  @Parameter(description = "Add file contents to the index")
      +  public List<String> patterns;
      +
      +  @Parameter(names = "-i")
      +  public Boolean interactive = false;
      +}
      +
      + +Then you register these commands with your JCommander object. After the parsing phase, you call getParsedCommand() on your JCommander object, and based on the command that is returned, you know which arg object to inspect (you can still use a main arg object if you want to support options before the first command appears on the command line): + +
      +CommandMain cm = new CommandMain();
      +JCommander jc = new JCommander(cm);
      +
      +CommandAdd add = new CommandAdd();
      +jc.addCommand("add", add);
      +CommandCommit commit = new CommandCommit();
      +jc.addCommand("commit", commit);
      +
      +jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java");
      +
      +Assert.assertTrue(cm.verbose);
      +Assert.assertEquals(jc.getParsedCommand(), "commit");
      +Assert.assertTrue(commit.amend);
      +Assert.assertEquals(commit.author, "cbeust");
      +Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java"));
      +

      Exception

      -- cgit v1.2.3 From 2384cc9b2d354441c7faef9d6703baf307c65d45 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Aug 2010 21:59:22 -0700 Subject: Added overloaded versions of usage() with StringBuilders --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 43 +++++++++++++++------- .../com/beust/jcommander/command/CommandTest.java | 11 ++++-- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8c7bbfe..9c1d6f3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ 1.5 +Added overloaded versions of usage() with StringBuilders Added inheritance support (Guillaume Sauthier) Added support for commands (e.g. "main add --author=cbeust Foo.java") Added support for converters for main parameters (e.g. List). diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 283f9aa..bfef376 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -579,7 +579,26 @@ public class JCommander { return result; } + /** + * Set the program name (used only in the usage). + */ + public void setProgramName(String name) { + m_programName = name; + } + + /** + * Display the usage for this command. + */ public void usage(String commandName) { + StringBuilder sb = new StringBuilder(); + usage(commandName, sb); + System.out.println(sb.toString()); + } + + /** + * Store the help for the command in the passed string builder. + */ + public void usage(String commandName, StringBuilder out) { Object o = m_commands.get(commandName); Object object; try { @@ -597,16 +616,18 @@ public class JCommander { } /** - * Set the program name (used only in the usage). + * Display a the help on System.out. */ - public void setProgramName(String name) { - m_programName = name; + public void usage() { + StringBuilder sb = new StringBuilder(); + usage(sb); + System.out.println(sb.toString()); } /** - * Display a the help on System.out. + * Store the help in the passed string builder. */ - public void usage() { + public void usage(StringBuilder out) { if (m_descriptions == null) createDescriptions(); boolean hasCommands = ! m_commands.isEmpty(); @@ -614,13 +635,12 @@ public class JCommander { // First line of the usage // String programName = m_programName != null ? m_programName : "
      "; - StringBuilder sb = new StringBuilder("Usage: " + programName + " [options]"); - if (hasCommands) sb.append(" [command] [command options]"); + out.append("Usage: " + programName + " [options]"); + if (hasCommands) out.append(" [command] [command options]"); if (m_mainParameterAnnotation != null) { - sb.append(" " + m_mainParameterAnnotation.description()); + out.append(" " + m_mainParameterAnnotation.description()); } - sb.append("\n Options:"); - System.out.println(sb.toString()); + out.append("\n Options:"); // // Align the descriptions at the "longestName" column @@ -651,7 +671,6 @@ public class JCommander { // // Display all the names and descriptions // - StringBuilder out = new StringBuilder(); for (ParameterDescription pd : sorted) { int l = pd.getNames().length(); int spaceCount = longestName - l; @@ -685,8 +704,6 @@ public class JCommander { out.append(" " + name + s(spaceCount) + jc.getMainParameterDescription() + "\n"); } } - - System.out.println(out); } /** diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java index 3f59e19..363d241 100644 --- a/src/test/java/com/beust/jcommander/command/CommandTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -50,9 +50,11 @@ public class CommandTest { CommandCommit commit = new CommandCommit(); jc.addCommand("commit", commit); jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); -// jc.usage(); -// jc.usage("add"); -// jc.usage("commit"); + + jc.setProgramName("TestCommander"); + jc.usage(); + jc.usage("add"); + jc.usage("commit"); Assert.assertTrue(cm.verbose); Assert.assertEquals(jc.getParsedCommand(), "commit"); @@ -61,4 +63,7 @@ public class CommandTest { Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); } + public static void main(String[] args) { + new CommandTest().commandTest2(); + } } -- cgit v1.2.3 From 30417dcf4561b3fe8d9848f5a4d5c654fd015340 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Aug 2010 22:02:16 -0700 Subject: Commented out a few lines --- src/test/java/com/beust/jcommander/command/CommandTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java index 363d241..0bedeeb 100644 --- a/src/test/java/com/beust/jcommander/command/CommandTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -51,10 +51,10 @@ public class CommandTest { jc.addCommand("commit", commit); jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java"); - jc.setProgramName("TestCommander"); - jc.usage(); - jc.usage("add"); - jc.usage("commit"); +// jc.setProgramName("TestCommander"); +// jc.usage(); +// jc.usage("add"); +// jc.usage("commit"); Assert.assertTrue(cm.verbose); Assert.assertEquals(jc.getParsedCommand(), "commit"); -- cgit v1.2.3 From 3d2c641fc513ffb4fbbd2515957fbf6767974577 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Aug 2010 11:54:14 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 82484ee..23f3f32 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.5-SNAPSHOT + 1.5 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From b5eff7a41137d62788593ee971e9c72dc9e6d4a3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Aug 2010 11:54:20 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 23f3f32..2d0c49d 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.5 + 1.6-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 352b129e4630f602cc705668bf30e392f8b5060a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 8 Aug 2010 09:15:56 -0700 Subject: JCommander 1.5 --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index e376145..36cec59 100644 --- a/doc/index.html +++ b/doc/index.html @@ -604,7 +604,7 @@ You can download JCommander from the following locations:
      • Source on github
      • -
      • Jar file
      • +
      • Jar file
      • Or if you are using Maven, add the following dependency to your pom.xml:
        @@ -612,7 +612,7 @@ You can download JCommander from the following locations:
         
           com.beust
           jcommander
        -  1.4
        +  1.5
         
           
        -- cgit v1.2.3 From 72cacbaebb04753ddba0c8dc0f9328310e8cb222 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 15 Aug 2010 17:23:00 -0700 Subject: Added: now throwing an exception if required main parameters are not supplied --- CHANGELOG | 17 +++++--- doc/index.html | 45 +++++++++++++--------- src/main/java/com/beust/jcommander/JCommander.java | 12 +++++- .../java/com/beust/jcommander/JCommanderTest.java | 9 +++-- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9c1d6f3..4ba85a0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,12 +1,17 @@ +1.6 + +Added: now throwing an exception if required main parameters are not supplied + 1.5 +2010/08/15 -Added overloaded versions of usage() with StringBuilders -Added inheritance support (Guillaume Sauthier) -Added support for commands (e.g. "main add --author=cbeust Foo.java") -Added support for converters for main parameters (e.g. List). +Added: overloaded versions of usage() with StringBuilders +Added: inheritance support (Guillaume Sauthier) +Added: support for commands (e.g. "main add --author=cbeust Foo.java") +Added: support for converters for main parameters (e.g. List). 1.4 -2010/08/28 +2010/07/28 Added string converter factories Added IDefaultProvider @@ -16,7 +21,7 @@ Support for values that look like parameters ("-integer -3", "/file /tmp/a") Added @Parameters(optionPrefixes) to allow for different prefixes than "-" 1.2 -2010/08/25 +2010/07/25 Usage is now aligned and alphabetically sorted Added the hidden attribute diff --git a/doc/index.html b/doc/index.html index 36cec59..07d93a4 100644 --- a/doc/index.html +++ b/doc/index.html @@ -38,8 +38,13 @@ Cédric Beust +

        Table of contents

        +
        +
        -

        Overview

        + + +

        Overview

        JCommander is a very small Java framework that makes it trivial to parse command line parameters.

        @@ -73,7 +78,7 @@ new JCommander(jct, argv); Assert.assertEquals(jct.verbose.intValue(), 2); -

        Types of options

        +

        Types of options

        The fields representing your parameters can be of any type. Basic types (Integer, Boolean., etc...) are supported by default and you can write type converters to support any other type (File, etc...). @@ -145,7 +150,7 @@ Value for -password (Connection password): You will need to type the value at this point before JCommander resumes. -

        Custom types

        +

        Custom types

        By annotation

        @@ -254,7 +259,7 @@ All you need to do is add the factory to your JCommander object: Another advantage of using string converter factories is that your factories can come from a dependency injection framework. -

        Main parameter

        +

        Main parameter

        So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a List<String> and it will contain all the parameters that are not options:
        @@ -273,7 +278,7 @@ java Main -debug file1 file2
         
         and the field files will receive the strings "file1" and "file2".
         
        -

        Private parameters

        +

        Private parameters

        Parameters can be private: @@ -294,7 +299,7 @@ new JCommander(args, "-verbose", "3"); Assert.assertEquals(args.getVerbose().intValue(), 3);
        -

        Parameter separators

        +

        Parameter separators

        By default, parameters are separated by spaces, but you can change this setting to allow different separators: @@ -322,7 +327,7 @@ public class SeparatorEqual { -

        Multiple descriptions

        +

        Multiple descriptions

        You can spread the description of your parameters on more than one class. For example, you can define the following two classes: @@ -358,7 +363,7 @@ Assert.assertEquals(s.slave, "slave"); -

        @ syntax

        +

        @ syntax

        JCommander supports the @ syntax, which allows you to put all your options into a file and pass this file as parameter: @@ -375,7 +380,7 @@ file3 java Main @/tmp/parameters -

        Arities (multiple values for parameters)

        +

        Arities (multiple values for parameters)

        If some of your parameters require more than one value, such as the following example where two values are expected after -pairs: @@ -403,7 +408,7 @@ parameters that define an arity. You will have to convert these values yourself if the parameters you need are of type Integer or other (this limitation is due to Java's erasure). -

        Multiple option names

        +

        Multiple option names

        You can specify more than one option name: @@ -421,7 +426,7 @@ java Main -d /tmp java Main --outputDirectory /tmp -

        Required and optional parameters

        +

        Required and optional parameters

        If some of your parameters are mandatory, you can use the required attribute (which default to false): @@ -436,7 +441,7 @@ If some of your parameters are mandatory, you can use the If this parameter is not specified, JCommander will throw an exception telling you which options are missing. -

        Default values

        +

        Default values

        The most common way to specify a default value for your parameters is to initialize the field at declaration time: @@ -478,7 +483,7 @@ JCommander jc = new JCommander(new Args()); jc.setDefaultProvider(DEFAULT_PROVIDER); -

        More complex syntaxes

        +

        More complex syntaxes

        Complex tools such as git or svn understand a whole set of commands, each of which with their own specific syntax: @@ -534,7 +539,7 @@ Assert.assertEquals(commit.author, "cbeust"); Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); -

        Exception

        +

        Exception

        Whenever JCommander detects an error, it will throw a ParameterException. Note that this is a Runtime Exception, @@ -542,7 +547,7 @@ since your application is probably not initialized correctly at this point. -

        Usage

        +

        Usage

        You can invoke usage() on the JCommander instance that you used to parse your command line in order to generate a summary of all the options that your program understands: @@ -557,7 +562,7 @@ Usage: <main class> [options] Options preceded by an asterisk are required. -

        Hiding parameters

        +

        Hiding parameters

        If you don't want certain parameters to appear in the usage, you can mark them as "hidden": @@ -566,7 +571,7 @@ If you don't want certain parameters to appear in the usage, you can mark them a public boolean debug = false; -

        Internationalization

        +

        Internationalization

        You can internationalize the descriptions of your parameters. @@ -594,11 +599,11 @@ host: Hôte JCommander will then use the default locale to resolve your descriptions. -

        More examples

        +

        More examples

        TestNG uses JCommander to parse its command line, here is its definition file. -

        Download

        +

        Download

        You can download JCommander from the following locations: @@ -622,4 +627,6 @@ You can download JCommander from the following locations: + + diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index bfef376..c4bf542 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -83,6 +83,8 @@ public class JCommander { */ private Parameter m_mainParameterAnnotation; + private ParameterDescription m_mainParameterDescription; + /** * A set of all the fields that are required. During the reflection phase, * this field receives all the fields that are annotated with required=true @@ -203,7 +205,14 @@ public class JCommander { } throw new ParameterException("The following options are required: " + missingFields); } - + + if (m_mainParameterDescription != null) { + if (m_mainParameterDescription.getParameter().required() && + !m_mainParameterDescription.wasAssigned()) { + throw new ParameterException("Main parameters are required (\"" + + m_mainParameterDescription.getDescription() + "\")"); + } + } } /** @@ -384,6 +393,7 @@ public class JCommander { m_mainParameterField = f; m_mainParameterObject = object; m_mainParameterAnnotation = p; + m_mainParameterDescription = new ParameterDescription(object, p, f, m_bundle, this); } else { for (String name : p.names()) { if (m_descriptions.containsKey(name)) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index cc7cc38..6d55ed1 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -30,6 +30,7 @@ import com.beust.jcommander.args.ArgsInherited; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; +import com.beust.jcommander.args.ArgsRequired; import com.beust.jcommander.args.ArgsSlave; import com.beust.jcommander.args.ArgsSlaveBogus; import com.beust.jcommander.args.SeparatorColon; @@ -304,9 +305,11 @@ public class JCommanderTest { Assert.assertEquals(a.verbose.intValue(), -3); } - @Test + @Test(expectedExceptions = ParameterException.class) public void requiredMainParameters() { - // + ArgsRequired a = new ArgsRequired(); + String[] argv = {}; + new JCommander(a, argv); } @DataProvider @@ -321,7 +324,7 @@ public class JCommanderTest { } public static void main(String[] args) { -// new JCommanderTest().commandTest2(); + new JCommanderTest().requiredMainParameters(); // new CommandTest().commandTest2(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); -- cgit v1.2.3 From abcd2cb029dfedf65af847a2a367fcb95f7c9134 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 15 Aug 2010 17:23:30 -0700 Subject: Minor fix --- CHANGELOG | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4ba85a0..f45abbe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,12 +13,12 @@ Added: support for converters for main parameters (e.g. List). 1.4 2010/07/28 -Added string converter factories -Added IDefaultProvider -Added PropertyFileDefaultProvider -Usage is now showing required parameters and default value -Support for values that look like parameters ("-integer -3", "/file /tmp/a") -Added @Parameters(optionPrefixes) to allow for different prefixes than "-" +Added: string converter factories +Added: IDefaultProvider +Added: PropertyFileDefaultProvider +Added: Usage is now showing required parameters and default value +Added: Support for values that look like parameters ("-integer -3", "/file /tmp/a") +Added: @Parameters(optionPrefixes) to allow for different prefixes than "-" 1.2 2010/07/25 -- cgit v1.2.3 From 0bf62c0269798a001ef93dcf9bb9776a95f6052f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 16 Aug 2010 19:49:42 -0700 Subject: Renaming --- src/main/java/com/beust/jcommander/JCommander.java | 5 ++-- .../com/beust/jcommander/ParameterDescription.java | 7 ++++- .../com/beust/jcommander/args/ArgsRequired.java | 31 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/args/ArgsRequired.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index c4bf542..a2d640a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -208,7 +208,7 @@ public class JCommander { if (m_mainParameterDescription != null) { if (m_mainParameterDescription.getParameter().required() && - !m_mainParameterDescription.wasAssigned()) { + !m_mainParameterDescription.isAssigned()) { throw new ParameterException("Main parameters are required (\"" + m_mainParameterDescription.getDescription() + "\")"); } @@ -511,6 +511,7 @@ public class JCommander { } } + m_mainParameterDescription.setAssigned(true); mp.add(convertedValue); } else { @@ -688,7 +689,7 @@ public class JCommander { + (pd.getParameter().required() ? "* " : " ") + pd.getNames() + s(spaceCount) + pd.getDescription()); try { - if (! pd.wasAssigned()) { + if (! pd.isAssigned()) { Object def = pd.getField().get(pd.getObject()); if (def != null) out.append(" (default: " + def + ")"); } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 6adbc09..015a897 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -128,10 +128,15 @@ public class ParameterDescription { /** * @return true if this parameter received a value during the parsing phase. */ - public boolean wasAssigned() { + public boolean isAssigned() { return m_assigned; } + + public void setAssigned(boolean b) { + m_assigned = true; + } + /** * Add the specified value to the field. First look up any field converter, then * any type converter, and if we can't find any, throw an exception. diff --git a/src/test/java/com/beust/jcommander/args/ArgsRequired.java b/src/test/java/com/beust/jcommander/args/ArgsRequired.java new file mode 100644 index 0000000..69cb814 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsRequired.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.internal.Lists; + +import java.util.List; + +public class ArgsRequired { + + @Parameter(description = "List of files", required = true) + public List parameters = Lists.newArrayList(); + +} -- cgit v1.2.3 From b89d58db97bc7514cc20f6758f413088aea5672d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 16 Aug 2010 21:45:23 -0700 Subject: Applied jstrachan's patch for usage --- src/main/java/com/beust/jcommander/JCommander.java | 53 ++++++++-------------- .../com/beust/jcommander/ParameterDescription.java | 10 ++++ 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index a2d640a..67b8208 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -110,7 +110,7 @@ public class JCommander { /** * List of commands and their instance. */ - private Map m_commands = Maps.newHashMap(); + private Map m_commands = Maps.newHashMap(); /** * The name of the command after the parsing has run. @@ -518,15 +518,13 @@ public class JCommander { // // Command parsing // - Object o = m_commands.get(arg); - if (o == null) throw new ParameterException("Expected a command, got " + arg); + JCommander jc = m_commands.get(arg); + if (jc == null) throw new ParameterException("Expected a command, got " + arg); m_parsedCommand = arg; - // Found a valid command, create a new JCommander object with its - // description object and ask it to parse the remainder of the arguments. + // Found a valid command, ask it to parse the remainder of the arguments. // Setting the boolean commandParsed to true will force the current // loop to end. - JCommander jc = new JCommander(o); jc.parse(subArray(args, i + 1)); commandParsed = true; } @@ -610,20 +608,13 @@ public class JCommander { * Store the help for the command in the passed string builder. */ public void usage(String commandName, StringBuilder out) { - Object o = m_commands.get(commandName); - Object object; - try { - // Create a new object since o might have received values - // and might therefore display default values that are incorrect. - object = o.getClass().newInstance(); - JCommander jc = new JCommander(object); - jc.setProgramName(commandName); - jc.usage(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); + JCommander jc = m_commands.get(commandName); + String description = jc.getMainParameterDescription(); + if (description != null) { + out.append(description); + out.append("\n"); } + jc.usage(out); } /** @@ -688,17 +679,8 @@ public class JCommander { out.append(" " + (pd.getParameter().required() ? "* " : " ") + pd.getNames() + s(spaceCount) + pd.getDescription()); - try { - if (! pd.isAssigned()) { - Object def = pd.getField().get(pd.getObject()); - if (def != null) out.append(" (default: " + def + ")"); - } - } catch (IllegalArgumentException e) { - // ignore - } catch (IllegalAccessException e) { - // ignore - } - out.append("\n"); + Object def = pd.getDefault(); + if (def != null) out.append(" (default: " + def + ")"); out.append("\n"); } // @@ -707,11 +689,10 @@ public class JCommander { if (hasCommands) { out.append(" Commands:\n"); int ln = longestName(m_commands.keySet()) + 3; - for (Map.Entry commands : m_commands.entrySet()) { + for (Map.Entry commands : m_commands.entrySet()) { String name = commands.getKey(); int spaceCount = ln - name.length(); - Object o = commands.getValue(); - JCommander jc = new JCommander(o); + JCommander jc = commands.getValue(); out.append(" " + name + s(spaceCount) + jc.getMainParameterDescription() + "\n"); } } @@ -840,8 +821,10 @@ public class JCommander { /** * Add a command object. */ - public void addCommand(String string, Object object) { - m_commands.put(string, object); + public void addCommand(String name, Object object) { + JCommander jc = new JCommander(object); + jc.setProgramName(name); + m_commands.put(name, jc); } public String getParsedCommand() { diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 015a897..f265cae 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -37,6 +37,7 @@ public class ParameterDescription { private ResourceBundle m_bundle; private String m_description; private JCommander m_jCommander; + private Object m_default; public ParameterDescription(Object object, Parameter annotation, Field field, ResourceBundle bundle, JCommander jc) { @@ -89,6 +90,15 @@ public class ParameterDescription { // "default description:'" + m_description + "'"); } } + + try { + m_default = m_field.get(m_object); + } catch (Exception e) { + } + } + + public Object getDefault() { + return m_default; } public String getDescription() { -- cgit v1.2.3 From a76d5b9a334e8600d0bc7b0c51506cf4e67e1a3a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 16 Aug 2010 21:48:14 -0700 Subject: Updated CHANGELOG --- CHANGELOG | 1 + src/test/java/com/beust/jcommander/JCommanderTest.java | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f45abbe..28b15d5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ 1.6 Added: now throwing an exception if required main parameters are not supplied +Fixed: usage() was changing default values after two runs (jstrachan) 1.5 2010/08/15 diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 6d55ed1..7ca1261 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -312,6 +312,19 @@ public class JCommanderTest { new JCommander(a, argv); } + @Test + public void usageShouldNotChange() { + JCommander jc = new JCommander(new Args1(), new String[]{"-log", "1"}); + StringBuilder sb = new StringBuilder(); + jc.usage(sb); + String expected = sb.toString(); + jc = new JCommander(new Args1(), new String[]{"-debug", "-log", "2", "-long", "5"}); + sb = new StringBuilder(); + jc.usage(sb); + String actual = sb.toString(); + Assert.assertEquals(actual, expected); + } + @DataProvider public static Object[][] f() { return new Integer[][] { -- cgit v1.2.3 From 30e1bb6cbc100c085435a7abdae9d272603726b3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 16 Aug 2010 22:32:40 -0700 Subject: Added Javadoc comments --- src/main/java/com/beust/jcommander/JCommander.java | 13 ++++++++++++- .../java/com/beust/jcommander/converters/BaseConverter.java | 5 +++++ .../com/beust/jcommander/converters/BooleanConverter.java | 5 +++++ .../jcommander/converters/CommaSeparatedConverter.java | 5 +++++ .../java/com/beust/jcommander/converters/FileConverter.java | 5 +++++ .../com/beust/jcommander/converters/IntegerConverter.java | 5 +++++ .../java/com/beust/jcommander/converters/LongConverter.java | 5 +++++ .../java/com/beust/jcommander/converters/NoConverter.java | 5 +++++ .../com/beust/jcommander/converters/StringConverter.java | 5 +++++ 9 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 67b8208..a34a861 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -128,16 +128,27 @@ public class JCommander { CONVERTER_FACTORIES.add(new DefaultConverterFactory()); }; + /** + * @param object The arg object expected to contain {@link @Parameter} annotations. + */ public JCommander(Object object) { init(object, null); } + /** + * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param bundle The bundle to use for the descriptions. Can be null. + * @param args The arguments to parse (optional). + */ public JCommander(Object object, ResourceBundle bundle, String... args) { init(object, bundle); parse(args); } - + /** + * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param args The arguments to parse (optional). + */ public JCommander(Object object, String... args) { init(object, null); parse(args); diff --git a/src/main/java/com/beust/jcommander/converters/BaseConverter.java b/src/main/java/com/beust/jcommander/converters/BaseConverter.java index c560af3..4287163 100644 --- a/src/main/java/com/beust/jcommander/converters/BaseConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BaseConverter.java @@ -20,6 +20,11 @@ package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; +/** + * Base class for converters that stores the name of the option. + * + * @author cbeust + */ abstract public class BaseConverter implements IStringConverter { private String m_optionName; diff --git a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java index 9ca299f..35188ca 100644 --- a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java @@ -20,6 +20,11 @@ package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; +/** + * Converts a string to a boolean. + * + * @author cbeust + */ public class BooleanConverter extends BaseConverter { public BooleanConverter(String optionName) { diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java index 252aa6e..033138a 100644 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java @@ -23,6 +23,11 @@ import com.beust.jcommander.IStringConverter; import java.util.Arrays; import java.util.List; +/** + * Convert a string of comma separated words into a list of string. + * + * @author cbeust + */ public class CommaSeparatedConverter implements IStringConverter> { @Override diff --git a/src/main/java/com/beust/jcommander/converters/FileConverter.java b/src/main/java/com/beust/jcommander/converters/FileConverter.java index a54ec83..ea4d9ba 100644 --- a/src/main/java/com/beust/jcommander/converters/FileConverter.java +++ b/src/main/java/com/beust/jcommander/converters/FileConverter.java @@ -22,6 +22,11 @@ import com.beust.jcommander.IStringConverter; import java.io.File; +/** + * Convert a string into a file. + * + * @author cbeust + */ public class FileConverter implements IStringConverter { @Override diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java index 766bd11..be38126 100644 --- a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java @@ -20,6 +20,11 @@ package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; +/** + * Convert a string to an integer. + * + * @author cbeust + */ public class IntegerConverter extends BaseConverter { public IntegerConverter(String optionName) { diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java index 5dd8b6a..bbfa0cf 100644 --- a/src/main/java/com/beust/jcommander/converters/LongConverter.java +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java @@ -20,6 +20,11 @@ package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; +/** + * Convert a string to a long. + * + * @author cbeust + */ public class LongConverter extends BaseConverter { public LongConverter(String optionName) { diff --git a/src/main/java/com/beust/jcommander/converters/NoConverter.java b/src/main/java/com/beust/jcommander/converters/NoConverter.java index eac2ef5..c670258 100644 --- a/src/main/java/com/beust/jcommander/converters/NoConverter.java +++ b/src/main/java/com/beust/jcommander/converters/NoConverter.java @@ -20,6 +20,11 @@ package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; +/** + * Default value for a converter when none is specified. + * + * @author cbeust + */ public class NoConverter implements IStringConverter { @Override diff --git a/src/main/java/com/beust/jcommander/converters/StringConverter.java b/src/main/java/com/beust/jcommander/converters/StringConverter.java index 2971a9c..1dce8b8 100644 --- a/src/main/java/com/beust/jcommander/converters/StringConverter.java +++ b/src/main/java/com/beust/jcommander/converters/StringConverter.java @@ -20,6 +20,11 @@ package com.beust.jcommander.converters; import com.beust.jcommander.IStringConverter; +/** + * Default converter for strings. + * + * @author cbeust + */ public class StringConverter implements IStringConverter { @Override -- cgit v1.2.3 From 29f59c27f3fd730f0b2ec02bd3a0db799dfa27a8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 16 Aug 2010 22:41:49 -0700 Subject: Added newline in the usage --- doc/index.html | 5 +++++ src/main/java/com/beust/jcommander/JCommander.java | 1 + 2 files changed, 6 insertions(+) diff --git a/doc/index.html b/doc/index.html index 07d93a4..e6fb95e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -603,6 +603,11 @@ JCommander will then use the default locale to resolve your descriptions. TestNG uses JCommander to parse its command line, here is its definition file. + +

        Javadocs

        + +The Javadocs for JCommander can be found here. +

        Download

        You can download JCommander from the following locations: diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index a34a861..9fc2dd3 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -650,6 +650,7 @@ public class JCommander { String programName = m_programName != null ? m_programName : "
        "; out.append("Usage: " + programName + " [options]"); if (hasCommands) out.append(" [command] [command options]"); + out.append("\n"); if (m_mainParameterAnnotation != null) { out.append(" " + m_mainParameterAnnotation.description()); } -- cgit v1.2.3 From dda1651c0b74aa9e8d225096f1d531871460e692 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 25 Aug 2010 18:54:58 -0700 Subject: Added: @Parameters(commandDescription = "command description") --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 35 +++++++++++++++++----- src/main/java/com/beust/jcommander/Parameters.java | 7 +++++ .../java/com/beust/jcommander/JCommanderTest.java | 15 ++++++++-- .../com/beust/jcommander/command/CommandAdd.java | 4 ++- .../beust/jcommander/command/CommandCommit.java | 4 +-- .../com/beust/jcommander/command/CommandMain.java | 2 +- 7 files changed, 55 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 28b15d5..ba9d43e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ 1.6 +Added: @Parameters(commandDescription = "command description") Added: now throwing an exception if required main parameters are not supplied Fixed: usage() was changing default values after two runs (jstrachan) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 9fc2dd3..d1f2ea1 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -619,13 +619,25 @@ public class JCommander { * Store the help for the command in the passed string builder. */ public void usage(String commandName, StringBuilder out) { - JCommander jc = m_commands.get(commandName); - String description = jc.getMainParameterDescription(); + String description = getCommandDescription(commandName); + if (description != null) { out.append(description); out.append("\n"); } - jc.usage(out); + usage(out); + } + + /** + * @return the description of the command. + */ + public String getCommandDescription(String commandName) { + JCommander jc = m_commands.get(commandName); + Parameters p = jc.getObjects().get(0).getClass().getAnnotation(Parameters.class); + String result = jc.getMainParameterDescription(); + if (p != null) result = p.commandDescription(); + + return result; } /** @@ -652,9 +664,9 @@ public class JCommander { if (hasCommands) out.append(" [command] [command options]"); out.append("\n"); if (m_mainParameterAnnotation != null) { - out.append(" " + m_mainParameterAnnotation.description()); + out.append(" " + m_mainParameterAnnotation.description() + "\n"); } - out.append("\n Options:"); + out.append(" Options:"); // // Align the descriptions at the "longestName" column @@ -700,12 +712,13 @@ public class JCommander { // if (hasCommands) { out.append(" Commands:\n"); + // The magic value 3 is the number of spaces between the name of the option + // and its description int ln = longestName(m_commands.keySet()) + 3; for (Map.Entry commands : m_commands.entrySet()) { String name = commands.getKey(); int spaceCount = ln - name.length(); - JCommander jc = commands.getValue(); - out.append(" " + name + s(spaceCount) + jc.getMainParameterDescription() + "\n"); + out.append(" " + name + s(spaceCount) + getCommandDescription(name) + "\n"); } } } @@ -854,5 +867,13 @@ public class JCommander { return result.toString(); } + + /** + * @return the objects that JCommander will fill with the result of + * parsing the command line. + */ + public List getObjects() { + return m_objects; + } } diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index b716ebe..8f1cf82 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -48,4 +48,11 @@ public @interface Parameters { * What characters an option starts with. */ String optionPrefixes() default DEFAULT_OPTION_PREFIXES; + + /** + * If this class was added to {@link JCommander} as a command {@see JCommander#addCommand}, + * then this string will be displayed in the description when @{link JCommander#usage} is + * invoked. + */ + String commandDescription() default ""; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 7ca1261..ca8c97d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -37,6 +37,9 @@ import com.beust.jcommander.args.SeparatorColon; import com.beust.jcommander.args.SeparatorEqual; import com.beust.jcommander.args.SeparatorMixed; import com.beust.jcommander.args.SlashSeparator; +import com.beust.jcommander.command.CommandAdd; +import com.beust.jcommander.command.CommandCommit; +import com.beust.jcommander.command.CommandMain; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -337,8 +340,16 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().requiredMainParameters(); -// new CommandTest().commandTest2(); + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit); + jc.usage(); + +// new JCommanderTest().requiredMainParameters(); +// new CommandTest().commandTest1(); // new DefaultProviderTest().defaultProvider1(); // ArgsMainParameter a = new ArgsMainParameter(); // new JCommander(a, "ex1:10", "ex2:20"); diff --git a/src/test/java/com/beust/jcommander/command/CommandAdd.java b/src/test/java/com/beust/jcommander/command/CommandAdd.java index 0e07da5..733e490 100644 --- a/src/test/java/com/beust/jcommander/command/CommandAdd.java +++ b/src/test/java/com/beust/jcommander/command/CommandAdd.java @@ -19,12 +19,14 @@ package com.beust.jcommander.command; import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; import java.util.List; +@Parameters(commandDescription = "Add file contents to the index") public class CommandAdd { - @Parameter(description = "Add file contents to the index") + @Parameter(description = "Patterns of files to be added") public List patterns; @Parameter(names = "-i") diff --git a/src/test/java/com/beust/jcommander/command/CommandCommit.java b/src/test/java/com/beust/jcommander/command/CommandCommit.java index 52fcba3..2934a89 100644 --- a/src/test/java/com/beust/jcommander/command/CommandCommit.java +++ b/src/test/java/com/beust/jcommander/command/CommandCommit.java @@ -23,10 +23,10 @@ import com.beust.jcommander.Parameters; import java.util.List; -@Parameters(separators = "=") +@Parameters(separators = "=", commandDescription = "Record changes to the repository") public class CommandCommit { - @Parameter(description = "Record changes to the repository") + @Parameter(description = "List of files") public List files; @Parameter(names = "--amend", description = "Amend") diff --git a/src/test/java/com/beust/jcommander/command/CommandMain.java b/src/test/java/com/beust/jcommander/command/CommandMain.java index b2c32f4..c205116 100644 --- a/src/test/java/com/beust/jcommander/command/CommandMain.java +++ b/src/test/java/com/beust/jcommander/command/CommandMain.java @@ -22,6 +22,6 @@ import com.beust.jcommander.Parameter; public class CommandMain { - @Parameter(names = "-v") + @Parameter(names = "-v", description = "Verbose mode") public Boolean verbose = false; } -- cgit v1.2.3 From 8c739694e49b3949637c8467f3847e2530db0694 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 25 Aug 2010 18:55:49 -0700 Subject: Script to build with Maven --- build-with-maven | 2 ++ 1 file changed, 2 insertions(+) create mode 100755 build-with-maven diff --git a/build-with-maven b/build-with-maven new file mode 100755 index 0000000..fa8a935 --- /dev/null +++ b/build-with-maven @@ -0,0 +1,2 @@ +mvn source:jar javadoc:jar repository:bundle-create -P sign + -- cgit v1.2.3 From b4592e441d1440228d0576efa21b56d247266b1e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 25 Aug 2010 18:56:16 -0700 Subject: Upload script --- upload | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 upload diff --git a/upload b/upload new file mode 100755 index 0000000..39c862d --- /dev/null +++ b/upload @@ -0,0 +1,3 @@ +scp doc/index.html target/jcommander-1.6.jar beust.com@beust.com:w/jcommander +scp -r target/site/apidocs beust.com@beust.com:w/jcommander + -- cgit v1.2.3 From fed6fcff8e6358753e73d923a02938ee44c0177c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 25 Aug 2010 19:09:49 -0700 Subject: Updated doc to include commandDescription --- doc/index.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/index.html b/doc/index.html index e6fb95e..8a8ae1e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -483,7 +483,7 @@ JCommander jc = new JCommander(new Args()); jc.setDefaultProvider(DEFAULT_PROVIDER); -

        More complex syntaxes

        +

        More complex syntaxes (commands)

        Complex tools such as git or svn understand a whole set of commands, each of which with their own specific syntax: @@ -494,10 +494,10 @@ Complex tools such as git or svn understand a whole set of com Words such as "commit" above are called "commands" in JCommander, and you can specify them by creating one arg object per command:
        -@Parameters(separators = "=")
        +@Parameters(separators = "=", commandDescription = "Record changes to the repository")
         public class CommandCommit {
         
        -  @Parameter(description = "Record changes to the repository")
        +  @Parameter(description = "The list of files to commit")
           public List<String> files;
         
           @Parameter(names = "--amend", description = "Amend")
        @@ -509,9 +509,10 @@ public class CommandCommit {
         
        +@Parameters(commandDescription = "Add file contents to the index")
         public class CommandAdd {
         
        -  @Parameter(description = "Add file contents to the index")
        +  @Parameter(description = "File patterns to add to the index")
           public List<String> patterns;
         
           @Parameter(names = "-i")
        -- 
        cgit v1.2.3
        
        
        From bf0a9ff5540101854db06ab3f6e474a0e7a10d76 Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Wed, 25 Aug 2010 19:10:58 -0700
        Subject: [maven-release-plugin] prepare release jcommander-1.6
        
        ---
         pom.xml | 2 +-
         1 file changed, 1 insertion(+), 1 deletion(-)
        
        diff --git a/pom.xml b/pom.xml
        index 2d0c49d..1a5f848 100644
        --- a/pom.xml
        +++ b/pom.xml
        @@ -24,7 +24,7 @@
           jcommander
           jar
           JCommander
        -  1.6-SNAPSHOT
        +  1.6
           A Java framework to parse command line options with annotations.
           http://beust.com/jcommander
           
        -- 
        cgit v1.2.3
        
        
        From 5ffa71a6d938d696768dd2175a0876f80954b6c4 Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Wed, 25 Aug 2010 19:11:05 -0700
        Subject: [maven-release-plugin] prepare for next development iteration
        
        ---
         pom.xml | 2 +-
         1 file changed, 1 insertion(+), 1 deletion(-)
        
        diff --git a/pom.xml b/pom.xml
        index 1a5f848..a3fb0ef 100644
        --- a/pom.xml
        +++ b/pom.xml
        @@ -24,7 +24,7 @@
           jcommander
           jar
           JCommander
        -  1.6
        +  1.7-SNAPSHOT
           A Java framework to parse command line options with annotations.
           http://beust.com/jcommander
           
        -- 
        cgit v1.2.3
        
        
        From 2b0f4c4b974d037ffe7961e90458a668ea9738be Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Tue, 31 Aug 2010 22:03:14 -0700
        Subject: Fixed: Minor bug in the command display (Marc Ende)
        
        ---
         src/main/java/com/beust/jcommander/JCommander.java | 4 ++--
         1 file changed, 2 insertions(+), 2 deletions(-)
        
        diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
        index d1f2ea1..b60a1e3 100644
        --- a/src/main/java/com/beust/jcommander/JCommander.java
        +++ b/src/main/java/com/beust/jcommander/JCommander.java
        @@ -620,12 +620,12 @@ public class JCommander {
            */
           public void usage(String commandName, StringBuilder out) {
             String description = getCommandDescription(commandName);
        -
        +    JCommander jc = m_commands.get(commandName);
             if (description != null) {
               out.append(description);
               out.append("\n");
             }
        -    usage(out);
        +    jc.usage(out);
           }
         
           /**
        -- 
        cgit v1.2.3
        
        
        From e97a6429e8ec68a3feecb5d40ec3a75cfbadb526 Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Tue, 31 Aug 2010 22:03:35 -0700
        Subject: CHANGELOG update.
        
        ---
         CHANGELOG | 5 +++++
         1 file changed, 5 insertions(+)
        
        diff --git a/CHANGELOG b/CHANGELOG
        index ba9d43e..a101e00 100644
        --- a/CHANGELOG
        +++ b/CHANGELOG
        @@ -1,4 +1,9 @@
        +1.7
        +
        +Fixed: Minor bug in the command display (Marc Ende)
        +
         1.6
        +2010/08/28
         
         Added: @Parameters(commandDescription = "command description")
         Added: now throwing an exception if required main parameters are not supplied
        -- 
        cgit v1.2.3
        
        
        From 2932c0bfad421f0fcc5634518b3418bf8453eeda Mon Sep 17 00:00:00 2001
        From: Cedric Beust 
        Date: Tue, 31 Aug 2010 22:03:49 -0700
        Subject: Update doc to 1.6.
        
        ---
         doc/index.html | 4 ++--
         1 file changed, 2 insertions(+), 2 deletions(-)
        
        diff --git a/doc/index.html b/doc/index.html
        index 8a8ae1e..067dfae 100644
        --- a/doc/index.html
        +++ b/doc/index.html
        @@ -615,7 +615,7 @@ You can download JCommander from the following locations:
         
         
        • Source on github
        • -
        • Jar file
        • +
        • Jar file
        • Or if you are using Maven, add the following dependency to your pom.xml:
          @@ -623,7 +623,7 @@ You can download JCommander from the following locations:
           
             com.beust
             jcommander
          -  1.5
          +  1.6
           
             
          -- cgit v1.2.3 From a5355541be1ffe1867657e71d134b77a7747a7ed Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 Aug 2010 22:04:04 -0700 Subject: Javadoc fix. --- src/main/java/com/beust/jcommander/Parameters.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index 8f1cf82..cffc030 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -50,9 +50,9 @@ public @interface Parameters { String optionPrefixes() default DEFAULT_OPTION_PREFIXES; /** - * If this class was added to {@link JCommander} as a command {@see JCommander#addCommand}, - * then this string will be displayed in the description when @{link JCommander#usage} is - * invoked. + * If the annotated class was added to {@link JCommander} as a command with + * {@link JCommander#addCommand}, then this string will be displayed in the + * description when @{link JCommander#usage} is invoked. */ String commandDescription() default ""; } -- cgit v1.2.3 From dffd01e50c8dcdd2139755a69d7bba36c4225180 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 Aug 2010 22:04:16 -0700 Subject: Updated release script. --- release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release b/release index c9a263e..e8b20dc 100644 --- a/release +++ b/release @@ -2,7 +2,7 @@ # Wiki: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide # # deploy without tagging: mvn deploy -DperformRelease -# mvn release:clean release:prepare release:perform +# mvn release:clean javadoc:javadoc release:prepare release:perform mvn release:perform -- cgit v1.2.3 From 4c020da73b8b25773bba8553263cf1954c718573 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 Aug 2010 22:23:52 -0700 Subject: Added: Command usages are now shown in the order they were added to the JCommander object. --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 6 +++- .../java/com/beust/jcommander/internal/Maps.java | 6 ++++ .../java/com/beust/jcommander/JCommanderTest.java | 42 ++++++++++++++++++---- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a101e00..05523fa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ 1.7 +Added: Command usages are now shown in the order they were added to the JCommander object Fixed: Minor bug in the command display (Marc Ende) 1.6 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index b60a1e3..f0c7d5a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -110,7 +110,7 @@ public class JCommander { /** * List of commands and their instance. */ - private Map m_commands = Maps.newHashMap(); + private Map m_commands = Maps.newLinkedHashMap(); /** * The name of the command after the parsing has run. @@ -852,6 +852,10 @@ public class JCommander { m_commands.put(name, jc); } + public Map getCommands() { + return m_commands; + } + public String getParsedCommand() { return m_parsedCommand; } diff --git a/src/main/java/com/beust/jcommander/internal/Maps.java b/src/main/java/com/beust/jcommander/internal/Maps.java index 9b476d0..9238aaa 100644 --- a/src/main/java/com/beust/jcommander/internal/Maps.java +++ b/src/main/java/com/beust/jcommander/internal/Maps.java @@ -19,6 +19,7 @@ package com.beust.jcommander.internal; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; public class Maps { @@ -26,4 +27,9 @@ public class Maps { public static Map newHashMap() { return new HashMap(); } + + public static Map newLinkedHashMap() { + return new LinkedHashMap(); + } + } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index ca8c97d..29f2d1f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -46,7 +46,9 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.util.Arrays; +import java.util.Iterator; import java.util.Locale; +import java.util.Map; import java.util.ResourceBundle; public class JCommanderTest { @@ -328,6 +330,31 @@ public class JCommanderTest { Assert.assertEquals(actual, expected); } + private void verifyCommandOrdering(String[] commandNames, Object[] commands) { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + + for (int i = 0; i < commands.length; i++) { + jc.addCommand(commandNames[i], commands[i]); + } + + Map c = jc.getCommands(); + Assert.assertEquals(c.size(), commands.length); + + Iterator it = c.keySet().iterator(); + for (int i = 0; i < commands.length; i++) { + Assert.assertEquals(it.next(), commandNames[i]); + } + } + + @Test + public void commandsShouldBeShownInOrderOfInsertion() { + verifyCommandOrdering(new String[] { "add", "commit" }, + new Object[] { new CommandAdd(), new CommandCommit() }); + verifyCommandOrdering(new String[] { "commit", "add" }, + new Object[] { new CommandCommit(), new CommandAdd() }); + } + @DataProvider public static Object[][] f() { return new Integer[][] { @@ -340,13 +367,14 @@ public class JCommanderTest { } public static void main(String[] args) { - CommandMain cm = new CommandMain(); - JCommander jc = new JCommander(cm); - CommandAdd add = new CommandAdd(); - jc.addCommand("add", add); - CommandCommit commit = new CommandCommit(); - jc.addCommand("commit", commit); - jc.usage(); + new JCommanderTest().commandsShouldBeShownInOrderOfInsertion(); +// CommandMain cm = new CommandMain(); +// JCommander jc = new JCommander(cm); +// CommandAdd add = new CommandAdd(); +// jc.addCommand("add", add); +// CommandCommit commit = new CommandCommit(); +// jc.addCommand("commit", commit); +// jc.usage(); // new JCommanderTest().requiredMainParameters(); // new CommandTest().commandTest1(); -- cgit v1.2.3 From d4b17eda61dbfe4d3c04e4761f0368eedf145349 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 4 Sep 2010 08:18:37 -0700 Subject: Now working with JDK5 --- pom.xml | 1 + src/main/java/com/beust/jcommander/JCommander.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/pom.xml b/pom.xml index a3fb0ef..cc26d44 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,7 @@ 2.3.1 1.5 + 1.5 UTF-8 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index f0c7d5a..5df0806 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -459,6 +459,7 @@ public class JCommander { // // Password option, use the Console to retrieve the password // + checkJdk6(); Console console = System.console(); if (console == null) { throw new ParameterException("No console is available to get parameter " + a); @@ -545,6 +546,17 @@ public class JCommander { } } + /** + * Aborts if we're not using Java 6. + */ + private void checkJdk6() { + try { + getClass().getClassLoader().loadClass("java.io.Console"); + } catch (ClassNotFoundException e) { + throw new ParameterException("The password option is only available with Java 6."); + } + } + private String[] subArray(String[] args, int index) { int l = args.length - index; String[] result = new String[l]; -- cgit v1.2.3 From ed891ffa6a8894150718d11df446269365bed216 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 4 Sep 2010 20:10:17 -0700 Subject: Now working with Java 5 --- src/main/java/com/beust/jcommander/JCommander.java | 24 +++++++++++----------- .../java/com/beust/jcommander/JCommanderTest.java | 7 ++++++- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 5df0806..00405b1 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -25,13 +25,13 @@ import com.beust.jcommander.internal.Lists; import com.beust.jcommander.internal.Maps; import java.io.BufferedReader; -import java.io.Console; import java.io.FileReader; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; @@ -459,13 +459,7 @@ public class JCommander { // // Password option, use the Console to retrieve the password // - checkJdk6(); - Console console = System.console(); - if (console == null) { - throw new ParameterException("No console is available to get parameter " + a); - } - System.out.print("Value for " + a + " (" + pd.getDescription() + "):"); - char[] password = console.readPassword(); + char[] password = readPassword(pd.getDescription()); pd.addValue(new String(password)); } else { // @@ -547,12 +541,18 @@ public class JCommander { } /** - * Aborts if we're not using Java 6. + * Invoke Console.readPassword through reflection to avoid depending + * on Java 6. */ - private void checkJdk6() { + private char[] readPassword(String description) { try { - getClass().getClassLoader().loadClass("java.io.Console"); - } catch (ClassNotFoundException e) { + Method consoleMethod = System.class.getDeclaredMethod("console", new Class[0]); + Object console = consoleMethod.invoke(null, new Object[0]); + Method readPassword = console.getClass().getDeclaredMethod("readPassword", new Class[0]); + System.out.print(description + ": "); + return (char[]) readPassword.invoke(console, new Object[0]); + } catch (Throwable t) { + t.printStackTrace(); throw new ParameterException("The password option is only available with Java 6."); } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 29f2d1f..e755e7f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -29,6 +29,7 @@ import com.beust.jcommander.args.ArgsI18N2New; import com.beust.jcommander.args.ArgsInherited; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; +import com.beust.jcommander.args.ArgsPassword; import com.beust.jcommander.args.ArgsPrivate; import com.beust.jcommander.args.ArgsRequired; import com.beust.jcommander.args.ArgsSlave; @@ -367,7 +368,11 @@ public class JCommanderTest { } public static void main(String[] args) { - new JCommanderTest().commandsShouldBeShownInOrderOfInsertion(); + ArgsPassword a = new ArgsPassword(); + JCommander jc = new JCommander(a); + jc.parse("-password"); + System.out.println("Password:" + a.password); +// new JCommanderTest().commandsShouldBeShownInOrderOfInsertion(); // CommandMain cm = new CommandMain(); // JCommander jc = new JCommander(cm); // CommandAdd add = new CommandAdd(); -- cgit v1.2.3 From f971bdacd01081543697d34ac7e98c73cc78a036 Mon Sep 17 00:00:00 2001 From: Joern Huxhorn Date: Sun, 5 Sep 2010 12:36:20 +0200 Subject: GPG-Signing is now triggered by a profile. e.g. mvn -P sign-artifacts clean install --- pom.xml | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index cc26d44..135a1f5 100644 --- a/pom.xml +++ b/pom.xml @@ -115,22 +115,6 @@ *.internal - - - - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - - @@ -187,6 +171,30 @@ + + + + sign-artifacts + + + + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + -- cgit v1.2.3 From 69ae0501cf8ff817ca75231568cc12d46a71c9d0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Sep 2010 07:16:55 -0700 Subject: Restored password support for Java5. --- src/main/java/com/beust/jcommander/JCommander.java | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 00405b1..bea5853 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -27,6 +27,7 @@ import com.beust.jcommander.internal.Maps; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -545,15 +546,30 @@ public class JCommander { * on Java 6. */ private char[] readPassword(String description) { + System.out.print(description + ": "); try { Method consoleMethod = System.class.getDeclaredMethod("console", new Class[0]); Object console = consoleMethod.invoke(null, new Object[0]); Method readPassword = console.getClass().getDeclaredMethod("readPassword", new Class[0]); - System.out.print(description + ": "); return (char[]) readPassword.invoke(console, new Object[0]); } catch (Throwable t) { - t.printStackTrace(); - throw new ParameterException("The password option is only available with Java 6."); + return readLine(description); + } + } + + /** + * Read a line from stdin (used when java.io.Console is not available) + */ + private char[] readLine(String description) { + try { + InputStreamReader isr = new InputStreamReader(System.in); + BufferedReader in = new BufferedReader(isr); + String result = in.readLine(); + in.close(); + isr.close(); + return result.toCharArray(); + } catch (IOException e) { + throw new ParameterException(e); } } -- cgit v1.2.3 From 22b8a2f4138976df4800fa6fd09c51de02ba2f98 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Sep 2010 07:17:37 -0700 Subject: Updated CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 05523fa..d50a065 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ 1.7 Added: Command usages are now shown in the order they were added to the JCommander object +Fixed: JCommander now compatible with Java 5 Fixed: Minor bug in the command display (Marc Ende) 1.6 -- cgit v1.2.3 From 0950e02eebdb274238b7dc998092279ce466cda4 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Sep 2010 07:19:14 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cc26d44..b0f6324 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.7-SNAPSHOT + 1.7 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From e126fbd528ba84022284e34e0319e572302927ec Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Sep 2010 07:19:20 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b0f6324..3bb5366 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.7 + 1.8-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 3a32b55a2b130ec22aec8dfe322f9fcbebcaabf7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Sep 2010 07:26:09 -0700 Subject: Doc updates --- CHANGELOG | 1 + doc/index.html | 6 ++---- upload | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d50a065..fa82243 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ 1.7 +2010/09/06 Added: Command usages are now shown in the order they were added to the JCommander object Fixed: JCommander now compatible with Java 5 diff --git a/doc/index.html b/doc/index.html index 067dfae..483b686 100644 --- a/doc/index.html +++ b/doc/index.html @@ -615,7 +615,7 @@ You can download JCommander from the following locations: diff --git a/upload b/upload index 39c862d..d0beaf5 100755 --- a/upload +++ b/upload @@ -1,3 +1,4 @@ -scp doc/index.html target/jcommander-1.6.jar beust.com@beust.com:w/jcommander +scp doc/index.html target/jcommander-1.7.jar beust.com@beust.com:w/jcommander +mvn javadoc:javadoc scp -r target/site/apidocs beust.com@beust.com:w/jcommander -- cgit v1.2.3 From 4872e054c216cb5733ac3bd11369c7b359169bf5 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Sep 2010 07:37:11 -0700 Subject: Changed profile name to 'sign' --- pom.xml | 4 ++-- release | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index cf53185..4fe71a7 100644 --- a/pom.xml +++ b/pom.xml @@ -174,10 +174,10 @@ - sign-artifacts + sign diff --git a/release b/release index e8b20dc..2a0163c 100644 --- a/release +++ b/release @@ -4,5 +4,5 @@ # deploy without tagging: mvn deploy -DperformRelease # mvn release:clean javadoc:javadoc release:prepare release:perform -mvn release:perform +mvn release:perform -P sign -- cgit v1.2.3 From 8a59ec24df3a94036e1fdfdafe9608256158ef74 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 9 Sep 2010 12:50:40 -0700 Subject: Added \n after the option display. --- src/main/java/com/beust/jcommander/JCommander.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index bea5853..5acdc7e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -694,7 +694,7 @@ public class JCommander { if (m_mainParameterAnnotation != null) { out.append(" " + m_mainParameterAnnotation.description() + "\n"); } - out.append(" Options:"); + out.append(" Options:\n"); // // Align the descriptions at the "longestName" column @@ -732,7 +732,8 @@ public class JCommander { + (pd.getParameter().required() ? "* " : " ") + pd.getNames() + s(spaceCount) + pd.getDescription()); Object def = pd.getDefault(); - if (def != null) out.append(" (default: " + def + ")"); out.append("\n"); + if (def != null) out.append(" (default: " + def + ")"); + out.append("\n"); } // -- cgit v1.2.3 From c8cd32114ca3752b07dfd3426ab943e7e6769b39 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 29 Sep 2010 13:37:17 -0700 Subject: Fixed capitalization problem caused by the highlighting. --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 483b686..3246ba3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -621,8 +621,8 @@ You can download JCommander from the following locations:
           
           
          -  com.beust
          -  jcommander
          +  <groupId>com.beust</groupId>
          +  <artifactId>jcommander</artifactId>
             1.7
           
             
          -- cgit v1.2.3 From a6e4abdbab416a28753abf76af5511bcd35753e9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 1 Oct 2010 11:42:59 -0700 Subject: Fixed: JCommander would sometimes just print a stack trace and continue, now rethrowing. --- CHANGELOG | 4 ++++ src/main/java/com/beust/jcommander/JCommander.java | 8 +++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fa82243..9053985 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +Current + +Fixed: JCommander would sometimes just print a stack trace and continue, now rethrowing. + 1.7 2010/09/06 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 5acdc7e..615b638 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -835,14 +835,12 @@ public class JCommander { String optionName = names.length > 0 ? names[0] : "[Main class]"; converter = instantiateConverter(optionName, converterClass); result = converter.convert(value); - } catch (IllegalArgumentException e) { - e.printStackTrace(); } catch (InstantiationException e) { - e.printStackTrace(); + throw new ParameterException(e); } catch (IllegalAccessException e) { - e.printStackTrace(); + throw new ParameterException(e); } catch (InvocationTargetException e) { - e.printStackTrace(); + throw new ParameterException(e); } return result; -- cgit v1.2.3 From 7d1d1f5ca71319676651a65696d4531793163b1b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 12:26:27 -0700 Subject: Updated to TestNG 5.14.1. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4fe71a7..ec874fa 100644 --- a/pom.xml +++ b/pom.xml @@ -127,7 +127,7 @@ 5.11 jdk15 --> - 5.12.1 + 5.14.1 test -- cgit v1.2.3 From d6b7acf32a7ae9cbc5d3195fb053fa4288cea671 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 12:29:31 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec874fa..6d133c0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.8-SNAPSHOT + 1.8 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 91ffd722e90e405f5a4f27fab3572da2c32ac76b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 12:29:37 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6d133c0..9fba253 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.8 + 1.9-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From ffba6dc741950e970ce37e44463fd6b44863ea83 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 12:53:08 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9fba253..87c5100 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.9-SNAPSHOT + 1.9 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From f66bb6200ce2b60ce38043afc71828310ab81e42 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 12:53:14 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 87c5100..cc08cba 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.9 + 1.10-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 7dc776f48d66301c2652b3a16dbbdeed78b5b572 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 13:23:52 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cc08cba..16ef784 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.10-SNAPSHOT + 1.10 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 4eebd47ca8887703c9b291adee415cbb8734aac7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 4 Oct 2010 13:23:58 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 16ef784..dfe6796 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.10 + 1.11-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From e5799d36df3ceddb4b71b5f786e343c1c1e0d027 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 11 Oct 2010 11:17:20 -0700 Subject: Fixed ArrayIndexOutOfBoundsException. --- src/main/java/com/beust/jcommander/JCommander.java | 20 ++++---- .../java/com/beust/jcommander/JCommanderTest.java | 56 ++++++++++++++++++---- .../java/com/beust/jcommander/args/Arity1.java | 9 ++++ 3 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/args/Arity1.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 615b638..0175a78 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -480,16 +480,20 @@ public class JCommander { int arity = pd.getParameter().arity(); int n = (arity != -1 ? arity : 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()); + 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(n + " parameters expected after " + arg); } - i += n + offset; } else { - throw new ParameterException(n + " parameters expected after " + arg); + throw new ParameterException("Expected a value after parameter " + arg); } } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index e755e7f..56cc638 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -18,6 +18,10 @@ package com.beust.jcommander; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + import com.beust.jcommander.args.Args1; import com.beust.jcommander.args.Args2; import com.beust.jcommander.args.ArgsArityString; @@ -34,6 +38,7 @@ import com.beust.jcommander.args.ArgsPrivate; import com.beust.jcommander.args.ArgsRequired; import com.beust.jcommander.args.ArgsSlave; import com.beust.jcommander.args.ArgsSlaveBogus; +import com.beust.jcommander.args.Arity1; import com.beust.jcommander.args.SeparatorColon; import com.beust.jcommander.args.SeparatorEqual; import com.beust.jcommander.args.SeparatorMixed; @@ -42,10 +47,6 @@ import com.beust.jcommander.command.CommandAdd; import com.beust.jcommander.command.CommandCommit; import com.beust.jcommander.command.CommandMain; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - import java.util.Arrays; import java.util.Iterator; import java.util.Locale; @@ -186,7 +187,7 @@ public class JCommanderTest { } @Test(expectedExceptions = ParameterException.class) - public void arity1Fail() { + public void arity2Fail() { ArgsArityString args = new ArgsArityString(); String[] argv = { "-pairs", "pair0" }; new JCommander(args, argv); @@ -367,11 +368,48 @@ public class JCommanderTest { }; } + @Test(expectedExceptions = ParameterException.class) + public void arity1Fail() { + final Arity1 arguments = new Arity1(); + final JCommander jCommander = new JCommander(arguments); + final String[] commands = { + "-inspect" + }; + jCommander.parse(commands); + System.out.println("Inspect:" + arguments.inspect); + Assert.assertTrue(arguments.inspect); + } + + @Test(expectedExceptions = ParameterException.class) + public void arity1Success1() { + final Arity1 arguments = new Arity1(); + final JCommander jCommander = new JCommander(arguments); + final String[] commands = { + "-inspect", "true" + }; + jCommander.parse(commands); + System.out.println("Inspect:" + arguments.inspect); + Assert.assertTrue(arguments.inspect); + } + + @Test(expectedExceptions = ParameterException.class) + public void arity1Success2() { + final Arity1 arguments = new Arity1(); + final JCommander jCommander = new JCommander(arguments); + final String[] commands = { + "-inspect", "false" + }; + jCommander.parse(commands); + System.out.println("Inspect:" + arguments.inspect); + Assert.assertFalse(arguments.inspect); + } + public static void main(String[] args) { - ArgsPassword a = new ArgsPassword(); - JCommander jc = new JCommander(a); - jc.parse("-password"); - System.out.println("Password:" + a.password); +// new JCommanderTest().arity1(); +// ArgsPassword a = new ArgsPassword(); +// JCommander jc = new JCommander(a); +// jc.parse("-password"); +// System.out.println("Password:" + a.password); // new JCommanderTest().commandsShouldBeShownInOrderOfInsertion(); // CommandMain cm = new CommandMain(); // JCommander jc = new JCommander(cm); diff --git a/src/test/java/com/beust/jcommander/args/Arity1.java b/src/test/java/com/beust/jcommander/args/Arity1.java new file mode 100644 index 0000000..8cbf086 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/Arity1.java @@ -0,0 +1,9 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class Arity1 +{ + @Parameter(arity = 1, names = "-inspect", description = "", required = false) + public boolean inspect; +} -- cgit v1.2.3 From 1c5e7d362685371709595fe3d2e65ceadbdfcffc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 11 Oct 2010 11:27:30 -0700 Subject: Disable new tests because TestNG depends on the older version of JCommander. --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/JCommanderTest.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 0175a78..9f9bcc9 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -490,7 +490,7 @@ public class JCommander { } i += n + offset; } else { - throw new ParameterException(n + " parameters expected after " + arg); + throw new ParameterException("Expected " + n + " values after " + arg); } } else { throw new ParameterException("Expected a value after parameter " + arg); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 56cc638..91851e3 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -368,7 +368,7 @@ public class JCommanderTest { }; } - @Test(expectedExceptions = ParameterException.class) +// @Test(expectedExceptions = ParameterException.class) public void arity1Fail() { final Arity1 arguments = new Arity1(); final JCommander jCommander = new JCommander(arguments); @@ -380,7 +380,7 @@ public class JCommanderTest { Assert.assertTrue(arguments.inspect); } - @Test(expectedExceptions = ParameterException.class) +// @Test(expectedExceptions = ParameterException.class) public void arity1Success1() { final Arity1 arguments = new Arity1(); final JCommander jCommander = new JCommander(arguments); @@ -392,7 +392,7 @@ public class JCommanderTest { Assert.assertTrue(arguments.inspect); } - @Test(expectedExceptions = ParameterException.class) +// @Test(expectedExceptions = ParameterException.class) public void arity1Success2() { final Arity1 arguments = new Arity1(); final JCommander jCommander = new JCommander(arguments); @@ -405,7 +405,7 @@ public class JCommanderTest { } public static void main(String[] args) { -// new JCommanderTest().arity1(); + new JCommanderTest().arity1Success2(); // ArgsPassword a = new ArgsPassword(); // JCommander jc = new JCommander(a); // jc.parse("-password"); -- cgit v1.2.3 From 45085a061b7e1bcb5cb6af2f10361951b26530e2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 11 Oct 2010 11:27:48 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.11 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dfe6796..7f213eb 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.11-SNAPSHOT + 1.11 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 234f2c7d5781a5e8b865c60b1362bf704cf90e46 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 11 Oct 2010 11:27:53 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7f213eb..1fa0228 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.11 + 1.12-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 5588fc8aa5d72cbac975e1f9addacd03faf15185 Mon Sep 17 00:00:00 2001 From: Xavier Fournet Date: Sun, 31 Oct 2010 21:19:41 +0100 Subject: Add OSGi headers in MANIFEST.MF --- pom.xml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pom.xml b/pom.xml index dfe6796..50a3568 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,34 @@
          + + + org.apache.felix + maven-bundle-plugin + 2.1.0 + + + bundle-manifest + process-classes + + manifest + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + + org.apache.felix + maven-bundle-plugin + 2.1.0 + + + bundle-manifest + process-classes + + manifest + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + - 5.14.1 - test - + + org.testng + testng + 5.14.2 + jar + test + -- cgit v1.2.3 From a0f0aae9343685b767d6b7e11b399276f90f47e7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Nov 2010 15:58:40 -0800 Subject: Better formatting of usage(). --- src/main/java/com/beust/jcommander/JCommander.java | 28 +++++++++++++++++++++- src/test/java/com/beust/jcommander/args/Args3.java | 6 ++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index fe4c60a..17bf452 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -743,9 +743,11 @@ public class JCommander { for (ParameterDescription pd : sorted) { int l = pd.getNames().length(); int spaceCount = longestName - l; + int start = out.length(); out.append(" " + (pd.getParameter().required() ? "* " : " ") - + pd.getNames() + s(spaceCount) + pd.getDescription()); + + pd.getNames() + s(spaceCount)); + wrapDescription(out, out.length() - start, pd.getDescription()); Object def = pd.getDefault(); if (def != null) out.append(" (default: " + def + ")"); out.append("\n"); @@ -767,6 +769,30 @@ public class JCommander { } } + private void wrapDescription(StringBuilder out, int indent, String description) { + int max = 79; + String[] words = description.split(" "); + int current = indent; + int i = 0; + while (i < words.length) { + String word = words[i]; + if (word.length() > max || current + word.length() <= max) { + out.append(word).append(" "); + current += word.length() + 1; + i++; + } else { + out.append("\n").append(spaces(indent)); + current = indent; + } + } + } + + private String spaces(int indent) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) sb.append(" "); + return sb.toString(); + } + /** * @return a Collection of all the @Parameter annotations found on the * target class. This can be used to display the usage() in a different diff --git a/src/test/java/com/beust/jcommander/args/Args3.java b/src/test/java/com/beust/jcommander/args/Args3.java index a1a4011..5fbaac0 100644 --- a/src/test/java/com/beust/jcommander/args/Args3.java +++ b/src/test/java/com/beust/jcommander/args/Args3.java @@ -4,7 +4,11 @@ import com.beust.jcommander.Parameter; public class Args3 { - @Parameter(names = "--classpath", description = "The classpath") + @Parameter(names = "--classpath", description = "The classpath. This is a very long " + + "description in order to test the line wrapping. Let's see how this works." + + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor" + + " incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " + + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.") public String classpath; @Parameter(names = { "-c", "--convention" }, description = "The convention") -- cgit v1.2.3 From 1860b2add066a6e87b16ee80a57fe8099983e2b9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 27 Nov 2010 16:00:39 -0800 Subject: Minor fix. --- src/main/java/com/beust/jcommander/JCommander.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 17bf452..6677e54 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -757,7 +757,7 @@ public class JCommander { // If commands were specified, show them as well // if (hasCommands) { - out.append(" Commands:\n"); + out.append("\n Commands:\n"); // The magic value 3 is the number of spaces between the name of the option // and its description int ln = longestName(m_commands.keySet()) + 3; @@ -777,7 +777,7 @@ public class JCommander { while (i < words.length) { String word = words[i]; if (word.length() > max || current + word.length() <= max) { - out.append(word).append(" "); + out.append(" ").append(word); current += word.length() + 1; i++; } else { -- cgit v1.2.3 From 28fde86d17ba423d09157646eff2339ff462c677 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 28 Nov 2010 10:10:42 -0800 Subject: Better usage formatting. --- src/main/java/com/beust/jcommander/JCommander.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 6677e54..5b38fb3 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -747,9 +747,10 @@ public class JCommander { out.append(" " + (pd.getParameter().required() ? "* " : " ") + pd.getNames() + s(spaceCount)); - wrapDescription(out, out.length() - start, pd.getDescription()); + int indent = out.length() - start; + wrapDescription(out, indent, pd.getDescription()); Object def = pd.getDefault(); - if (def != null) out.append(" (default: " + def + ")"); + if (def != null) out.append("\n" + spaces(indent + 1)).append("Default: " + def); out.append("\n"); } @@ -757,7 +758,7 @@ public class JCommander { // If commands were specified, show them as well // if (hasCommands) { - out.append("\n Commands:\n"); + out.append(" Commands:\n"); // The magic value 3 is the number of spaces between the name of the option // and its description int ln = longestName(m_commands.keySet()) + 3; -- cgit v1.2.3 From 9c170b3038460fde4999afc7af7bb5d31e3f1e47 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 28 Nov 2010 12:00:17 -0800 Subject: Alphabetical usage. --- src/main/java/com/beust/jcommander/JCommander.java | 4 ++-- .../com/beust/jcommander/ParameterDescription.java | 14 ++++++++++-- .../java/com/beust/jcommander/JCommanderTest.java | 4 ++-- src/test/java/com/beust/jcommander/args/Args3.java | 25 ---------------------- .../beust/jcommander/args/ArgsLongDescription.java | 25 ++++++++++++++++++++++ 5 files changed, 41 insertions(+), 31 deletions(-) delete mode 100644 src/test/java/com/beust/jcommander/args/Args3.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsLongDescription.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 5b38fb3..e3322ea 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -732,8 +732,8 @@ public class JCommander { // Collections.sort(sorted, new Comparator() { @Override - public int compare(ParameterDescription arg0, ParameterDescription arg1) { - return cleanUpNames(arg0.getNames()).compareTo(cleanUpNames(arg1.getNames())); + public int compare(ParameterDescription p0, ParameterDescription p1) { + return p0.getLongestName().compareTo(p1.getLongestName()); } }); diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 169f20c..58ed485 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -38,6 +38,8 @@ public class ParameterDescription { private String m_description; private JCommander m_jCommander; private Object m_default; + /** Longest of the names(), used to present usage() alphabetically */ + private String m_longestName = ""; public ParameterDescription(Object object, Parameter annotation, Field field, ResourceBundle bundle, JCommander jc) { @@ -91,11 +93,19 @@ public class ParameterDescription { } } + for (String name : annotation.names()) { + if (name.length() > m_longestName.length()) m_longestName = name; + } + try { m_default = m_field.get(m_object); } catch (Exception e) { - } - } + } + } + + public String getLongestName() { + return m_longestName; + } public Object getDefault() { return m_default; diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index b4fa641..36b1a9d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -20,7 +20,7 @@ package com.beust.jcommander; import com.beust.jcommander.args.Args1; import com.beust.jcommander.args.Args2; -import com.beust.jcommander.args.Args3; +import com.beust.jcommander.args.ArgsLongDescription; import com.beust.jcommander.args.ArgsArityString; import com.beust.jcommander.args.ArgsBooleanArity; import com.beust.jcommander.args.ArgsBooleanArity0; @@ -426,7 +426,7 @@ public class JCommanderTest { public static void main(String[] args) { // new JCommanderTest().booleanArity0(); // new JCommanderTest().booleanArity1(); - Args3 a = new Args3(); + ArgsLongDescription a = new ArgsLongDescription(); JCommander jc = new JCommander(a); jc.usage(); // ArgsPassword a = new ArgsPassword(); diff --git a/src/test/java/com/beust/jcommander/args/Args3.java b/src/test/java/com/beust/jcommander/args/Args3.java deleted file mode 100644 index 5fbaac0..0000000 --- a/src/test/java/com/beust/jcommander/args/Args3.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.beust.jcommander.args; - -import com.beust.jcommander.Parameter; - -public class Args3 { - - @Parameter(names = "--classpath", description = "The classpath. This is a very long " - + "description in order to test the line wrapping. Let's see how this works." - + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor" - + " incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " - + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.") - public String classpath; - - @Parameter(names = { "-c", "--convention" }, description = "The convention") - public String convention; - - @Parameter(names = { "-d", "--destination" }, description = "The destination to go to") - public String destination; - - @Parameter(names = "--configure", description = "How to configure") - public String configure; - - @Parameter(names = "--filespec") - public String filespec; -} diff --git a/src/test/java/com/beust/jcommander/args/ArgsLongDescription.java b/src/test/java/com/beust/jcommander/args/ArgsLongDescription.java new file mode 100644 index 0000000..e961016 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsLongDescription.java @@ -0,0 +1,25 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +public class ArgsLongDescription { + + @Parameter(names = "--classpath", description = "The classpath. This is a very long " + + "description in order to test the line wrapping. Let's see how this works." + + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor" + + " incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " + + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.") + public String classpath = "/tmp"; + + @Parameter(names = { "-c", "--convention" }, description = "The convention", required = true) + public String convention = "Java"; + + @Parameter(names = { "-d", "--destination" }, description = "The destination to go to") + public String destination; + + @Parameter(names = "--configure", description = "How to configure") + public String configure; + + @Parameter(names = "--filespec") + public String filespec; +} -- cgit v1.2.3 From c1d51baff4fb68b90b2f9cdfea512c84ab94eb42 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 09:49:08 -0800 Subject: Removed @Override to guarantee JDK 1.5 compilation. --- src/main/java/com/beust/jcommander/JCommander.java | 4 +--- .../com/beust/jcommander/converters/BooleanConverter.java | 1 - .../beust/jcommander/converters/CommaSeparatedConverter.java | 1 - .../java/com/beust/jcommander/converters/FileConverter.java | 1 - .../com/beust/jcommander/converters/IntegerConverter.java | 1 - .../java/com/beust/jcommander/converters/LongConverter.java | 1 - .../java/com/beust/jcommander/converters/NoConverter.java | 1 - .../java/com/beust/jcommander/converters/StringConverter.java | 1 - .../defaultprovider/PropertyFileDefaultProvider.java | 1 - src/test/java/com/beust/jcommander/ConverterFactoryTest.java | 1 - src/test/java/com/beust/jcommander/DefaultProviderTest.java | 1 - src/test/java/com/beust/jcommander/HostPortConverter.java | 1 - src/test/java/com/beust/jcommander/JCommanderTest.java | 11 ++++++----- .../java/com/beust/jcommander/args/ArgsMainParameter1.java | 1 - .../java/com/beust/jcommander/args/ArgsMainParameter2.java | 1 - 15 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index e3322ea..43198dc 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -486,8 +486,7 @@ public class JCommander { || boolean.class.isAssignableFrom(fieldType))) { pd.addValue("true"); m_requiredFields.remove(pd.getField()); - } - else if (i < args.length - 1) { + } else if (i < args.length - 1) { int offset = "--".equals(args[i + 1]) ? 1 : 0; if (i + n < args.length) { @@ -731,7 +730,6 @@ public class JCommander { // Sort the options // Collections.sort(sorted, new Comparator() { - @Override public int compare(ParameterDescription p0, ParameterDescription p1) { return p0.getLongestName().compareTo(p1.getLongestName()); } diff --git a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java index 35188ca..5126d22 100644 --- a/src/main/java/com/beust/jcommander/converters/BooleanConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BooleanConverter.java @@ -31,7 +31,6 @@ public class BooleanConverter extends BaseConverter { super(optionName); } - @Override public Boolean convert(String value) { if ("false".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value)) { return Boolean.parseBoolean(value); diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java index 033138a..b719bd4 100644 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java @@ -30,7 +30,6 @@ import java.util.List; */ public class CommaSeparatedConverter implements IStringConverter> { - @Override public List convert(String value) { return Arrays.asList(value.split(",")); } diff --git a/src/main/java/com/beust/jcommander/converters/FileConverter.java b/src/main/java/com/beust/jcommander/converters/FileConverter.java index ea4d9ba..c18b575 100644 --- a/src/main/java/com/beust/jcommander/converters/FileConverter.java +++ b/src/main/java/com/beust/jcommander/converters/FileConverter.java @@ -29,7 +29,6 @@ import java.io.File; */ public class FileConverter implements IStringConverter { - @Override public File convert(String value) { return new File(value); } diff --git a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java index be38126..53d1119 100644 --- a/src/main/java/com/beust/jcommander/converters/IntegerConverter.java +++ b/src/main/java/com/beust/jcommander/converters/IntegerConverter.java @@ -31,7 +31,6 @@ public class IntegerConverter extends BaseConverter { super(optionName); } - @Override public Integer convert(String value) { try { return Integer.parseInt(value); diff --git a/src/main/java/com/beust/jcommander/converters/LongConverter.java b/src/main/java/com/beust/jcommander/converters/LongConverter.java index bbfa0cf..863956b 100644 --- a/src/main/java/com/beust/jcommander/converters/LongConverter.java +++ b/src/main/java/com/beust/jcommander/converters/LongConverter.java @@ -31,7 +31,6 @@ public class LongConverter extends BaseConverter { super(optionName); } - @Override public Long convert(String value) { try { return Long.parseLong(value); diff --git a/src/main/java/com/beust/jcommander/converters/NoConverter.java b/src/main/java/com/beust/jcommander/converters/NoConverter.java index c670258..618daf9 100644 --- a/src/main/java/com/beust/jcommander/converters/NoConverter.java +++ b/src/main/java/com/beust/jcommander/converters/NoConverter.java @@ -27,7 +27,6 @@ import com.beust.jcommander.IStringConverter; */ public class NoConverter implements IStringConverter { - @Override public String convert(String value) { throw new UnsupportedOperationException(); } diff --git a/src/main/java/com/beust/jcommander/converters/StringConverter.java b/src/main/java/com/beust/jcommander/converters/StringConverter.java index 1dce8b8..ea1ae38 100644 --- a/src/main/java/com/beust/jcommander/converters/StringConverter.java +++ b/src/main/java/com/beust/jcommander/converters/StringConverter.java @@ -27,7 +27,6 @@ import com.beust.jcommander.IStringConverter; */ public class StringConverter implements IStringConverter { - @Override public String convert(String value) { return value; } diff --git a/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java b/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java index 47eeedb..d5401a1 100644 --- a/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java +++ b/src/main/java/com/beust/jcommander/defaultprovider/PropertyFileDefaultProvider.java @@ -58,7 +58,6 @@ public class PropertyFileDefaultProvider implements IDefaultProvider { } } - @Override public String getDefaultValueFor(String optionName) { int index = 0; while (index < optionName.length() && ! Character.isLetterOrDigit(optionName.charAt(index))) { diff --git a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java index a93f27c..e02166e 100644 --- a/src/test/java/com/beust/jcommander/ConverterFactoryTest.java +++ b/src/test/java/com/beust/jcommander/ConverterFactoryTest.java @@ -41,7 +41,6 @@ public class ConverterFactoryTest { private static final IStringConverterFactory CONVERTER_FACTORY = new IStringConverterFactory() { - @Override public Class> getConverter(Class forType) { return MAP.get(forType); } diff --git a/src/test/java/com/beust/jcommander/DefaultProviderTest.java b/src/test/java/com/beust/jcommander/DefaultProviderTest.java index 171d116..45ab6b6 100644 --- a/src/test/java/com/beust/jcommander/DefaultProviderTest.java +++ b/src/test/java/com/beust/jcommander/DefaultProviderTest.java @@ -27,7 +27,6 @@ import org.testng.annotations.Test; public class DefaultProviderTest { private static final IDefaultProvider DEFAULT_PROVIDER = new IDefaultProvider() { - @Override public String getDefaultValueFor(String optionName) { return "-debug".equals(optionName) ? "false" : "42"; } diff --git a/src/test/java/com/beust/jcommander/HostPortConverter.java b/src/test/java/com/beust/jcommander/HostPortConverter.java index 5f55474..5409d21 100644 --- a/src/test/java/com/beust/jcommander/HostPortConverter.java +++ b/src/test/java/com/beust/jcommander/HostPortConverter.java @@ -20,7 +20,6 @@ package com.beust.jcommander; public class HostPortConverter implements IStringConverter { - @Override public HostPort convert(String value) { HostPort result = new HostPort(); String[] s = value.split(":"); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 36b1a9d..f0573db 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -237,7 +237,8 @@ public class JCommanderTest { argsBoolean1(new String[] { "-debug", "true" }, Boolean.TRUE); } - @Test + @Test(enabled = false, + description = "Disabled because of JCommander -> TestNG -> JCommander dependency") public void booleanArity0() { argsBoolean0(new String[] {}, Boolean.FALSE); argsBoolean0(new String[] { "-debug"}, Boolean.TRUE); @@ -424,11 +425,11 @@ public class JCommanderTest { } public static void main(String[] args) { -// new JCommanderTest().booleanArity0(); + new JCommanderTest().booleanArity0(); // new JCommanderTest().booleanArity1(); - ArgsLongDescription a = new ArgsLongDescription(); - JCommander jc = new JCommander(a); - jc.usage(); +// ArgsLongDescription a = new ArgsLongDescription(); +// JCommander jc = new JCommander(a); +// jc.usage(); // ArgsPassword a = new ArgsPassword(); // JCommander jc = new JCommander(a); // jc.parse("-password"); diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java index b223fd9..cd5c52d 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter1.java @@ -34,7 +34,6 @@ public class ArgsMainParameter1 implements IHostPorts { @Parameter public List parameters = Lists.newArrayList(); - @Override public List getHostPorts() { return parameters; } diff --git a/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java b/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java index 739c13e..57422e3 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java +++ b/src/test/java/com/beust/jcommander/args/ArgsMainParameter2.java @@ -35,7 +35,6 @@ public class ArgsMainParameter2 implements IHostPorts { @Parameter(converter = HostPortConverter.class) public List parameters = Lists.newArrayList(); - @Override public List getHostPorts() { return parameters; } -- cgit v1.2.3 From 1e9898cd44c70572833b1b0710b50de9c68c53e9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 09:49:32 -0800 Subject: Make sure JCommander tests against the current version of itself. --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 44abd7f..94e6b5d 100644 --- a/pom.xml +++ b/pom.xml @@ -159,18 +159,18 @@ - -- cgit v1.2.3 From 5c4ce3389afb95f3cc879b096328a6e4f517d6cf Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 09:50:09 -0800 Subject: Script update. --- build-with-maven | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index fa8a935..063a495 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,2 +1,7 @@ -mvn source:jar javadoc:jar repository:bundle-create -P sign +mvn clean source:jar javadoc:jar repository:bundle-create -P sign + +echo "To deploy to the snapshot repository: mvn deploy" +echo "To deploy to the release directory: mvn release:clean release:prepare release:perform" +echo "Nexus UI: https://oss.sonatype.org/index.html" +echo "Wiki: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide" -- cgit v1.2.3 From 6023b80bf53c6b058641c222181d3c56621166ba Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 09:53:20 -0800 Subject: Bump. --- pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 94e6b5d..4f19805 100644 --- a/pom.xml +++ b/pom.xml @@ -159,6 +159,7 @@ + + org.apache.maven.plugins -- cgit v1.2.3 From a6491f05ea6cbe741bca01d6312bf3fda318f981 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 09:53:36 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4f19805..272cc08 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.12-SNAPSHOT + 1.12 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From edca1893b65becc5252e03a445d690ceb6b57cde Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 09:53:41 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 272cc08..c46f6d0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.12 + 1.13-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 460998fec3b06bf45b024c645b5b5e854de68c24 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 16:23:18 -0800 Subject: Added class level @Test. --- .../java/com/beust/jcommander/JCommanderTest.java | 42 +++------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index f0573db..d661ccd 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -54,8 +54,8 @@ import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; +@Test public class JCommanderTest { - @Test public void simpleArgs() { Args1 args = new Args1(); String[] argv = { "-debug", "-log", "2", "-groups", "unit", "a", "b", "c" }; @@ -71,7 +71,6 @@ public class JCommanderTest { * Make sure that if there are args with multiple names (e.g. "-log" and "-verbose"), * the usage will only display it once. */ - @Test public void repeatedArgs() { Args1 args = new Args1(); String[] argv = { "-log", "2" }; @@ -99,12 +98,10 @@ public class JCommanderTest { Assert.assertEquals(args.verbose.intValue(), 2); } - @Test public void multipleNames1() { multipleNames("-log"); } - @Test public void multipleNames2() { multipleNames("-verbose"); } @@ -122,17 +119,14 @@ public class JCommanderTest { Assert.assertEquals(pd.getDescription(), expectedString); } - @Test public void i18nNoLocale() { i18n1("MessageBundle", null, "Host"); } - @Test public void i18nUsLocale() { i18n1("MessageBundle", new Locale("en", "US"), "Host"); } - @Test public void i18nFrLocale() { i18n1("MessageBundle", new Locale("fr", "FR"), "Hôte"); } @@ -145,17 +139,14 @@ public class JCommanderTest { Assert.assertEquals(pd.getDescription(), "Hôte"); } - @Test public void i18nWithResourceAnnotation() { i18n2(new ArgsI18N2()); } - @Test public void i18nWithResourceAnnotationNew() { i18n2(new ArgsI18N2New()); } - @Test public void multiObjects() { ArgsMaster m = new ArgsMaster(); ArgsSlave s = new ArgsSlave(); @@ -174,7 +165,6 @@ public class JCommanderTest { new JCommander(new Object[] { m , s }, argv); } - @Test public void arityString() { ArgsArityString args = new ArgsArityString(); String[] argv = { "-pairs", "pair0", "pair1", "rest" }; @@ -201,14 +191,12 @@ public class JCommanderTest { new JCommander(args, argv); } - @Test public void privateArgs() { ArgsPrivate args = new ArgsPrivate(); new JCommander(args, "-verbose", "3"); Assert.assertEquals(args.getVerbose().intValue(), 3); } - @Test public void converterArgs() { ArgsConverter args = new ArgsConverter(); String fileName = "a"; @@ -231,14 +219,11 @@ public class JCommanderTest { Assert.assertEquals(args.debug, expected); } - @Test public void booleanArity1() { argsBoolean1(new String[] {}, Boolean.FALSE); argsBoolean1(new String[] { "-debug", "true" }, Boolean.TRUE); } - @Test(enabled = false, - description = "Disabled because of JCommander -> TestNG -> JCommander dependency") public void booleanArity0() { argsBoolean0(new String[] {}, Boolean.FALSE); argsBoolean0(new String[] { "-debug"}, Boolean.TRUE); @@ -251,7 +236,6 @@ public class JCommanderTest { new JCommander(args, argv); } - @Test(expectedExceptions = ParameterException.class) public void badParameterShouldThrowParameter2Exception() { Args1 args = new Args1(); @@ -259,7 +243,6 @@ public class JCommanderTest { new JCommander(args, argv); } - @Test public void listParameters() { Args2 a = new Args2(); String[] argv = {"-log", "2", "-groups", "unit", "a", "b", "c", "-host", "host2"}; @@ -270,7 +253,6 @@ public class JCommanderTest { Assert.assertEquals(a.parameters, Arrays.asList("a", "b", "c")); } - @Test public void separatorEqual() { SeparatorEqual s = new SeparatorEqual(); String[] argv = { "-log=3", "--longoption=10" }; @@ -279,7 +261,6 @@ public class JCommanderTest { Assert.assertEquals(s.longOption.intValue(), 10); } - @Test public void separatorColon() { SeparatorColon s = new SeparatorColon(); String[] argv = { "-verbose:true" }; @@ -287,7 +268,6 @@ public class JCommanderTest { Assert.assertTrue(s.verbose); } - @Test public void separatorBoth() { SeparatorColon s = new SeparatorColon(); SeparatorEqual s2 = new SeparatorEqual(); @@ -297,7 +277,6 @@ public class JCommanderTest { Assert.assertEquals(s2.log.intValue(), 3); } - @Test public void separatorMixed1() { SeparatorMixed s = new SeparatorMixed(); String[] argv = { "-long:1", "-level=42" }; @@ -306,7 +285,6 @@ public class JCommanderTest { Assert.assertEquals(s.level.intValue(), 42); } - @Test public void slashParameters() { SlashSeparator a = new SlashSeparator(); String[] argv = { "/verbose", "/file", "/tmp/a" }; @@ -315,7 +293,6 @@ public class JCommanderTest { Assert.assertEquals(a.file, "/tmp/a"); } - @Test public void inheritance() { ArgsInherited args = new ArgsInherited(); String[] argv = { "-log", "3", "-child", "2" }; @@ -324,7 +301,6 @@ public class JCommanderTest { Assert.assertEquals(args.log.intValue(), 3); } - @Test public void negativeNumber() { Args1 a = new Args1(); String[] argv = { "-verbose", "-3" }; @@ -339,7 +315,6 @@ public class JCommanderTest { new JCommander(a, argv); } - @Test public void usageShouldNotChange() { JCommander jc = new JCommander(new Args1(), new String[]{"-log", "1"}); StringBuilder sb = new StringBuilder(); @@ -369,7 +344,6 @@ public class JCommanderTest { } } - @Test public void commandsShouldBeShownInOrderOfInsertion() { verifyCommandOrdering(new String[] { "add", "commit" }, new Object[] { new CommandAdd(), new CommandCommit() }); @@ -388,7 +362,7 @@ public class JCommanderTest { }; } -// @Test(expectedExceptions = ParameterException.class) + @Test(expectedExceptions = ParameterException.class) public void arity1Fail() { final Arity1 arguments = new Arity1(); final JCommander jCommander = new JCommander(arguments); @@ -396,11 +370,8 @@ public class JCommanderTest { "-inspect" }; jCommander.parse(commands); - System.out.println("Inspect:" + arguments.inspect); - Assert.assertTrue(arguments.inspect); } -// @Test(expectedExceptions = ParameterException.class) public void arity1Success1() { final Arity1 arguments = new Arity1(); final JCommander jCommander = new JCommander(arguments); @@ -408,11 +379,9 @@ public class JCommanderTest { "-inspect", "true" }; jCommander.parse(commands); - System.out.println("Inspect:" + arguments.inspect); Assert.assertTrue(arguments.inspect); } -// @Test(expectedExceptions = ParameterException.class) public void arity1Success2() { final Arity1 arguments = new Arity1(); final JCommander jCommander = new JCommander(arguments); @@ -420,12 +389,11 @@ public class JCommanderTest { "-inspect", "false" }; jCommander.parse(commands); - System.out.println("Inspect:" + arguments.inspect); Assert.assertFalse(arguments.inspect); } - public static void main(String[] args) { - new JCommanderTest().booleanArity0(); +// public static void main(String[] args) { +// new JCommanderTest().arity1Fail(); // new JCommanderTest().booleanArity1(); // ArgsLongDescription a = new ArgsLongDescription(); // JCommander jc = new JCommander(a); @@ -456,7 +424,7 @@ public class JCommanderTest { // String[] argv = { "-log=10" }; // JCommander jc = new JCommander(a, argv); // Assert.assertEquals(a.log.intValue(), 10); - } +// } // Tests: // required unparsed parameter -- cgit v1.2.3 From 8ce2cef8db6b2a96e4bfa1b607f05e5bcd6b1436 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 16:23:39 -0800 Subject: Depends on TestNG 5.14.4. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c46f6d0..05ef02f 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.5 + 2.7 com.beust @@ -190,7 +190,7 @@ org.testng testng - 5.14.2 + 5.14.4 jar test -- cgit v1.2.3 From 4bdf09bffd90d164f7acf494dd6ef3d97d2cf310 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 16:24:03 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.13 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 05ef02f..5727827 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.13-SNAPSHOT + 1.13 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From eb8435b7df590e5ba3b40e1e0b16dbc720eeb417 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 15 Dec 2010 16:24:09 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5727827..372e14a 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.13 + 1.14-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 32868be31e1c6fd5b55608c05dc3eab3d0295239 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 22 Dec 2010 20:38:37 -0800 Subject: Bumped to TestNG 5.14.6. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44abd7f..43a4c62 100644 --- a/pom.xml +++ b/pom.xml @@ -188,7 +188,7 @@ org.testng testng - 5.14.2 + 5.14.6 jar test -- cgit v1.2.3 From f2cd60c1f0e475201b9d24b486df920ff1d02ac5 Mon Sep 17 00:00:00 2001 From: Russell Egan Date: Thu, 23 Dec 2010 14:37:30 -0500 Subject: parse() should check if createDescriptions was already called When using main parameters, createDescriptions can't be called twice, but it is possible to do so by using combinations of usage() and parse() --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/JCommanderTest.java | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 43198dc..d9e674d 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -183,7 +183,7 @@ public class JCommander { sb.append(join(args).append("\"\n with:").append(join(m_objects.toArray()))); p(sb.toString()); - createDescriptions(); + if (m_descriptions == null) createDescriptions(); initializeDefaultValues(); parseValues(expandArgs(args)); validateOptions(); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index d661ccd..3af64ff 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -29,6 +29,7 @@ import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; import com.beust.jcommander.args.ArgsInherited; +import com.beust.jcommander.args.ArgsMainParameter1; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; import com.beust.jcommander.args.ArgsPrivate; @@ -315,6 +316,15 @@ public class JCommanderTest { new JCommander(a, argv); } + @Test + public void noParseConstructor() { + JCommander jCommander = new JCommander(new ArgsMainParameter1()); + jCommander.usage(); + // Before fix, this parse would throw an exception, because it calls createDescription, which + // was already called by usage(), and can only be called once. + jCommander.parse(); + } + public void usageShouldNotChange() { JCommander jc = new JCommander(new Args1(), new String[]{"-log", "1"}); StringBuilder sb = new StringBuilder(); -- cgit v1.2.3 From dae46a1c4166085b56a78669050dc19938735a41 Mon Sep 17 00:00:00 2001 From: Russell Egan Date: Thu, 23 Dec 2010 14:38:47 -0500 Subject: Added a constructor which takes a resource bundle, but doesn't parse immediately. This is useful when you want to interrogate some options even when required options are missing. --- src/main/java/com/beust/jcommander/JCommander.java | 8 ++++++ .../java/com/beust/jcommander/JCommanderTest.java | 21 +++++++++++++++ .../java/com/beust/jcommander/args/ArgsHelp.java | 30 ++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/test/java/com/beust/jcommander/args/ArgsHelp.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index d9e674d..427332b 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -136,6 +136,14 @@ public class JCommander { init(object, null); } + /** + * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param bundle The bundle to use for the descriptions. Can be null. + */ + public JCommander(Object object, ResourceBundle bundle) { + init(object, bundle); + } + /** * @param object The arg object expected to contain {@link @Parameter} annotations. * @param bundle The bundle to use for the descriptions. Can be null. diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 3af64ff..eba6cfe 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -20,6 +20,7 @@ package com.beust.jcommander; import com.beust.jcommander.args.Args1; import com.beust.jcommander.args.Args2; +import com.beust.jcommander.args.ArgsHelp; import com.beust.jcommander.args.ArgsLongDescription; import com.beust.jcommander.args.ArgsArityString; import com.beust.jcommander.args.ArgsBooleanArity; @@ -148,6 +149,26 @@ public class JCommanderTest { i18n2(new ArgsI18N2New()); } + /** + * Test a use case where there are required parameters, but you still want + * to interrogate the options which are specified. + */ + @Test + public void usageWithRequiredArgsAndResourceBundle() { + System.out.println("In the test"); + ArgsHelp argsHelp = new ArgsHelp(); + JCommander jc = new JCommander(new Object[]{argsHelp, new ArgsRequired()}, java.util.ResourceBundle.getBundle("MessageBundle")); + // Should be able to display usage without triggering validation + jc.usage(); + try { + jc.parse("-h"); + Assert.fail("Should have thrown a required parameter exception"); + } catch (ParameterException e) { + Assert.assertTrue(e.getMessage().contains("are required")); + } + Assert.assertTrue(argsHelp.help); + } + public void multiObjects() { ArgsMaster m = new ArgsMaster(); ArgsSlave s = new ArgsSlave(); diff --git a/src/test/java/com/beust/jcommander/args/ArgsHelp.java b/src/test/java/com/beust/jcommander/args/ArgsHelp.java new file mode 100644 index 0000000..4baaddd --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsHelp.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; + +/** + * Test a help option which overrides other options and option validations + */ +public class ArgsHelp { + + @Parameter(names = "-h", description = "Display help") + public boolean help; +} -- cgit v1.2.3 From 426ec1427d55ef46e33d4d26ff70e844b1bf046c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 23 Dec 2010 12:22:03 -0800 Subject: Version updates. --- doc/index.html | 2 +- pom.xml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/index.html b/doc/index.html index 3246ba3..1813b02 100644 --- a/doc/index.html +++ b/doc/index.html @@ -623,7 +623,7 @@ You can download JCommander from the following locations: <groupId>com.beust</groupId> <artifactId>jcommander</artifactId> - 1.7 + 1.13
        diff --git a/pom.xml b/pom.xml index 372e14a..6e20b65 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,8 @@ com.beust jcommander ${project.version} - + 1.13 + --> @@ -190,7 +191,7 @@ org.testng testng - 5.14.4 + 5.14.6 jar test -- cgit v1.2.3 From 21059374aa90082d8d0b94c758a0041c2c6b06de Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 23 Dec 2010 12:22:20 -0800 Subject: A few changes on top of ansel1's patch. --- .../java/com/beust/jcommander/JCommanderTest.java | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index eba6cfe..5c5ac34 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -149,15 +149,22 @@ public class JCommanderTest { i18n2(new ArgsI18N2New()); } + public void noParseConstructor() { + JCommander jCommander = new JCommander(new ArgsMainParameter1()); + jCommander.usage(); + // Before fix, this parse would throw an exception, because it calls createDescription, which + // was already called by usage(), and can only be called once. + jCommander.parse(); + } + /** * Test a use case where there are required parameters, but you still want * to interrogate the options which are specified. */ - @Test public void usageWithRequiredArgsAndResourceBundle() { - System.out.println("In the test"); ArgsHelp argsHelp = new ArgsHelp(); - JCommander jc = new JCommander(new Object[]{argsHelp, new ArgsRequired()}, java.util.ResourceBundle.getBundle("MessageBundle")); + JCommander jc = new JCommander(new Object[]{argsHelp, new ArgsRequired()}, + java.util.ResourceBundle.getBundle("MessageBundle")); // Should be able to display usage without triggering validation jc.usage(); try { @@ -337,15 +344,6 @@ public class JCommanderTest { new JCommander(a, argv); } - @Test - public void noParseConstructor() { - JCommander jCommander = new JCommander(new ArgsMainParameter1()); - jCommander.usage(); - // Before fix, this parse would throw an exception, because it calls createDescription, which - // was already called by usage(), and can only be called once. - jCommander.parse(); - } - public void usageShouldNotChange() { JCommander jc = new JCommander(new Args1(), new String[]{"-log", "1"}); StringBuilder sb = new StringBuilder(); -- cgit v1.2.3 From fce970edb1612958996a17ce1024325d5075e9d8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 23 Dec 2010 12:25:49 -0800 Subject: CHANGELOG update. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 0bcc4db..c6e0174 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Current Added: Boolean parameters with arity 0 (e.g. "foo -debug") +Added: Added a constructor that takes a Bundle only, https://github.com/cbeust/jcommander/pull/47 (Russell Egan) Fixed: JCommander would sometimes just print a stack trace and continue, now rethrowing. 1.7 -- cgit v1.2.3 From 1f4e89c967e1a43abad1f5f6cffda47ffc23b103 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 23 Dec 2010 12:33:45 -0800 Subject: Log update. --- CHANGELOG | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c6e0174..1e15034 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,11 @@ Current -Added: Boolean parameters with arity 0 (e.g. "foo -debug") Added: Added a constructor that takes a Bundle only, https://github.com/cbeust/jcommander/pull/47 (Russell Egan) + +1.13 +2010/12/15 + +Added: Boolean parameters with arity 0 (e.g. "foo -debug") Fixed: JCommander would sometimes just print a stack trace and continue, now rethrowing. 1.7 -- cgit v1.2.3 From dc01e7c94224b7a9c2b07af35404fb988732a0ad Mon Sep 17 00:00:00 2001 From: Patrick Linskey Date: Sat, 1 Jan 2011 12:53:16 -0800 Subject: no-args constructor for cases where there is no top-level param object. This might happen if all options are destined to be parsed by commands, which are added after instance construction. --- src/main/java/com/beust/jcommander/JCommander.java | 39 +++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 427332b..c6ca64a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -66,7 +66,7 @@ public class JCommander { /** * The objects that contain fields annotated with @Parameter. */ - private List m_objects; + private List m_objects = Lists.newArrayList(); /** * This field will contain whatever command line parameter is not an option. @@ -129,11 +129,17 @@ public class JCommander { CONVERTER_FACTORIES.add(new DefaultConverterFactory()); }; + /** + * Creates a new un-configured JCommander object. + */ + public JCommander() { + } + /** * @param object The arg object expected to contain {@link @Parameter} annotations. */ public JCommander(Object object) { - init(object, null); + addObject(object); } /** @@ -141,7 +147,8 @@ public class JCommander { * @param bundle The bundle to use for the descriptions. Can be null. */ public JCommander(Object object, ResourceBundle bundle) { - init(object, bundle); + addObject(object); + setDescriptionsBundle(bundle); } /** @@ -150,7 +157,8 @@ public class JCommander { * @param args The arguments to parse (optional). */ public JCommander(Object object, ResourceBundle bundle, String... args) { - init(object, bundle); + addObject(object); + setDescriptionsBundle(bundle); parse(args); } @@ -159,13 +167,20 @@ public class JCommander { * @param args The arguments to parse (optional). */ public JCommander(Object object, String... args) { - init(object, null); + addObject(object); parse(args); } - private void init(Object object, ResourceBundle bundle) { - m_bundle = bundle; - m_objects = Lists.newArrayList(); + /** + * Adds the provided arg object to the set of objects that this commander + * will parse arguments into. + * + * @param object The arg object expected to contain {@link Parameter} + * annotations. If object is an array or is {@link Iterable}, + * the child objects will be added instead. + */ + // declared final since this is invoked from constructors + public final void addObject(Object object) { if (object instanceof Iterable) { // Iterable for (Object o : (Iterable) object) { @@ -180,7 +195,15 @@ public class JCommander { // Single object m_objects.add(object); } + } + /** + * Sets the {@link ResourceBundle} to use for looking up descriptions. + * Set this to null to use description text directly. + */ + // declared final since this is invoked from constructors + public final void setDescriptionsBundle(ResourceBundle bundle) { + m_bundle = bundle; } /** -- cgit v1.2.3 From e5012b124d36eda59ffb69ca42dcd89637279716 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 4 Jan 2011 12:41:01 -0800 Subject: Removed extra spaces. --- src/main/java/com/beust/jcommander/JCommander.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index c6ca64a..b03b25a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -130,7 +130,7 @@ public class JCommander { }; /** - * Creates a new un-configured JCommander object. + * Creates a new un-configured JCommander object. */ public JCommander() { } @@ -173,10 +173,10 @@ public class JCommander { /** * Adds the provided arg object to the set of objects that this commander - * will parse arguments into. + * will parse arguments into. * - * @param object The arg object expected to contain {@link Parameter} - * annotations. If object is an array or is {@link Iterable}, + * @param object The arg object expected to contain {@link Parameter} + * annotations. If object is an array or is {@link Iterable}, * the child objects will be added instead. */ // declared final since this is invoked from constructors -- cgit v1.2.3 From b5598e97aa7d22a933223f6211d50329b1a20308 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 4 Jan 2011 13:02:48 -0800 Subject: Added testng.xml and now running the tests directly with TestNG instead of Maven. --- build-with-maven | 4 ++++ pom.xml | 9 ++++++--- src/test/java/com/beust/jcommander/JCommanderTest.java | 7 +++---- src/test/resources/testng.xml | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 src/test/resources/testng.xml diff --git a/build-with-maven b/build-with-maven index 063a495..75677bd 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,5 +1,9 @@ mvn clean source:jar javadoc:jar repository:bundle-create -P sign +export TESTNG=../testng/target/testng-5.14.7beta.jar + +java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml + echo "To deploy to the snapshot repository: mvn deploy" echo "To deploy to the release directory: mvn release:clean release:prepare release:perform" echo "Nexus UI: https://oss.sonatype.org/index.html" diff --git a/pom.xml b/pom.xml index 6e20b65..f13fa35 100644 --- a/pom.xml +++ b/pom.xml @@ -159,21 +159,24 @@ - ---> diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 5c5ac34..31f409e 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -20,12 +20,11 @@ package com.beust.jcommander; import com.beust.jcommander.args.Args1; import com.beust.jcommander.args.Args2; -import com.beust.jcommander.args.ArgsHelp; -import com.beust.jcommander.args.ArgsLongDescription; import com.beust.jcommander.args.ArgsArityString; import com.beust.jcommander.args.ArgsBooleanArity; import com.beust.jcommander.args.ArgsBooleanArity0; import com.beust.jcommander.args.ArgsConverter; +import com.beust.jcommander.args.ArgsHelp; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; @@ -151,7 +150,7 @@ public class JCommanderTest { public void noParseConstructor() { JCommander jCommander = new JCommander(new ArgsMainParameter1()); - jCommander.usage(); + jCommander.usage(new StringBuilder()); // Before fix, this parse would throw an exception, because it calls createDescription, which // was already called by usage(), and can only be called once. jCommander.parse(); @@ -166,7 +165,7 @@ public class JCommanderTest { JCommander jc = new JCommander(new Object[]{argsHelp, new ArgsRequired()}, java.util.ResourceBundle.getBundle("MessageBundle")); // Should be able to display usage without triggering validation - jc.usage(); + jc.usage(new StringBuilder()); try { jc.parse("-h"); Assert.fail("Should have thrown a required parameter exception"); diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml new file mode 100644 index 0000000..3f9f985 --- /dev/null +++ b/src/test/resources/testng.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + -- cgit v1.2.3 From 31c421a62bc1c2e90b4a2c30719d677f73d086fd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 4 Jan 2011 15:59:58 -0800 Subject: Removed Javadoc warnings. --- src/main/java/com/beust/jcommander/JCommander.java | 24 +++++++++------------- .../com/beust/jcommander/ParameterDescription.java | 3 --- .../java/com/beust/jcommander/ResourceBundle.java | 2 +- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index b03b25a..46f3b9b 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -49,9 +49,9 @@ import java.util.ResourceBundle; * values and a few other helper methods, such as usage(). * * The object(s) you pass in the constructor are expected to have one or more - * @Parameter annotations on them. You can pass either a single object, an array of objects + * \@Parameter annotations on them. You can pass either a single object, an array of objects * or an instance of Iterable. In the case of an array or Iterable, JCommander will collect - * the @Parameter annotations from all the objects passed in parameter. + * the \@Parameter annotations from all the objects passed in parameter. * * @author cbeust */ @@ -136,14 +136,14 @@ public class JCommander { } /** - * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param object The arg object expected to contain {@link Parameter} annotations. */ public JCommander(Object object) { addObject(object); } /** - * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param object The arg object expected to contain {@link Parameter} annotations. * @param bundle The bundle to use for the descriptions. Can be null. */ public JCommander(Object object, ResourceBundle bundle) { @@ -152,7 +152,7 @@ public class JCommander { } /** - * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param object The arg object expected to contain {@link Parameter} annotations. * @param bundle The bundle to use for the descriptions. Can be null. * @param args The arguments to parse (optional). */ @@ -163,7 +163,7 @@ public class JCommander { } /** - * @param object The arg object expected to contain {@link @Parameter} annotations. + * @param object The arg object expected to contain {@link Parameter} annotations. * @param args The arguments to parse (optional). */ public JCommander(Object object, String... args) { @@ -407,7 +407,7 @@ public class JCommander { } /** - * Create the ParameterDescriptions for all the @Parameter found. + * Create the ParameterDescriptions for all the \@Parameter found. */ private void createDescriptions() { m_descriptions = Maps.newHashMap(); @@ -718,10 +718,6 @@ public class JCommander { System.out.println(sb.toString()); } - private String cleanUpNames(String names) { - return names.replace("-", "").replace(" ", "").toLowerCase(); - } - /** * Store the help in the passed string builder. */ @@ -824,7 +820,7 @@ public class JCommander { } /** - * @return a Collection of all the @Parameter annotations found on the + * @return a Collection of all the \@Parameter annotations found on the * target class. This can be used to display the usage() in a different * format (e.g. HTML). */ @@ -863,8 +859,8 @@ public class JCommander { } /** - * @param type The class of the field - * @param annotation The annotation + * @param field The field + * @param type The type of the actual parameter * @param value The value to convert */ public Object convertValue(Field field, Class type, String value) { diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 58ed485..a2232f6 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -162,8 +162,6 @@ public class ParameterDescription { /** * Add the specified value to the field. First look up any field converter, then * any type converter, and if we can't find any, throw an exception. - * - * @param markAdded if true, mark this parameter as assigned */ public void addValue(String value, boolean isDefault) { p("Adding " + (isDefault ? "default " : "") + "value:" + value @@ -178,7 +176,6 @@ public class ParameterDescription { if (! isDefault) m_assigned = true; Object convertedValue = m_jCommander.convertValue(this, value); boolean isCollection = Collection.class.isAssignableFrom(type); - boolean isMainParameter = m_parameterAnnotation.names().length == 0; try { if (isCollection) { diff --git a/src/main/java/com/beust/jcommander/ResourceBundle.java b/src/main/java/com/beust/jcommander/ResourceBundle.java index 8309216..279fa6d 100644 --- a/src/main/java/com/beust/jcommander/ResourceBundle.java +++ b/src/main/java/com/beust/jcommander/ResourceBundle.java @@ -24,7 +24,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; /** - * @deprecated, use @Parameters + * @deprecated use @Parameters * * @author cbeust */ -- cgit v1.2.3 From fa693c2855c6b2ba839a5cb49bab01c85a57a1db Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 13 Jan 2011 12:39:50 -0800 Subject: Fixed broken links. --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 1813b02..2f8c45c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -607,7 +607,7 @@ TestNG uses JCommander to parse its command line, here is Javadocs -The Javadocs for JCommander can be found here. +The Javadocs for JCommander can be found here.

        Download

        @@ -615,7 +615,7 @@ You can download JCommander from the following locations:
        • Source on github
        • -
        • Jar file
        • +
        • Jar file
        • Or if you are using Maven, add the following dependency to your pom.xml:
          -- 
          cgit v1.2.3
          
          
          From e2d8da7b584b6a13c23de32ce2df0799a4d3513d Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:01:29 -0800
          Subject: Fixed: NPE with calling getCommandDescription() of an unknown command
          
          ---
           CHANGELOG                                              |  4 ++++
           src/main/java/com/beust/jcommander/JCommander.java     |  4 ++++
           src/test/java/com/beust/jcommander/JCommanderTest.java | 10 ++++++++++
           3 files changed, 18 insertions(+)
          
          diff --git a/CHANGELOG b/CHANGELOG
          index 1e15034..5b872f2 100644
          --- a/CHANGELOG
          +++ b/CHANGELOG
          @@ -1,6 +1,10 @@
           Current
           
          +1.14
          +2011/01/24
          +
           Added: Added a constructor that takes a Bundle only, https://github.com/cbeust/jcommander/pull/47 (Russell Egan)
          +Fixed: NPE with calling getCommandDescription() of an unknown command
           
           1.13
           2010/12/15
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 46f3b9b..f715620 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -702,6 +702,10 @@ public class JCommander {
              */
             public String getCommandDescription(String commandName) {
               JCommander jc = m_commands.get(commandName);
          +    if (jc == null) {
          +      throw new ParameterException("Asking description for unknown command: " + commandName);
          +    }
          +
               Parameters p = jc.getObjects().get(0).getClass().getAnnotation(Parameters.class);
               String result = jc.getMainParameterDescription();
               if (p != null) result = p.commandDescription();
          diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
          index 31f409e..f2dfc68 100644
          --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
          +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
          @@ -89,6 +89,16 @@ public class JCommanderTest {
               new JCommander(args, argv);
             }
           
          +  /**
          +   * Getting the description of a nonexistent command should throw an exception.
          +   */
          +  @Test(expectedExceptions = ParameterException.class)
          +  public void nonexistentCommandShouldThrow() {
          +    String[] argv = { };
          +    JCommander jc = new JCommander(new Object(), argv);
          +    jc.getCommandDescription("foo");
          +  }
          +
             /**
              * Required options with multiple names should work with all names.
              */
          -- 
          cgit v1.2.3
          
          
          From 9eaf795e5d0971aafe0d939b105aeaf3fd5f40d0 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:06:47 -0800
          Subject: Temp.
          
          ---
           build-with-maven | 2 +-
           pom.xml          | 2 +-
           2 files changed, 2 insertions(+), 2 deletions(-)
          
          diff --git a/build-with-maven b/build-with-maven
          index 75677bd..50cfc6f 100755
          --- a/build-with-maven
          +++ b/build-with-maven
          @@ -5,7 +5,7 @@ export TESTNG=../testng/target/testng-5.14.7beta.jar
           java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
           
           echo "To deploy to the snapshot repository: mvn deploy"
          -echo "To deploy to the release directory: mvn release:clean release:prepare release:perform"
          +echo "To deploy to the release directory: mvn -DskipTests=true release:clean release:prepare release:perform"
           echo "Nexus UI:  https://oss.sonatype.org/index.html"
           echo "Wiki: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide"
           
          diff --git a/pom.xml b/pom.xml
          index f13fa35..8a308ec 100644
          --- a/pom.xml
          +++ b/pom.xml
          @@ -24,7 +24,7 @@
             jcommander
             jar
             JCommander
          -  1.14-SNAPSHOT
          +  1.15-SNAPSHOT
             A Java framework to parse command line options with annotations.
             http://beust.com/jcommander
             
          -- 
          cgit v1.2.3
          
          
          From e1a4b8b495fcc200580656796141a0d94c71d675 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:11:11 -0800
          Subject: pom.xml fix.
          
          ---
           pom.xml | 4 ++--
           1 file changed, 2 insertions(+), 2 deletions(-)
          
          diff --git a/pom.xml b/pom.xml
          index 8a308ec..f2069d4 100644
          --- a/pom.xml
          +++ b/pom.xml
          @@ -170,9 +170,9 @@
                     
                       com.beust
                       jcommander
          -            ${project.version}
          -
                      
                   
          -- 
          cgit v1.2.3
          
          
          From 22ae988b983b3d07649946f5a3743a53c0391537 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:11:25 -0800
          Subject: [maven-release-plugin] prepare release jcommander-1.15
          
          ---
           pom.xml | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/pom.xml b/pom.xml
          index f2069d4..9db8daf 100644
          --- a/pom.xml
          +++ b/pom.xml
          @@ -24,7 +24,7 @@
             jcommander
             jar
             JCommander
          -  1.15-SNAPSHOT
          +  1.15
             A Java framework to parse command line options with annotations.
             http://beust.com/jcommander
             
          -- 
          cgit v1.2.3
          
          
          From fe52e522a581cba78ffcb129792dcfa51023b76f Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:11:32 -0800
          Subject: [maven-release-plugin] prepare for next development iteration
          
          ---
           pom.xml | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/pom.xml b/pom.xml
          index 9db8daf..3b1f36f 100644
          --- a/pom.xml
          +++ b/pom.xml
          @@ -24,7 +24,7 @@
             jcommander
             jar
             JCommander
          -  1.15
          +  1.16-SNAPSHOT
             A Java framework to parse command line options with annotations.
             http://beust.com/jcommander
             
          -- 
          cgit v1.2.3
          
          
          From 5f94fa3f279131d63e55a68bf16b4dd632c643f6 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:21:01 -0800
          Subject: Don't display "Options:" if none were defined.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index f715620..f7532a2 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -739,7 +739,6 @@ public class JCommander {
               if (m_mainParameterAnnotation != null) {
                 out.append(" " + m_mainParameterAnnotation.description() + "\n");
               }
          -    out.append("  Options:\n");
           
               // 
               // Align the descriptions at the "longestName" column
          @@ -769,6 +768,7 @@ public class JCommander {
               //
               // Display all the names and descriptions
               //
          +    if (sorted.size() > 0) out.append("  Options:\n");
               for (ParameterDescription pd : sorted) {
                 int l = pd.getNames().length();
                 int spaceCount = longestName - l;
          -- 
          cgit v1.2.3
          
          
          From 804498ec24662928bf06efcee6584d55fca3d898 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:44:15 -0800
          Subject: Double check that the type of a main parameter is a List.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java |  9 +++++---
           .../beust/jcommander/ArgsRequiredWrongMain.java    |  6 ++++++
           .../java/com/beust/jcommander/JCommanderTest.java  | 24 ++++++++++++++++++++--
           3 files changed, 34 insertions(+), 5 deletions(-)
           create mode 100644 src/test/java/com/beust/jcommander/ArgsRequiredWrongMain.java
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index f7532a2..1167034 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -629,7 +629,7 @@ public class JCommander {
             /**
              * @return the field that's meant to receive all the parameters that are not options.
              * 
          -   * @param arg the arg that we're about to add (only passed here to ouput a meaningful
          +   * @param arg the arg that we're about to add (only passed here to output a meaningful
              * error message).
              */
             private List getMainParameter(String arg) {
          @@ -639,10 +639,13 @@ public class JCommander {
               }
           
               try {
          -      @SuppressWarnings("unchecked")
          -      List result = (List) m_mainParameterField.get(m_mainParameterObject);
          +      List result = (List) m_mainParameterField.get(m_mainParameterObject);
                 if (result == null) {
                   result = Lists.newArrayList();
          +        if (! List.class.isAssignableFrom(m_mainParameterField.getType())) {
          +          throw new ParameterException("Main parameter field " + m_mainParameterField
          +              + " needs to be of type List, not " + m_mainParameterField.getType());
          +        }
                   m_mainParameterField.set(m_mainParameterObject, result);
                 }
                 return result;
          diff --git a/src/test/java/com/beust/jcommander/ArgsRequiredWrongMain.java b/src/test/java/com/beust/jcommander/ArgsRequiredWrongMain.java
          new file mode 100644
          index 0000000..c2124d9
          --- /dev/null
          +++ b/src/test/java/com/beust/jcommander/ArgsRequiredWrongMain.java
          @@ -0,0 +1,6 @@
          +package com.beust.jcommander;
          +
          +public class ArgsRequiredWrongMain {
          +  @Parameter(required = true)
          +  public String[] file;
          +}
          \ No newline at end of file
          diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
          index f2dfc68..8e2a48a 100644
          --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
          +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
          @@ -45,12 +45,15 @@ import com.beust.jcommander.command.CommandAdd;
           import com.beust.jcommander.command.CommandCommit;
           import com.beust.jcommander.command.CommandMain;
           
          +import org.omg.PortableServer.POAPackage.WrongAdapter;
           import org.testng.Assert;
           import org.testng.annotations.DataProvider;
           import org.testng.annotations.Test;
           
          +import java.util.ArrayList;
           import java.util.Arrays;
           import java.util.Iterator;
          +import java.util.List;
           import java.util.Locale;
           import java.util.Map;
           import java.util.ResourceBundle;
          @@ -430,8 +433,24 @@ public class JCommanderTest {
               Assert.assertFalse(arguments.inspect);
             }
           
          -//  public static void main(String[] args) {
          -//    new JCommanderTest().arity1Fail();
          +  @Parameters(commandDescription = "Help for the given commands.")
          +  public static class Help {
          +      public static final String NAME = "help";
          +
          +      @Parameter(description = "List of commands.")
          +      public List commands=new ArrayList();
          +  }
          +
          +  @Test(expectedExceptions = ParameterException.class,
          +      description = "Verify that the main parameter's type is checked to be a List")
          +  public void wrongMainTypeShouldThrow() {
          +    JCommander jc = new JCommander(new ArgsRequiredWrongMain());
          +    jc.parse(new String[] { "f1", "f2" });
          +  }
          +
          +  @Test(enabled = false)
          +  public static void main(String[] args) {
          +    new JCommander(new Help()).usage();
           //    new JCommanderTest().booleanArity1();
           //    ArgsLongDescription a = new ArgsLongDescription();
           //    JCommander jc = new JCommander(a);
          @@ -463,6 +482,7 @@ public class JCommanderTest {
           //    JCommander jc = new JCommander(a, argv);
           //    Assert.assertEquals(a.log.intValue(), 10);
           //  }
          +  }
           
             // Tests:
             // required unparsed parameter
          -- 
          cgit v1.2.3
          
          
          From c512c633a76a8bfe5a8eda8c6198cce7af4c5eaf Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:52:47 -0800
          Subject: Fixed OOM reported by huxi.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java          |  4 ++--
           src/test/java/com/beust/jcommander/JCommanderTest.java      |  9 ++++++++-
           .../java/com/beust/jcommander/args/ArgsOutOfMemory.java     | 13 +++++++++++++
           3 files changed, 23 insertions(+), 3 deletions(-)
           create mode 100644 src/test/java/com/beust/jcommander/args/ArgsOutOfMemory.java
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 1167034..e4ab6a0 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -812,11 +812,11 @@ public class JCommander {
                 if (word.length() > max || current + word.length() <= max) {
                   out.append(" ").append(word);
                   current += word.length() + 1;
          -        i++;
                 } else {
          -        out.append("\n").append(spaces(indent));
          +        out.append("\n").append(spaces(indent + 1)).append(word);
                   current = indent;
                 }
          +      i++;
               }
             }
           
          diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
          index 8e2a48a..9dabd57 100644
          --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
          +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
          @@ -32,6 +32,7 @@ import com.beust.jcommander.args.ArgsInherited;
           import com.beust.jcommander.args.ArgsMainParameter1;
           import com.beust.jcommander.args.ArgsMaster;
           import com.beust.jcommander.args.ArgsMultipleUnparsed;
          +import com.beust.jcommander.args.ArgsOutOfMemory;
           import com.beust.jcommander.args.ArgsPrivate;
           import com.beust.jcommander.args.ArgsRequired;
           import com.beust.jcommander.args.ArgsSlave;
          @@ -448,9 +449,15 @@ public class JCommanderTest {
               jc.parse(new String[] { "f1", "f2" });
             }
           
          +  @Test(description = "This used to run out of memory")
          +  public void oom() {
          +    JCommander jc = new JCommander(new ArgsOutOfMemory());
          +    jc.usage(new StringBuilder());
          +  }
          +
             @Test(enabled = false)
             public static void main(String[] args) {
          -    new JCommander(new Help()).usage();
          +    new JCommanderTest().oom();
           //    new JCommanderTest().booleanArity1();
           //    ArgsLongDescription a = new ArgsLongDescription();
           //    JCommander jc = new JCommander(a);
          diff --git a/src/test/java/com/beust/jcommander/args/ArgsOutOfMemory.java b/src/test/java/com/beust/jcommander/args/ArgsOutOfMemory.java
          new file mode 100644
          index 0000000..f059ebb
          --- /dev/null
          +++ b/src/test/java/com/beust/jcommander/args/ArgsOutOfMemory.java
          @@ -0,0 +1,13 @@
          +package com.beust.jcommander.args;
          +
          +import com.beust.jcommander.Parameter;
          +
          +public class ArgsOutOfMemory
          +{
          +  @Parameter(names = { "-p", "--pattern"  },
          +      description = "pattern used by 'tail'. See http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout and http://logback.qos.ch/manual/layouts.html#AccessPatternLayout")
          +  public String pattern;
          +
          +  @Parameter(names = "-q", description = "Filler arg")
          +  public String filler;
          +}
          -- 
          cgit v1.2.3
          
          
          From 279af567cbf71ef018ec01c80990e4ea20ecad38 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 24 Jan 2011 14:57:44 -0800
          Subject: Updated change log.
          
          ---
           CHANGELOG | 6 +++++-
           1 file changed, 5 insertions(+), 1 deletion(-)
          
          diff --git a/CHANGELOG b/CHANGELOG
          index 5b872f2..0201303 100644
          --- a/CHANGELOG
          +++ b/CHANGELOG
          @@ -1,6 +1,10 @@
           Current
           
          -1.14
          +Added: Don't display "Options:" if none were defined.
          +Added: Enforce that the type of the main parameter is a List.
          +Fixed: OOM when parsing certain descriptions with long URL's in them.
          +
          +1.15
           2011/01/24
           
           Added: Added a constructor that takes a Bundle only, https://github.com/cbeust/jcommander/pull/47 (Russell Egan)
          -- 
          cgit v1.2.3
          
          
          From 26fa1a86fa9c35b50735e4bcfca1c9ea7919fae1 Mon Sep 17 00:00:00 2001
          From: sclasen 
          Date: Mon, 28 Feb 2011 12:45:30 -0800
          Subject: call createDescriptions in single arg constructor and make
           getMaimParamterDescription public
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 3 ++-
           1 file changed, 2 insertions(+), 1 deletion(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index e4ab6a0..79d2a85 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -140,6 +140,7 @@ public class JCommander {
              */
             public JCommander(Object object) {
               addObject(object);
          +    createDescriptions();
             }
           
             /**
          @@ -655,7 +656,7 @@ public class JCommander {
               }
             }
           
          -  private String getMainParameterDescription() {
          +  public String getMainParameterDescription() {
               if (m_descriptions == null) createDescriptions();
               return m_mainParameterAnnotation != null ? m_mainParameterAnnotation.description()
                   : null;
          -- 
          cgit v1.2.3
          
          
          From 704a28637f848de8506df4dd0fb2c12862c5313f Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 28 Feb 2011 13:00:31 -0800
          Subject: TestNG version bump.
          
          ---
           build-with-maven | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/build-with-maven b/build-with-maven
          index 50cfc6f..f6241fb 100755
          --- a/build-with-maven
          +++ b/build-with-maven
          @@ -1,6 +1,6 @@
           mvn clean source:jar javadoc:jar repository:bundle-create -P sign
           
          -export TESTNG=../testng/target/testng-5.14.7beta.jar
          +export TESTNG=../testng/target/testng-5.14.11beta.jar
           
           java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
           
          -- 
          cgit v1.2.3
          
          
          From 498e8bdb06b2926085c06a9d64c4846872569a1c Mon Sep 17 00:00:00 2001
          From: sclasen 
          Date: Fri, 4 Mar 2011 16:34:03 -0800
          Subject: make it possible to do partial parsing of arguments, and get back
           info on what parsed successfully
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 45 ++++++++++++++++------
           1 file changed, 33 insertions(+), 12 deletions(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 79d2a85..1265b30 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -47,12 +47,12 @@ import java.util.ResourceBundle;
            * 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
            * values and a few other helper methods, such as usage().
          - * 
          + *
            * The object(s) you pass in the constructor are expected to have one or more
          - * \@Parameter annotations on them. You can pass either a single object, an array of objects 
          + * \@Parameter annotations on them. You can pass either a single object, an array of objects
            * or an instance of Iterable. In the case of an array or Iterable, JCommander will collect
            * the \@Parameter annotations from all the objects passed in parameter.
          - * 
          + *
            * @author cbeust
            */
           public class JCommander {
          @@ -221,6 +221,27 @@ public class JCommander {
               validateOptions();
             }
           
          +  public void parseWithoutValidation(String... args) {
          +    StringBuilder sb = new StringBuilder("Parsing \"");
          +    sb.append(join(args).append("\"\n  with:").append(join(m_objects.toArray())));
          +    p(sb.toString());
          +
          +    if (m_descriptions == null) createDescriptions();
          +    initializeDefaultValues();
          +    parseValues(expandArgs(args));
          +  }
          +
          +  public List getParsedParameterDescriptions(){
          +      List descriptions  = new ArrayList();
          +      descriptions.addAll(m_descriptions.values());
          +      if(m_mainParameterDescription != null){
          +        descriptions.add(m_mainParameterDescription);
          +      }
          +      return descriptions;
          +  }
          +
          +
          +
             private StringBuilder join(Object[] args) {
               StringBuilder result = new StringBuilder();
               for (int i = 0; i < args.length; i++) {
          @@ -258,12 +279,12 @@ public class JCommander {
                 }
               }
             }
          -  
          +
             /**
              * Expand the command line parameters to take @ parameters into account.
              * When @ is encountered, the content of the file that follows is inserted
              * in the command line.
          -   * 
          +   *
              * @param originalArgv the original command line parameters
              * @return the new and enriched command line parameters
              */
          @@ -367,7 +388,7 @@ public class JCommander {
             /**
              * Reads the file specified by filename and returns the file content as a string.
              * End of lines are replaced by a space.
          -   * 
          +   *
              * @param fileName the command line filename
              * @return the file content as a string.
              */
          @@ -499,7 +520,7 @@ public class JCommander {
                       // 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)
          @@ -551,7 +572,7 @@ public class JCommander {
                       List mp = getMainParameter(arg);
                       String value = arg;
                       Object convertedValue = value;
          - 
          +
                       if (m_mainParameterField.getGenericType() instanceof ParameterizedType) {
                         ParameterizedType p = (ParameterizedType) m_mainParameterField.getGenericType();
                         Type cls = p.getActualTypeArguments()[0];
          @@ -559,7 +580,7 @@ public class JCommander {
                           convertedValue = convertValue(m_mainParameterField, (Class) cls, value);
                         }
                       }
          - 
          +
                       m_mainParameterDescription.setAssigned(true);
                       mp.add(convertedValue);
                     }
          @@ -591,7 +612,7 @@ public class JCommander {
               System.out.print(description + ": ");
               try {
                 Method consoleMethod = System.class.getDeclaredMethod("console", new Class[0]);
          -      Object console = consoleMethod.invoke(null, new Object[0]); 
          +      Object console = consoleMethod.invoke(null, new Object[0]);
                 Method readPassword = console.getClass().getDeclaredMethod("readPassword", new Class[0]);
                 return (char[]) readPassword.invoke(console, new Object[0]);
               } catch (Throwable t) {
          @@ -629,7 +650,7 @@ public class JCommander {
           
             /**
              * @return the field that's meant to receive all the parameters that are not options.
          -   * 
          +   *
              * @param arg the arg that we're about to add (only passed here to output a meaningful
              * error message).
              */
          @@ -744,7 +765,7 @@ public class JCommander {
                 out.append(" " + m_mainParameterAnnotation.description() + "\n");
               }
           
          -    // 
          +    //
               // Align the descriptions at the "longestName" column
               //
               int longestName = 0;
          -- 
          cgit v1.2.3
          
          
          From ef5dbe79a31d03712952e0266f60d5138859631b Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 7 Mar 2011 11:27:55 -0800
          Subject: Removed duplicates in pom.xml.
          
          ---
           pom.xml | 33 ---------------------------------
           1 file changed, 33 deletions(-)
          
          diff --git a/pom.xml b/pom.xml
          index 3b1f36f..a55edd5 100644
          --- a/pom.xml
          +++ b/pom.xml
          @@ -125,39 +125,6 @@
                   
                 
           
          -      
          -      
          -        org.apache.felix
          -        maven-bundle-plugin
          -        2.1.0
          -        
          -          
          -            bundle-manifest
          -            process-classes
          -            
          -              manifest
          -            
          -            
          -              
          -                <_versionpolicy>$(@)
          -              
          -            
          -          
          -        
          -      
          -
          -      
          -      
          -        org.apache.maven.plugins
          -        maven-jar-plugin
          -        2.3.1
          -        
          -          
          -            ${project.build.outputDirectory}/META-INF/MANIFEST.MF
          -          
          -        
          -      
          -
                 
                 
                   org.apache.maven.plugins
          -- 
          cgit v1.2.3
          
          
          From cf51b03416fc313fadfc6a427c23f37fb282f24c Mon Sep 17 00:00:00 2001
          From: sclasen 
          Date: Mon, 7 Mar 2011 16:39:32 -0800
          Subject: after parsing, set the assigned flag for the parameterDescriptions in
           m_fields that have been assigned, add a getMainParameter method that returns
           the main ParamaterDescription obj
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 26 +++++++++++++---------
           1 file changed, 15 insertions(+), 11 deletions(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 1265b30..5fb47ba 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -231,17 +231,6 @@ public class JCommander {
               parseValues(expandArgs(args));
             }
           
          -  public List getParsedParameterDescriptions(){
          -      List descriptions  = new ArrayList();
          -      descriptions.addAll(m_descriptions.values());
          -      if(m_mainParameterDescription != null){
          -        descriptions.add(m_mainParameterDescription);
          -      }
          -      return descriptions;
          -  }
          -
          -
          -
             private StringBuilder join(Object[] args) {
               StringBuilder result = new StringBuilder();
               for (int i = 0; i < args.length; i++) {
          @@ -602,6 +591,14 @@ public class JCommander {
                 }
                 i++;
               }
          +
          +      //Flag the parameter descriptions held in field as assigned
          +      for (ParameterDescription parameterDescription : m_descriptions.values()) {
          +          if(parameterDescription.isAssigned()){
          +            m_fields.get(parameterDescription.getField()).setAssigned(true);
          +          }
          +      }
          +
             }
           
             /**
          @@ -857,6 +854,13 @@ public class JCommander {
               return new ArrayList(m_fields.values());
             }
           
          +    /**
          +     * @return the main parameter description or null if none is defined.
          +     */
          +  public ParameterDescription getMainParameter(){
          +    return m_mainParameterDescription;
          +  }
          +
             private void p(String string) {
               if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) {
                 System.out.println("[JCommander] " + string);
          -- 
          cgit v1.2.3
          
          
          From b2367c03a3dcb1bead3b34926d958fc94d9c0028 Mon Sep 17 00:00:00 2001
          From: sclasen 
          Date: Tue, 8 Mar 2011 12:21:18 -0800
          Subject: fix typo in comment
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 5fb47ba..e7ff287 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -592,7 +592,7 @@ public class JCommander {
                 i++;
               }
           
          -      //Flag the parameter descriptions held in field as assigned
          +      //Flag the parameter descriptions held in m_fields as assigned
                 for (ParameterDescription parameterDescription : m_descriptions.values()) {
                     if(parameterDescription.isAssigned()){
                       m_fields.get(parameterDescription.getField()).setAssigned(true);
          -- 
          cgit v1.2.3
          
          
          From 71de5baa23811cac1ee6014e29cf021a283a18c1 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Wed, 9 Mar 2011 11:21:08 -0800
          Subject: TestNG update.
          
          ---
           build-with-maven | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/build-with-maven b/build-with-maven
          index f6241fb..700b33d 100755
          --- a/build-with-maven
          +++ b/build-with-maven
          @@ -1,6 +1,6 @@
           mvn clean source:jar javadoc:jar repository:bundle-create -P sign
           
          -export TESTNG=../testng/target/testng-5.14.11beta.jar
          +export TESTNG=../testng/target/testng-5.14.12beta.jar
           
           java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
           
          -- 
          cgit v1.2.3
          
          
          From cfbeb8905f1166e5fd03624a34571d6ae5ab321d Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Wed, 9 Mar 2011 11:24:15 -0800
          Subject: First pass at implementing validators.
          
          ---
           .../com/beust/jcommander/IParameterValidator.java  | 38 ++++++++++++++++++++
           src/main/java/com/beust/jcommander/Parameter.java  |  6 ++++
           .../com/beust/jcommander/ParameterDescription.java | 21 ++++++++++--
           .../beust/jcommander/validators/NoValidator.java   | 35 +++++++++++++++++++
           .../jcommander/validators/PositiveInteger.java     | 40 ++++++++++++++++++++++
           .../java/com/beust/jcommander/JCommanderTest.java  | 18 ++++++++--
           .../com/beust/jcommander/args/ArgsValidate1.java   | 10 ++++++
           7 files changed, 163 insertions(+), 5 deletions(-)
           create mode 100644 src/main/java/com/beust/jcommander/IParameterValidator.java
           create mode 100644 src/main/java/com/beust/jcommander/validators/NoValidator.java
           create mode 100644 src/main/java/com/beust/jcommander/validators/PositiveInteger.java
           create mode 100644 src/test/java/com/beust/jcommander/args/ArgsValidate1.java
          
          diff --git a/src/main/java/com/beust/jcommander/IParameterValidator.java b/src/main/java/com/beust/jcommander/IParameterValidator.java
          new file mode 100644
          index 0000000..19fee0d
          --- /dev/null
          +++ b/src/main/java/com/beust/jcommander/IParameterValidator.java
          @@ -0,0 +1,38 @@
          +/**
          + * Copyright (C) 2011 the original author or authors.
          + * See the notice.md file distributed with this work for additional
          + * information regarding copyright ownership.
          + *
          + * Licensed under the Apache License, Version 2.0 (the "License");
          + * you may not use this file except in compliance with the License.
          + * You may obtain a copy of the License at
          + *
          + *     http://www.apache.org/licenses/LICENSE-2.0
          + *
          + * Unless required by applicable law or agreed to in writing, software
          + * distributed under the License is distributed on an "AS IS" BASIS,
          + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          + * See the License for the specific language governing permissions and
          + * limitations under the License.
          + */
          +
          +package com.beust.jcommander;
          +
          +/**
          + * The class used to validate parameters.
          + *
          + * @author Cedric Beust 
          + */
          +public interface IParameterValidator {
          +
          +  /**
          +   * Validate the parameter.
          +   *
          +   * @param name The name of the parameter (e.g. "-host").
          +   * @param value The value of the parameter that we need to validate
          +   *
          +   * @throws ParameterException Thrown if the value of the parameter is invalid.
          +   */
          +  void validate(String name, String value) throws ParameterException;
          +
          +}
          diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java
          index 24fa469..7003f5d 100644
          --- a/src/main/java/com/beust/jcommander/Parameter.java
          +++ b/src/main/java/com/beust/jcommander/Parameter.java
          @@ -21,6 +21,7 @@ package com.beust.jcommander;
           import static java.lang.annotation.ElementType.FIELD;
           
           import com.beust.jcommander.converters.NoConverter;
          +import com.beust.jcommander.validators.NoValidator;
           
           import java.lang.annotation.Retention;
           import java.lang.annotation.Target;
          @@ -72,4 +73,9 @@ public @interface Parameter {
              * If true, this parameter won't appear in the usage().
              */
             boolean hidden() default false;
          +
          +  /**
          +   * The validation class to use.
          +   */
          +  Class validateWith() default NoValidator.class;
           }
          diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
          index a2232f6..281f190 100644
          --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
          +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
          @@ -20,6 +20,7 @@ package com.beust.jcommander;
           
           
           import com.beust.jcommander.internal.Lists;
          +import com.beust.jcommander.validators.NoValidator;
           
           import java.lang.reflect.Field;
           import java.util.Collection;
          @@ -160,17 +161,31 @@ public class ParameterDescription {
             }
           
             /**
          -   * Add the specified value to the field. First look up any field converter, then
          -   * any type converter, and if we can't find any, throw an exception.
          +   * Add the specified value to the field. First, validate the value if a
          +   * validator was specified. Then look up any field converter, then any type
          +   * converter, and if we can't find any, throw an exception.
              */
             public void addValue(String value, boolean isDefault) {
               p("Adding " + (isDefault ? "default " : "") + "value:" + value
                   + " to parameter:" + m_field.getName());
          +    String name = m_parameterAnnotation.names()[0];
               if (m_assigned && ! isMultiOption()) {
          -      throw new ParameterException("Can only specify option " + m_parameterAnnotation.names()[0]
          +      throw new ParameterException("Can only specify option " + name
                     + " once.");
               }
           
          +     Class validator = m_parameterAnnotation.validateWith();
          +    if (validator != NoValidator.class) {
          +      try {
          +        p("Validating parameter:" + name + " value:" + value + " validator:" + validator);
          +        validator.newInstance().validate(name, value);
          +      } catch (InstantiationException e) {
          +        throw new ParameterException("Can't instantiate validator:" + e);
          +      } catch (IllegalAccessException e) {
          +        throw new ParameterException("Can't instantiate validator:" + e);
          +      }
          +    }
          +
               Class type = m_field.getType();
           
               if (! isDefault) m_assigned = true;
          diff --git a/src/main/java/com/beust/jcommander/validators/NoValidator.java b/src/main/java/com/beust/jcommander/validators/NoValidator.java
          new file mode 100644
          index 0000000..f1b4df2
          --- /dev/null
          +++ b/src/main/java/com/beust/jcommander/validators/NoValidator.java
          @@ -0,0 +1,35 @@
          +/**
          + * Copyright (C) 2011 the original author or authors.
          + * See the notice.md file distributed with this work for additional
          + * information regarding copyright ownership.
          + *
          + * Licensed under the Apache License, Version 2.0 (the "License");
          + * you may not use this file except in compliance with the License.
          + * You may obtain a copy of the License at
          + *
          + *     http://www.apache.org/licenses/LICENSE-2.0
          + *
          + * Unless required by applicable law or agreed to in writing, software
          + * distributed under the License is distributed on an "AS IS" BASIS,
          + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          + * See the License for the specific language governing permissions and
          + * limitations under the License.
          + */
          +
          +package com.beust.jcommander.validators;
          +
          +import com.beust.jcommander.IParameterValidator;
          +import com.beust.jcommander.ParameterException;
          +
          +/**
          + * This is the default value of the validateWith attribute.
          + *
          + * @author Cedric Beust 
          + */
          +public class NoValidator implements IParameterValidator {
          +
          +  public void validate(String parameterName, String parameterValue)
          +      throws ParameterException {
          +  }
          +
          +}
          diff --git a/src/main/java/com/beust/jcommander/validators/PositiveInteger.java b/src/main/java/com/beust/jcommander/validators/PositiveInteger.java
          new file mode 100644
          index 0000000..7b5c1b7
          --- /dev/null
          +++ b/src/main/java/com/beust/jcommander/validators/PositiveInteger.java
          @@ -0,0 +1,40 @@
          +/**
          + * Copyright (C) 2011 the original author or authors.
          + * See the notice.md file distributed with this work for additional
          + * information regarding copyright ownership.
          + *
          + * Licensed under the Apache License, Version 2.0 (the "License");
          + * you may not use this file except in compliance with the License.
          + * You may obtain a copy of the License at
          + *
          + *     http://www.apache.org/licenses/LICENSE-2.0
          + *
          + * Unless required by applicable law or agreed to in writing, software
          + * distributed under the License is distributed on an "AS IS" BASIS,
          + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          + * See the License for the specific language governing permissions and
          + * limitations under the License.
          + */
          +
          +package com.beust.jcommander.validators;
          +
          +import com.beust.jcommander.IParameterValidator;
          +import com.beust.jcommander.ParameterException;
          +
          +/**
          + * A validator that makes sure the value of the parameter is a positive integer.
          + *
          + * @author Cedric Beust 
          + */
          +public class PositiveInteger implements IParameterValidator {
          +
          +  public void validate(String name, String value)
          +      throws ParameterException {
          +    int n = Integer.parseInt(value);
          +    if (n < 0) {
          +      throw new ParameterException("Parameter " + name
          +          + " should be positive (found " + value +")");
          +    }
          +  }
          +
          +}
          diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
          index 9dabd57..627a95b 100644
          --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
          +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
          @@ -37,6 +37,7 @@ import com.beust.jcommander.args.ArgsPrivate;
           import com.beust.jcommander.args.ArgsRequired;
           import com.beust.jcommander.args.ArgsSlave;
           import com.beust.jcommander.args.ArgsSlaveBogus;
          +import com.beust.jcommander.args.ArgsValidate1;
           import com.beust.jcommander.args.Arity1;
           import com.beust.jcommander.args.SeparatorColon;
           import com.beust.jcommander.args.SeparatorEqual;
          @@ -46,7 +47,6 @@ import com.beust.jcommander.command.CommandAdd;
           import com.beust.jcommander.command.CommandCommit;
           import com.beust.jcommander.command.CommandMain;
           
          -import org.omg.PortableServer.POAPackage.WrongAdapter;
           import org.testng.Assert;
           import org.testng.annotations.DataProvider;
           import org.testng.annotations.Test;
          @@ -455,9 +455,23 @@ public class JCommanderTest {
               jc.usage(new StringBuilder());
             }
           
          +  @Test
          +  public void getParametersShouldNotNpe() {
          +    JCommander jc = new JCommander(new Args1());
          +    List parameters = jc.getParameters();
          +  }
          +
          +  @Test(expectedExceptions = ParameterException.class)
          +  public void validationShouldWork1() {
          +    ArgsValidate1 a = new ArgsValidate1();
          +    JCommander jc = new JCommander(a);
          +    jc.parse(new String[] { "-age", "-2 "});
          +    System.out.println("Age:" + a.age);
          +  }
          +
             @Test(enabled = false)
             public static void main(String[] args) {
          -    new JCommanderTest().oom();
          +    new JCommanderTest().validationShouldWork1();
           //    new JCommanderTest().booleanArity1();
           //    ArgsLongDescription a = new ArgsLongDescription();
           //    JCommander jc = new JCommander(a);
          diff --git a/src/test/java/com/beust/jcommander/args/ArgsValidate1.java b/src/test/java/com/beust/jcommander/args/ArgsValidate1.java
          new file mode 100644
          index 0000000..5274220
          --- /dev/null
          +++ b/src/test/java/com/beust/jcommander/args/ArgsValidate1.java
          @@ -0,0 +1,10 @@
          +package com.beust.jcommander.args;
          +
          +import com.beust.jcommander.Parameter;
          +import com.beust.jcommander.validators.PositiveInteger;
          +
          +public class ArgsValidate1 {
          +
          +  @Parameter(names = "-age", validateWith = PositiveInteger.class)
          +  public Integer age;
          +}
          -- 
          cgit v1.2.3
          
          
          From 344383cd3a0d67c900fb40dd7ba7d8a528798411 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 10:44:19 -0800
          Subject: Dead code.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 8 ++++----
           1 file changed, 4 insertions(+), 4 deletions(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 79d2a85..2b18236 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -898,10 +898,10 @@ public class JCommander {
           //      converter = (IStringConverter) m_converterFactories.getConverter(type);
           //    }
           
          -    if (converterClass == null) {
          -      throw new ParameterException("Don't know how to convert " + value
          -          + " to type " + type + " (field: " + field.getName() + ")");
          -    }
          +//    if (converterClass == null) {
          +//      throw new ParameterException("Don't know how to convert " + value
          +//          + " to type " + type + " (field: " + field.getName() + ")");
          +//    }
           
               IStringConverter converter;
               Object result = null;
          -- 
          cgit v1.2.3
          
          
          From ad383ae3f3e890856da4ae1d487bdcac5feab4b7 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 10:44:32 -0800
          Subject: Dead code.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 3 ---
           1 file changed, 3 deletions(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 2b18236..c7f921f 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -884,9 +884,6 @@ public class JCommander {
               if (converterClass == null) {
                 converterClass = StringConverter.class;
               }
          -    if (converterClass == null && Collection.class.isAssignableFrom(type)) {
          -      converterClass = StringConverter.class;
          -    }
           
               //
           //    //
          -- 
          cgit v1.2.3
          
          
          From 91b83b28a07d3ab0df7880b473e37b2b978c6a99 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 10:44:54 -0800
          Subject: Suppress a few warnings.
          
          ---
           src/main/java/com/beust/jcommander/ParameterDescription.java | 1 +
           src/main/java/com/beust/jcommander/ParameterException.java   | 7 +++++++
           src/test/java/com/beust/jcommander/args/ArgsI18N2.java       | 1 +
           3 files changed, 9 insertions(+)
          
          diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
          index 281f190..210d0ba 100644
          --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
          +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
          @@ -51,6 +51,7 @@ public class ParameterDescription {
              * Find the resource bundle in the annotations.
              * @return
              */
          +  @SuppressWarnings("deprecation")
             private ResourceBundle findResourceBundle(Object o) {
               ResourceBundle result = null;
           
          diff --git a/src/main/java/com/beust/jcommander/ParameterException.java b/src/main/java/com/beust/jcommander/ParameterException.java
          index 8bf5a20..3c0f588 100644
          --- a/src/main/java/com/beust/jcommander/ParameterException.java
          +++ b/src/main/java/com/beust/jcommander/ParameterException.java
          @@ -18,6 +18,13 @@
           
           package com.beust.jcommander;
           
          +/**
          + * The main exception that JCommand will throw when something goes wrong while
          + * parsing parameters.
          + *
          + * @author Cedric Beust 
          + */
          +@SuppressWarnings("serial")
           public class ParameterException extends RuntimeException {
           
             public ParameterException(Throwable t) {
          diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N2.java b/src/test/java/com/beust/jcommander/args/ArgsI18N2.java
          index 772d041..1ccfd43 100644
          --- a/src/test/java/com/beust/jcommander/args/ArgsI18N2.java
          +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N2.java
          @@ -21,6 +21,7 @@ package com.beust.jcommander.args;
           import com.beust.jcommander.Parameter;
           import com.beust.jcommander.ResourceBundle;
           
          +@SuppressWarnings("deprecation")
           @ResourceBundle("MessageBundle")
           public class ArgsI18N2 {
           
          -- 
          cgit v1.2.3
          
          
          From 045653099e8e35ef1f05654b6b023cc8324c0ebf Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 10:45:11 -0800
          Subject: Javadoc.
          
          ---
           src/main/java/com/beust/jcommander/ResourceBundle.java | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/src/main/java/com/beust/jcommander/ResourceBundle.java b/src/main/java/com/beust/jcommander/ResourceBundle.java
          index 279fa6d..806ade8 100644
          --- a/src/main/java/com/beust/jcommander/ResourceBundle.java
          +++ b/src/main/java/com/beust/jcommander/ResourceBundle.java
          @@ -26,7 +26,7 @@ import java.lang.annotation.Target;
           /**
            * @deprecated use @Parameters
            * 
          - * @author cbeust
          + * @author Cedric Beust 
            */
           @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
           @Target({ TYPE })
          -- 
          cgit v1.2.3
          
          
          From e1d494d69d20c1afab9ff29a9fd31e48ba71cc7c Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 10:45:34 -0800
          Subject: Better test case for the validator.
          
          ---
           src/test/java/com/beust/jcommander/JCommanderTest.java | 10 ++++++++--
           1 file changed, 8 insertions(+), 2 deletions(-)
          
          diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
          index 627a95b..293e976 100644
          --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
          +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
          @@ -461,12 +461,18 @@ public class JCommanderTest {
               List parameters = jc.getParameters();
             }
           
          -  @Test(expectedExceptions = ParameterException.class)
             public void validationShouldWork1() {
          +    ArgsValidate1 a = new ArgsValidate1();
          +    JCommander jc = new JCommander(a);
          +    jc.parse(new String[] { "-age", "2 "});
          +    Assert.assertEquals(a.age, new Integer(2));
          +  }
          +
          +  @Test(expectedExceptions = ParameterException.class)
          +  public void validationShouldWork2() {
               ArgsValidate1 a = new ArgsValidate1();
               JCommander jc = new JCommander(a);
               jc.parse(new String[] { "-age", "-2 "});
          -    System.out.println("Age:" + a.age);
             }
           
             @Test(enabled = false)
          -- 
          cgit v1.2.3
          
          
          From d576340c4a1fe43ad63ac3dfb346ca4c90dde574 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 10:45:46 -0800
          Subject: Introduced new MissingCommandException.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java |  2 +-
           .../beust/jcommander/MissingCommandException.java  | 36 ++++++++++++++++++++++
           2 files changed, 37 insertions(+), 1 deletion(-)
           create mode 100644 src/main/java/com/beust/jcommander/MissingCommandException.java
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index c7f921f..2cbbac2 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -568,7 +568,7 @@ public class JCommander {
                       // Command parsing
                       //
                       JCommander jc = m_commands.get(arg);
          -            if (jc == null) throw new ParameterException("Expected a command, got " + arg);
          +            if (jc == null) throw new MissingCommandException("Expected a command, got " + arg);
                       m_parsedCommand = arg;
           
                       // Found a valid command, ask it to parse the remainder of the arguments.
          diff --git a/src/main/java/com/beust/jcommander/MissingCommandException.java b/src/main/java/com/beust/jcommander/MissingCommandException.java
          new file mode 100644
          index 0000000..1d572ab
          --- /dev/null
          +++ b/src/main/java/com/beust/jcommander/MissingCommandException.java
          @@ -0,0 +1,36 @@
          +/**
          + * Copyright (C) 2010 the original author or authors.
          + * See the notice.md file distributed with this work for additional
          + * information regarding copyright ownership.
          + *
          + * Licensed under the Apache License, Version 2.0 (the "License");
          + * you may not use this file except in compliance with the License.
          + * You may obtain a copy of the License at
          + *
          + *     http://www.apache.org/licenses/LICENSE-2.0
          + *
          + * Unless required by applicable law or agreed to in writing, software
          + * distributed under the License is distributed on an "AS IS" BASIS,
          + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          + * See the License for the specific language governing permissions and
          + * limitations under the License.
          + */
          +
          +package com.beust.jcommander;
          +
          +/**
          + * Thrown when a command was expected.
          + *
          + * @author Cedric Beust 
          + */
          +@SuppressWarnings("serial")
          +public class MissingCommandException extends ParameterException {
          +
          +  public MissingCommandException(String string) {
          +    super(string);
          +  }
          +
          +  public MissingCommandException(Throwable t) {
          +    super(t);
          +  }
          +}
          -- 
          cgit v1.2.3
          
          
          From 8877f663e79381340b329180922d7ac448e26317 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 11:04:38 -0800
          Subject: Fixed: Exception when using an @ file with empty lines between
           options.
          
          ---
           CHANGELOG                                              |  2 ++
           src/main/java/com/beust/jcommander/JCommander.java     |  3 ++-
           src/test/java/com/beust/jcommander/JCommanderTest.java | 18 ++++++++++++++++--
           3 files changed, 20 insertions(+), 3 deletions(-)
          
          diff --git a/CHANGELOG b/CHANGELOG
          index 0201303..f16f616 100644
          --- a/CHANGELOG
          +++ b/CHANGELOG
          @@ -1,7 +1,9 @@
           Current
           
          +Added: IParameterValidator
           Added: Don't display "Options:" if none were defined.
           Added: Enforce that the type of the main parameter is a List.
          +Fixed: Exception when using an @ file with empty lines between options
           Fixed: OOM when parsing certain descriptions with long URL's in them.
           
           1.15
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 2cbbac2..4209aa1 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -381,7 +381,8 @@ public class JCommander {
           
                 // Read through file one line at time. Print line # and line
                 while ((line = bufRead.readLine()) != null) {
          -        result.add(line);
          +        // Allow empty lines in these at files
          +        if (line.length() > 0) result.add(line);
                 }
           
                 bufRead.close();
          diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
          index 293e976..9985d49 100644
          --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
          +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
          @@ -51,6 +51,9 @@ import org.testng.Assert;
           import org.testng.annotations.DataProvider;
           import org.testng.annotations.Test;
           
          +import java.io.File;
          +import java.io.FileWriter;
          +import java.io.IOException;
           import java.util.ArrayList;
           import java.util.Arrays;
           import java.util.Iterator;
          @@ -475,9 +478,20 @@ public class JCommanderTest {
               jc.parse(new String[] { "-age", "-2 "});
             }
           
          +  public void atFileCanContainEmptyLines() throws IOException {
          +    File f = File.createTempFile("JCommander", null);
          +    f.deleteOnExit();
          +    FileWriter fw = new FileWriter(f);
          +    fw.write("-log\n");
          +    fw.write("\n");
          +    fw.write("2\n");
          +    fw.close();
          +    new JCommander(new Args1(), "@" + f.getAbsolutePath());
          +  }
          +
             @Test(enabled = false)
          -  public static void main(String[] args) {
          -    new JCommanderTest().validationShouldWork1();
          +  public static void main(String[] args) throws Exception {
          +    new JCommanderTest().atFileCanContainEmptyLines();
           //    new JCommanderTest().booleanArity1();
           //    ArgsLongDescription a = new ArgsLongDescription();
           //    JCommander jc = new JCommander(a);
          -- 
          cgit v1.2.3
          
          
          From 6995afda6050f57d12bc08046755146e0de67de1 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 10 Mar 2011 13:24:20 -0800
          Subject: Some refactoring on top of sclasen's change.
          
          ---
           src/main/java/com/beust/jcommander/JCommander.java | 37 +++++++++++-----------
           1 file changed, 19 insertions(+), 18 deletions(-)
          
          diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
          index 46fbffc..f96efff 100644
          --- a/src/main/java/com/beust/jcommander/JCommander.java
          +++ b/src/main/java/com/beust/jcommander/JCommander.java
          @@ -208,20 +208,20 @@ public class JCommander {
             }
           
             /**
          -   * Parse the command line parameters.
          +   * Parse and validate the command line parameters.
              */
             public void parse(String... args) {
          -    StringBuilder sb = new StringBuilder("Parsing \"");
          -    sb.append(join(args).append("\"\n  with:").append(join(m_objects.toArray())));
          -    p(sb.toString());
          -
          -    if (m_descriptions == null) createDescriptions();
          -    initializeDefaultValues();
          -    parseValues(expandArgs(args));
          -    validateOptions();
          +    parse(true /* validate */, args);
             }
           
          +  /**
          +   * Parse the command line parameters without validating them.
          +   */
             public void parseWithoutValidation(String... args) {
          +    parse(false /* no validation */, args);
          +  }
          +
          +  private void parse(boolean validate, String... args) {
               StringBuilder sb = new StringBuilder("Parsing \"");
               sb.append(join(args).append("\"\n  with:").append(join(m_objects.toArray())));
               p(sb.toString());
          @@ -229,6 +229,7 @@ public class JCommander {
               if (m_descriptions == null) createDescriptions();
               initializeDefaultValues();
               parseValues(expandArgs(args));
          +    if (validate) validateOptions();
             }
           
             private StringBuilder join(Object[] args) {
          @@ -593,12 +594,12 @@ public class JCommander {
                 i++;
               }
           
          -      //Flag the parameter descriptions held in m_fields as assigned
          -      for (ParameterDescription parameterDescription : m_descriptions.values()) {
          -          if(parameterDescription.isAssigned()){
          -            m_fields.get(parameterDescription.getField()).setAssigned(true);
          -          }
          +    // Mark the parameter descriptions held in m_fields as assigned
          +    for (ParameterDescription parameterDescription : m_descriptions.values()) {
          +      if (parameterDescription.isAssigned()) {
          +        m_fields.get(parameterDescription.getField()).setAssigned(true);
                 }
          +    }
           
             }
           
          @@ -855,10 +856,10 @@ public class JCommander {
               return new ArrayList(m_fields.values());
             }
           
          -    /**
          -     * @return the main parameter description or null if none is defined.
          -     */
          -  public ParameterDescription getMainParameter(){
          +  /**
          +   * @return the main parameter description or null if none is defined.
          +   */
          +  public ParameterDescription getMainParameter() {
               return m_mainParameterDescription;
             }
           
          -- 
          cgit v1.2.3
          
          
          From 758c9118cfef92d1851fb6cb3c10472866fc7bb8 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Fri, 11 Mar 2011 10:57:40 -0800
          Subject: Added the doc for parameter validation.
          
          ---
           doc/index.html | 42 ++++++++++++++++++++++++++++++++++++++++++
           1 file changed, 42 insertions(+)
          
          diff --git a/doc/index.html b/doc/index.html
          index 2f8c45c..4b4a431 100644
          --- a/doc/index.html
          +++ b/doc/index.html
          @@ -258,6 +258,48 @@ All you need to do is add the factory to your JCommander object:
           
           Another advantage of using string converter factories is that your factories can come from a dependency injection framework.
           
          +

          Parameter validation

          + +You can ask JCommander to perform early validation on your parameters by providing a class that implements the following interface: + +
          +public interface IParameterValidator {
          + /**
          +   * Validate the parameter.
          +   *
          +   * @param name The name of the parameter (e.g. "-host").
          +   * @param value The value of the parameter that we need to validate
          +   *
          +   * @throws ParameterException Thrown if the value of the parameter is invalid.
          +   */
          +  void validate(String name, String value) throws ParameterException;
          +}
          +
          +
          + +Here is an example implementation that will make sure that the parameter is a positive integer: + +
          +public class PositiveInteger implements IParameterValidator {
          + public void validate(String name, String value)
          +      throws ParameterException {
          +    int n = Integer.parseInt(value);
          +    if (n < 0) {
          +      throw new ParameterException("Parameter " + name + " should be positive (found " + value +")");
          +    }
          +  }
          +}
          +
          + +Specify the name of a class implementing this interface in the validateWith attribute of your @Parameter annotations: + +
          +@Parameter(names = "-age", validateWith = PositiveInteger.class)
          +public Integer age;
          +
          + +Attempting to pass a negative integer to this option will cause a ParameterException to be thrown. +

          Main parameter

          So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a List<String> and it will contain all the parameters that are not options: -- cgit v1.2.3 From 0e5234ded49df9e0b19fff6d551c08c9d1182419 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 14 Mar 2011 14:10:08 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.16 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a55edd5..34aaf15 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.16-SNAPSHOT + 1.16 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 0fe4d1779226b6024c361bac37ee9f887133bcd9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 14 Mar 2011 14:10:15 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34aaf15..0443f17 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.16 + 1.17-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 8241c1e0d8b38b8fe36bfc4ade3a789e44f2c851 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 14 Mar 2011 14:12:51 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.17 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0443f17..96a74be 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.17-SNAPSHOT + 1.17 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From f27a703ff5e74b33ea0fea8d1e33454ff2cae51a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 14 Mar 2011 14:12:57 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96a74be..31515a2 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.17 + 1.18-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 122046aebee36783f5cf73081ef288faddd0a249 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 14 Mar 2011 14:17:51 -0700 Subject: Version bump. --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 4b4a431..6d01cf3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -665,7 +665,7 @@ You can download JCommander from the following locations: <groupId>com.beust</groupId> <artifactId>jcommander</artifactId> - 1.13 + 1.17
          -- cgit v1.2.3 From bb2b66c8eb6a88d193c95336a8563cb8b0a324f5 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 15 Mar 2011 15:38:36 -0700 Subject: Upgraded to TestNG 6.0. --- build-with-maven | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build-with-maven b/build-with-maven index 700b33d..238ddf5 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn clean source:jar javadoc:jar repository:bundle-create -P sign -export TESTNG=../testng/target/testng-5.14.12beta.jar +export TESTNG=../testng/target/testng-6.0.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml diff --git a/pom.xml b/pom.xml index 31515a2..50ca8f0 100644 --- a/pom.xml +++ b/pom.xml @@ -161,7 +161,7 @@ org.testng testng - 5.14.6 + 6.0 jar test -- cgit v1.2.3 From a9656e4788b44f97aff3c480a4292245c588fed3 Mon Sep 17 00:00:00 2001 From: sclasen Date: Mon, 11 Apr 2011 14:49:16 -0700 Subject: let converterfactories have the chance to override existing defaults --- src/main/java/com/beust/jcommander/JCommander.java | 9 ++++-- .../java/com/beust/jcommander/internal/Lists.java | 33 ++++++++++++++-------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index f96efff..104f6ee 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -40,9 +40,12 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.LinkedList; import java.util.Map; import java.util.ResourceBundle; + + /** * 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 @@ -123,10 +126,10 @@ public class JCommander { /** * The factories used to look up string converters. */ - private static List CONVERTER_FACTORIES = Lists.newArrayList(); + private static LinkedList CONVERTER_FACTORIES = Lists.newLinkedList(); static { - CONVERTER_FACTORIES.add(new DefaultConverterFactory()); + CONVERTER_FACTORIES.addFirst(new DefaultConverterFactory()); }; /** @@ -877,7 +880,7 @@ public class JCommander { } public void addConverterFactory(IStringConverterFactory converterFactory) { - CONVERTER_FACTORIES.add(converterFactory); + CONVERTER_FACTORIES.addFirst(converterFactory); } public Class> findConverter(Class cls) { diff --git a/src/main/java/com/beust/jcommander/internal/Lists.java b/src/main/java/com/beust/jcommander/internal/Lists.java index 8666fe4..c4017c0 100644 --- a/src/main/java/com/beust/jcommander/internal/Lists.java +++ b/src/main/java/com/beust/jcommander/internal/Lists.java @@ -20,19 +20,30 @@ package com.beust.jcommander.internal; import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedList; import java.util.List; public class Lists { - public static List newArrayList() { - return new ArrayList(); - } - - public static List newArrayList(Collection c) { - return new ArrayList(c); - } - - public static List newArrayList(int size) { - return new ArrayList(size); - } + public static List newArrayList() { + return new ArrayList(); + } + + public static List newArrayList(Collection c) { + return new ArrayList(c); + } + + public static List newArrayList(int size) { + return new ArrayList(size); + } + + public static LinkedList newLinkedList() { + return new LinkedList(); + } + + public static LinkedList newLinkedList(Collection c) { + return new LinkedList(c); + } + + } -- cgit v1.2.3 From db01fd217bef9949af8ee2c2d9e5b6c9c148d2b9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 12 Apr 2011 13:03:29 -0700 Subject: Added: Default converter factories can be overridden (Scott Clasen) --- CHANGELOG | 1 + build-with-maven | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index f16f616..7f1fc4e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: Default converter factories can be overridden (Scott Clasen) Added: IParameterValidator Added: Don't display "Options:" if none were defined. Added: Enforce that the type of the main parameter is a List. diff --git a/build-with-maven b/build-with-maven index 238ddf5..5f0e714 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn clean source:jar javadoc:jar repository:bundle-create -P sign -export TESTNG=../testng/target/testng-6.0.jar +export TESTNG=../testng/target/testng-6.0.2beta.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From 4804ce09adb4fe1227850edc5ef4545528704678 Mon Sep 17 00:00:00 2001 From: rodionmoiseev Date: Sat, 28 May 2011 19:15:08 +0900 Subject: Added support for command aliases, e.g. "ci" for "commit" command, etc. Any number of aliases can be optionally specified to the addCommand() method. In usage output commands containing aliases will be formatted with a post-fixed comma-separated list of aliases in brackets, e.g. commit(ci,cmt). usage(String) series of methods also accept both commands and aliases. All existing API should be compatible with previous versions. --- src/main/java/com/beust/jcommander/JCommander.java | 184 +++++++++++++++++++-- .../beust/jcommander/command/CommandAliasTest.java | 174 +++++++++++++++++++ src/test/resources/testng.xml | 1 + 3 files changed, 342 insertions(+), 17 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/command/CommandAliasTest.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 104f6ee..da3cd6c 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -36,9 +36,11 @@ import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.LinkedList; import java.util.Map; @@ -114,14 +116,24 @@ public class JCommander { /** * List of commands and their instance. */ - private Map m_commands = Maps.newLinkedHashMap(); + private Map m_commands = Maps.newLinkedHashMap(); + /** + * Alias database for reverse lookup + */ + private Map aliasMap = Maps.newLinkedHashMap(); /** * The name of the command after the parsing has run. */ private String m_parsedCommand; - private String m_programName; + /** + * The name of command or alias as it was passed to the + * command line + */ + private String m_parsedAlias; + + private ProgramName m_programName; /** * The factories used to look up string converters. @@ -582,9 +594,10 @@ public class JCommander { // // Command parsing // - JCommander jc = m_commands.get(arg); + JCommander jc = findCommandByAlias(arg); if (jc == null) throw new MissingCommandException("Expected a command, got " + arg); - m_parsedCommand = arg; + m_parsedCommand = jc.m_programName.name; + m_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 @@ -699,7 +712,17 @@ public class JCommander { * Set the program name (used only in the usage). */ public void setProgramName(String name) { - m_programName = name; + setProgramName(name, new String[0]); + } + + /** + * 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)); } /** @@ -716,7 +739,7 @@ public class JCommander { */ public void usage(String commandName, StringBuilder out) { String description = getCommandDescription(commandName); - JCommander jc = m_commands.get(commandName); + JCommander jc = findCommandByAlias(commandName); if (description != null) { out.append(description); out.append("\n"); @@ -728,7 +751,7 @@ public class JCommander { * @return the description of the command. */ public String getCommandDescription(String commandName) { - JCommander jc = m_commands.get(commandName); + JCommander jc = findCommandByAlias(commandName); if (jc == null) { throw new ParameterException("Asking description for unknown command: " + commandName); } @@ -754,12 +777,12 @@ public class JCommander { */ public void usage(StringBuilder out) { if (m_descriptions == null) createDescriptions(); - boolean hasCommands = ! m_commands.isEmpty(); + boolean hasCommands = !m_commands.isEmpty(); // // First line of the usage // - String programName = m_programName != null ? m_programName : "
          "; + String programName = m_programName != null ? m_programName.getDisplayName() : "
          "; out.append("Usage: " + programName + " [options]"); if (hasCommands) out.append(" [command] [command options]"); out.append("\n"); @@ -818,10 +841,11 @@ public class JCommander { // The magic value 3 is the number of spaces between the name of the option // and its description int ln = longestName(m_commands.keySet()) + 3; - for (Map.Entry commands : m_commands.entrySet()) { - String name = commands.getKey(); - int spaceCount = ln - name.length(); - out.append(" " + name + s(spaceCount) + getCommandDescription(name) + "\n"); + for (Map.Entry commands : m_commands.entrySet()) { + ProgramName progName = commands.getKey(); + String dispName = progName.getDisplayName(); + int spaceCount = ln - dispName.length(); + out.append(" " + dispName + s(spaceCount) + getCommandDescription(progName.name) + "\n"); } } } @@ -976,19 +1000,64 @@ public class JCommander { * Add a command object. */ public void addCommand(String name, Object object) { + addCommand(name, object, new String[0]); + } + + /** + * Add a command object. + */ + public void addCommand(String name, Object object, String... aliases) { JCommander jc = new JCommander(object); - jc.setProgramName(name); - m_commands.put(name, jc); + jc.setProgramName(name, aliases); + ProgramName progName = jc.m_programName; + m_commands.put(progName, jc); + + /* + * Register aliases + */ + //register command name as an alias of itself for reverse lookup + //Note: Name clash check is intentionally omitted to resemble the + // original behaviour of clashing commands. + // Aliases are, however, are strictly checked for name clashes. + aliasMap.put(name, progName); + for (String alias : aliases) { + //omit pointless aliases to avoid name clash exception + if (!alias.equals(name)) { + ProgramName mappedName = aliasMap.get(alias); + if (mappedName != null && !mappedName.equals(progName)) { + throw new ParameterException("Cannot set alias " + alias + + " for " + name + + " command because it has already been defined for " + + mappedName.name + " command"); + } + aliasMap.put(alias, progName); + } + } } public Map getCommands() { - return m_commands; + Map res = Maps.newLinkedHashMap(); + for (Map.Entry entry : m_commands.entrySet()) { + res.put(entry.getKey().name, entry.getValue()); + } + return res; } public String getParsedCommand() { return m_parsedCommand; } + /** + * The name of the command or the alias in the form it was + * passed to the command line. null if no + * command or alias was specified. + * + * @return Name of command or alias passed to command line. If none passed: null. + */ + public String getParsedAlias() { + return m_parsedAlias; + } + /** * @return n spaces */ @@ -1008,5 +1077,86 @@ public class JCommander { public List getObjects() { return m_objects; } -} + /* + * Reverse lookup JCommand object by command's name or its alias + */ + private JCommander findCommandByAlias(String commandOrAlias) { + ProgramName progName = aliasMap.get(commandOrAlias); + if (progName == null) { + return null; + } + JCommander jc = m_commands.get(progName); + if (jc == null) { + throw new IllegalStateException( + "There appears to be inconsistency in the internal command database. " + + " This is likely a bug. Please report."); + } + return jc; + } + + private static final class ProgramName { + private final String name; + private final List aliases; + + ProgramName(String name) { + this(name, Collections.emptyList()); + } + + ProgramName(String name, List aliases) { + this.name = name; + this.aliases = aliases; + } + + private String getDisplayName() { + StringBuilder sb = new StringBuilder(); + sb.append(name); + if (!aliases.isEmpty()) { + sb.append("("); + Iterator aliasesIt = aliases.iterator(); + while (aliasesIt.hasNext()) { + sb.append(aliasesIt.next()); + if (aliasesIt.hasNext()) { + sb.append(","); + } + } + sb.append(")"); + } + return sb.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ProgramName other = (ProgramName) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + /* + * Important: ProgramName#toString() is used by longestName(Collection) function + * to format usage output. + */ + @Override + public String toString() { + return getDisplayName(); + } + } +} diff --git a/src/test/java/com/beust/jcommander/command/CommandAliasTest.java b/src/test/java/com/beust/jcommander/command/CommandAliasTest.java new file mode 100644 index 0000000..eddcb0a --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/CommandAliasTest.java @@ -0,0 +1,174 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Tests command alias functionality + * + * @author rodionmoiseev + */ +public class CommandAliasTest { + @Test + public void oneCommandWithSingleAlias() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add, "a"); + jc.parse("a", "-i", "A.java"); + + Assert.assertEquals(jc.getParsedCommand(), "add"); + Assert.assertEquals(jc.getParsedAlias(), "a"); + Assert.assertEquals(add.interactive.booleanValue(), true); + Assert.assertEquals(add.patterns, Arrays.asList("A.java")); + } + + @Test + public void oneCommandWithMultipleAliases_commit_ci() { + testCommitWithAlias("ci"); + } + + @Test + public void oneCommandWithMultipleAliases_commit_cmt() { + testCommitWithAlias("cmt"); + } + + private void testCommitWithAlias(String alias) { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit, "ci", "cmt"); + jc.parse(alias, "--amend", "--author", "jack", "file1.txt"); + + Assert.assertEquals(jc.getParsedCommand(), "commit"); + Assert.assertEquals(jc.getParsedAlias(), alias); + Assert.assertEquals(commit.amend.booleanValue(), true); + Assert.assertEquals(commit.author, "jack"); + Assert.assertEquals(commit.files, Arrays.asList("file1.txt")); + } + + @Test + public void twoCommandsWithAliases() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add, "a"); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit, "ci", "cmt"); + jc.parse("a", "-i", "A.java"); + + Assert.assertEquals(jc.getParsedCommand(), "add"); + Assert.assertEquals(add.interactive.booleanValue(), true); + Assert.assertEquals(add.patterns, Arrays.asList("A.java")); + } + + @Test + public void clashingAliasesAreNotAllowed() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add, "xx"); + CommandCommit commit = new CommandCommit(); + try { + jc.addCommand("commit", commit, "ci", "xx"); + Assert.fail("Should not be able to register clashing alias 'xx'"); + } catch (ParameterException pe) { + //Make sure the message mentions that "xx" aliases is already + //defined for "add" command + Assert.assertTrue(pe.getMessage().contains("xx")); + Assert.assertTrue(pe.getMessage().contains("add")); + } + } + + @Test + public void mainCommandReturnsNullsForGetCommandAndGetParsedAlias() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + Assert.assertNull(jc.getParsedCommand()); + Assert.assertNull(jc.getParsedAlias()); + } + + @Test + public void usageCanBeRetrievedWithBothCommandAndAlias() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit, "ci", "cmt"); + StringBuilder out = new StringBuilder(); + jc.usage("commit", out); + patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1); + + out = new StringBuilder(); + jc.usage("ci", out); + patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1); + + out = new StringBuilder(); + jc.usage("cmt", out); + patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1); + } + + @Test + public void usageDisplaysCommandWithAliasesOnlyOnce() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit, "ci", "cmt"); + StringBuilder out = new StringBuilder(); + jc.usage(out); + patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1); + } + + /** + * Visually test the formatting for "prettiness" + */ + @Test + public void formattingLooksNice(){ + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add, "a"); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit, "ci", "cmt"); + StringBuilder sb = new StringBuilder(); + jc.usage(sb); + System.out.println("--- usage() formatting ---"); + System.out.println(sb.toString()); + + sb = new StringBuilder(); + jc.usage("commit", sb); + System.out.println("--- usage('commit') formatting ---"); + System.out.println(sb.toString()); + } + + private void patternMatchesTimes(String pattern, String input, int times) { + Matcher m = Pattern.compile(pattern).matcher(input); + int matches = 0; + while (m.find()) + matches++; + Assert.assertEquals(matches, times); + } +} diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 3f9f985..7b55b9d 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -5,6 +5,7 @@ + -- cgit v1.2.3 From b9893ab2c4547b75942f73f96d20b37d1e245689 Mon Sep 17 00:00:00 2001 From: rodionmoiseev Date: Sun, 29 May 2011 11:37:46 +0900 Subject: Fixed issue #64 (wrong default value behaviour in for list parameters), and added support for Set parameters. Fix for #64: * ParameterDescription#m_assigned flag was being set too early, meaning it could become true even in case of an exception. To fix, moved it to the end of the try block. * Now we can use m_assigned, to test if the fields is being set for the first time, and use it to clear default values for collection parameters. Added support for Set type parameters, and provided a clearer exception for unsupported Collection type parameters (before the fix, a ClassCastException would be thrown). Additional support for Stack and Queue types could be added but would require a little more testing. Not sure of how useful Queues and Stacks would be anyway. --- .../com/beust/jcommander/ParameterDescription.java | 34 ++++++- .../java/com/beust/jcommander/internal/Sets.java | 5 + .../com/beust/jcommander/DefaultValueTest.java | 113 +++++++++++++++++++++ src/test/resources/testng.xml | 1 + 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/DefaultValueTest.java diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 210d0ba..488a7b0 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -20,6 +20,7 @@ package com.beust.jcommander; import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Sets; import com.beust.jcommander.validators.NoValidator; import java.lang.reflect.Field; @@ -189,16 +190,15 @@ public class ParameterDescription { Class type = m_field.getType(); - if (! isDefault) m_assigned = true; Object convertedValue = m_jCommander.convertValue(this, value); boolean isCollection = Collection.class.isAssignableFrom(type); try { if (isCollection) { @SuppressWarnings("unchecked") - List l = (List) m_field.get(m_object); - if (l == null) { - l = Lists.newArrayList(); + Collection l = (Collection) m_field.get(m_object); + if (l == null || fieldIsSetForTheFirstTime(isDefault)) { + l = newCollection(type); m_field.set(m_object, l); } if (convertedValue instanceof Collection) { @@ -211,12 +211,38 @@ public class ParameterDescription { } else { m_field.set(m_object, convertedValue); } + if (! isDefault) m_assigned = true; } catch(IllegalAccessException ex) { ex.printStackTrace(); } } + /* + * Creates a new collection for the field's type. + * + * Currently only List and Set are supported. Support for + * Queues and Stacks could be useful. + */ + private Collection newCollection(Class type) { + if(List.class.isAssignableFrom(type)){ + return Lists.newArrayList(); + } else if(Set.class.isAssignableFrom(type)){ + return Sets.newLinkedHashSet(); + } else { + throw new ParameterException("Parameters of Collection type '" + type.getSimpleName() + + "' are not supported. Please use List or Set instead."); + } + } + + /* + * Tests if its the first time a non-default value is + * being added to the field. + */ + private boolean fieldIsSetForTheFirstTime(boolean isDefault) { + return (!isDefault && !m_assigned); + } + public boolean isNumber() { Class type = m_field.getType(); return type.equals(Integer.class) || type.equals(int.class) diff --git a/src/main/java/com/beust/jcommander/internal/Sets.java b/src/main/java/com/beust/jcommander/internal/Sets.java index 221376a..77949c3 100644 --- a/src/main/java/com/beust/jcommander/internal/Sets.java +++ b/src/main/java/com/beust/jcommander/internal/Sets.java @@ -19,6 +19,7 @@ package com.beust.jcommander.internal; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; public class Sets { @@ -27,4 +28,8 @@ public class Sets { return new HashSet(); } + public static Set newLinkedHashSet() { + return new LinkedHashSet(); + } + } diff --git a/src/test/java/com/beust/jcommander/DefaultValueTest.java b/src/test/java/com/beust/jcommander/DefaultValueTest.java new file mode 100644 index 0000000..3b1f29c --- /dev/null +++ b/src/test/java/com/beust/jcommander/DefaultValueTest.java @@ -0,0 +1,113 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander; + +import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Sets; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * Test behaviour of default parameter values + * @author rodionmoiseev + */ +public class DefaultValueTest { + @Test + public void emptyDefaultValueForListParameterStaysEmptyIfNotAssignedOrIsSetOtherwise() { + MyOptsWithEmptyDefaults opts = new MyOptsWithEmptyDefaults(); + JCommander cmd = new JCommander(opts); + cmd.parse(new String[]{"-a", "anotherValue"}); + Assert.assertEquals(opts.list.size(), 1); + Assert.assertEquals(opts.list.get(0), "anotherValue"); + Assert.assertEquals(opts.set.size(), 0); + } + + @Test + public void defaultValueForListParametersGetsOverwrittenWithSpecifiedValueOrStaysAsDefaultOtherwise() { + MyOptsWithDefaultValues opts = new MyOptsWithDefaultValues(); + JCommander cmd = new JCommander(opts); + cmd.parse(new String[]{"-a", "anotherValue"}); + Assert.assertEquals(opts.list.size(), 1); + Assert.assertEquals(opts.list.get(0), "anotherValue"); + Assert.assertEquals(opts.set.size(), 1); + Assert.assertEquals(opts.set.iterator().next(), "defaultValue"); + } + + @Test + public void anyNumberOfValuesCanBeSetToListParameters_ForEmptyDefaults(){ + MyOptsWithEmptyDefaults opts = new MyOptsWithEmptyDefaults(); + testSettingMultipleValuesToListTypeParameters(opts); + } + + @Test + public void anyNumberOfValuesCanBeSetToListParameters_ForNonEmptyDefaults(){ + MyOptsWithDefaultValues opts = new MyOptsWithDefaultValues(); + testSettingMultipleValuesToListTypeParameters(opts); + } + + private void testSettingMultipleValuesToListTypeParameters(MyOpts opts) { + JCommander cmd = new JCommander(opts); + cmd.parse(new String[]{"-a", "anotherValue", "-a", "anotherValue2", + "-b", "anotherValue3", "-b", "anotherValue4"}); + Assert.assertEquals(opts.list.size(), 2); + Assert.assertEquals(opts.list.get(0), "anotherValue"); + Assert.assertEquals(opts.list.get(1), "anotherValue2"); + Assert.assertEquals(opts.set.size(), 2); + Iterator arg2it = opts.set.iterator(); + Assert.assertEquals(arg2it.next(), "anotherValue3"); + Assert.assertEquals(arg2it.next(), "anotherValue4"); + } + + public static class MyOpts { + @Parameter(names = "-a") + public List list; + @Parameter(names = "-b") + public Set set; + } + + public static final class MyOptsWithDefaultValues extends MyOpts { + public MyOptsWithDefaultValues(){ + this.list = singletonList("defaultValue"); + this.set = singletonSet("defaultValue"); + } + } + + public static final class MyOptsWithEmptyDefaults extends MyOpts { + public MyOptsWithEmptyDefaults(){ + this.list = Lists.newArrayList(); + this.set = Sets.newLinkedHashSet(); + } + } + + public static final List singletonList(String value) { + List list = Lists.newArrayList(); + list.add(value); + return list; + } + + public static final Set singletonSet(String value){ + Set set = Sets.newLinkedHashSet(); + set.add(value); + return set; + } +} diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 7b55b9d..0ba3c9b 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -8,6 +8,7 @@ + -- cgit v1.2.3 From 307ad87e19e6c8ae91d7dec7acfe308873097e26 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 May 2011 11:31:33 -0700 Subject: Minor fixes on top of rodionmoiseev's patch. - Javadoc update - Disabled a test. --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/command/CommandAliasTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index da3cd6c..62d2cd9 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1004,7 +1004,7 @@ public class JCommander { } /** - * Add a command object. + * Add a command object and its aliases. */ public void addCommand(String name, Object object, String... aliases) { JCommander jc = new JCommander(object); diff --git a/src/test/java/com/beust/jcommander/command/CommandAliasTest.java b/src/test/java/com/beust/jcommander/command/CommandAliasTest.java index eddcb0a..15d79d4 100644 --- a/src/test/java/com/beust/jcommander/command/CommandAliasTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandAliasTest.java @@ -145,7 +145,7 @@ public class CommandAliasTest { /** * Visually test the formatting for "prettiness" */ - @Test + @Test(enabled = false, description = "TODO: test the output instead of displaying it") public void formattingLooksNice(){ CommandMain cm = new CommandMain(); JCommander jc = new JCommander(cm); -- cgit v1.2.3 From fe8a696f6c65438505eb26d8b734d34910932ef7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 13 Jun 2011 13:35:31 -0700 Subject: Fixed: Default values with a validator were being validate at parse() time instead of creation time. --- CHANGELOG | 1 + .../com/beust/jcommander/ParameterDescription.java | 35 +++++++++++++++------- .../java/com/beust/jcommander/ArgsValidate2.java | 24 +++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 8 ++++- 4 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/ArgsValidate2.java diff --git a/CHANGELOG b/CHANGELOG index 7f1fc4e..fc696fe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ Added: Default converter factories can be overridden (Scott Clasen) Added: IParameterValidator Added: Don't display "Options:" if none were defined. Added: Enforce that the type of the main parameter is a List. +Fixed: Default values with a validator were being validate at parse() time instead of creation time. Fixed: Exception when using an @ file with empty lines between options Fixed: OOM when parsing certain descriptions with long URL's in them. diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 488a7b0..7b43677 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -104,6 +104,15 @@ public class ParameterDescription { m_default = m_field.get(m_object); } catch (Exception e) { } + + // + // Validate default values, if any and if applicable + // + if (m_default != null) { + String[] names = m_parameterAnnotation.names(); + String name = names.length > 0 ? names[0] : ""; + validateParameter(name, m_default.toString()); + } } public String getLongestName() { @@ -176,17 +185,7 @@ public class ParameterDescription { + " once."); } - Class validator = m_parameterAnnotation.validateWith(); - if (validator != NoValidator.class) { - try { - p("Validating parameter:" + name + " value:" + value + " validator:" + validator); - validator.newInstance().validate(name, value); - } catch (InstantiationException e) { - throw new ParameterException("Can't instantiate validator:" + e); - } catch (IllegalAccessException e) { - throw new ParameterException("Can't instantiate validator:" + e); - } - } + validateParameter(name, value); Class type = m_field.getType(); @@ -218,6 +217,20 @@ public class ParameterDescription { } } + private void validateParameter(String name, String value) { + Class validator = m_parameterAnnotation.validateWith(); + if (validator != NoValidator.class) { + try { + p("Validating parameter:" + name + " value:" + value + " validator:" + validator); + validator.newInstance().validate(name, value); + } catch (InstantiationException e) { + throw new ParameterException("Can't instantiate validator:" + e); + } catch (IllegalAccessException e) { + throw new ParameterException("Can't instantiate validator:" + e); + } + } + } + /* * Creates a new collection for the field's type. * diff --git a/src/test/java/com/beust/jcommander/ArgsValidate2.java b/src/test/java/com/beust/jcommander/ArgsValidate2.java new file mode 100644 index 0000000..f45f5df --- /dev/null +++ b/src/test/java/com/beust/jcommander/ArgsValidate2.java @@ -0,0 +1,24 @@ +package com.beust.jcommander; + +import com.beust.jcommander.converters.FileConverter; + +import java.io.File; + +public class ArgsValidate2 { + public static class FailingValidator implements IParameterValidator { + + public void validate(String name, String value) throws ParameterException { + throw new ParameterException("Validation will always fail:" + name + " " + value); + } + + } + + public static final String POSSIBLE_TEMPLATE_FILE = "mayOrMayNotExist.tempalate"; + + @Parameter(names = { "-template"}, + description = "The default file may or may not exist", + converter = FileConverter.class, + validateWith = FailingValidator.class + ) + public File template = new File(POSSIBLE_TEMPLATE_FILE); +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9985d49..e5822ee 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -471,6 +471,12 @@ public class JCommanderTest { Assert.assertEquals(a.age, new Integer(2)); } + @Test(expectedExceptions = ParameterException.class) + public void validationShouldWorkWithDefaultValues() { + ArgsValidate2 a = new ArgsValidate2(); + new JCommander(a); + } + @Test(expectedExceptions = ParameterException.class) public void validationShouldWork2() { ArgsValidate1 a = new ArgsValidate1(); @@ -491,7 +497,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().atFileCanContainEmptyLines(); + new JCommanderTest().validationShouldWorkWithDefaultValues(); // new JCommanderTest().booleanArity1(); // ArgsLongDescription a = new ArgsLongDescription(); // JCommander jc = new JCommander(a); -- cgit v1.2.3 From 1f80e8ab0d32fdd23634e76b780a4ca6487ee42b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 29 Jun 2011 16:30:32 -0700 Subject: Scala doc update. --- doc/index.html | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/index.html b/doc/index.html index 3246ba3..21ffb09 100644 --- a/doc/index.html +++ b/doc/index.html @@ -600,6 +600,37 @@ host: Hôte JCommander will then use the default locale to resolve your descriptions. +

          JCommander in Scala

          + +Here is a quick example of how to use JCommander in Scala (courtesy of Patrick Linskey): + +
          +import java.io.File
          +import com.beust.jcommander.{JCommander, Parameter}
          +import collection.JavaConversions._
          +
          +object Main {
          +  object Args {
          +    // Declared as var because JCommander assigns a new collection; declared
          +    // as java.util.List because that's what JCommander will replace with.
          +    // It'd be nice if JCommander would just use the provided List so this
          +    // could be a val and a Scala LinkedList.
          +    @Parameter(
          +      names = Array("-f", "--file"),
          +      description = "File to load. Can be specified multiple times.")
          +    var file: java.util.List[String] = null
          +  }
          +
          +  def main(args: Array[String]): Unit = {
          +    new JCommander(Args, args.toArray: _*)
          +    for (filename <- Args.file) {
          +      val f = new File(filename)
          +      printf("file: %s\n", f.getName)
          +    }
          +  }
          +}
          +
          +

          More examples

          TestNG uses JCommander to parse its command line, here is its definition file. -- cgit v1.2.3 From 4fdea2348ea2720e5525b45dab0de5ba66514314 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 29 Jun 2011 16:30:47 -0700 Subject: upload script update. --- upload | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/upload b/upload index d0beaf5..a177639 100755 --- a/upload +++ b/upload @@ -1,4 +1,5 @@ -scp doc/index.html target/jcommander-1.7.jar beust.com@beust.com:w/jcommander +scp doc/index.html target/jcommander-1.7.jar beust.com@beust.com:domains/jcommander.org/html mvn javadoc:javadoc -scp -r target/site/apidocs beust.com@beust.com:w/jcommander +scp -r target/site/apidocs beust.com@beust.com:domains/jcommander.org/html + -- cgit v1.2.3 From 1af343c624b09d38ef4cb79805a09dffd75edee2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 29 Jun 2011 16:30:55 -0700 Subject: Updated TestNG dependency to 6.1. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 43a4c62..8a188ac 100644 --- a/pom.xml +++ b/pom.xml @@ -188,7 +188,7 @@ org.testng testng - 5.14.6 + 6.1 jar test -- cgit v1.2.3 From b3eff749853a11c6cf8ff08b66a1d77db4924f95 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 29 Jun 2011 16:39:29 -0700 Subject: Script update. --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index 5f0e714..dd985eb 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn clean source:jar javadoc:jar repository:bundle-create -P sign -export TESTNG=../testng/target/testng-6.0.2beta.jar +export TESTNG=../testng/target/testng-6.1.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From 0f2f333aaab931cc8cf9dbb877c4ec39e96c97fe Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 7 Jul 2011 11:15:36 -0700 Subject: Build file update. --- build-with-maven | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build-with-maven b/build-with-maven index 5f0e714..3ae2808 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,7 @@ -mvn clean source:jar javadoc:jar repository:bundle-create -P sign +mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -export TESTNG=../testng/target/testng-6.0.2beta.jar +v=6.1.2beta +export TESTNG=../testng/target/testng-${v}.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From b9f80c6e8a3040bb0ad3bece9303385063ee4f2f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 7 Jul 2011 11:15:51 -0700 Subject: Depending on 6.1.1. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 50ca8f0..ea21119 100644 --- a/pom.xml +++ b/pom.xml @@ -161,7 +161,7 @@ org.testng testng - 6.0 + 6.1.1 jar test -- cgit v1.2.3 From c199c87fcd7d702047dd813fbc4224c7d85fd95d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 7 Jul 2011 13:34:54 -0700 Subject: Added: usage() now displays the options for each command as well --- CHANGELOG | 7 +- src/main/java/com/beust/jcommander/JCommander.java | 75 +++++++++++++--------- .../beust/jcommander/command/CommandAliasTest.java | 7 +- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fc696fe..5946d1c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,11 +2,12 @@ Current Added: Default converter factories can be overridden (Scott Clasen) Added: IParameterValidator -Added: Don't display "Options:" if none were defined. -Added: Enforce that the type of the main parameter is a List. +Added: Don't display "Options:" if none were defined +Added: Enforce that the type of the main parameter is a List +Added: usage() now displays the options for each command as well Fixed: Default values with a validator were being validate at parse() time instead of creation time. Fixed: Exception when using an @ file with empty lines between options -Fixed: OOM when parsing certain descriptions with long URL's in them. +Fixed: OOM when parsing certain descriptions with long URL's in them 1.15 2011/01/24 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 62d2cd9..260942f 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -596,7 +596,7 @@ public class JCommander { // JCommander jc = findCommandByAlias(arg); if (jc == null) throw new MissingCommandException("Expected a command, got " + arg); - m_parsedCommand = jc.m_programName.name; + m_parsedCommand = jc.m_programName.m_name; m_parsedAlias = arg; //preserve the original form // Found a valid command, ask it to parse the remainder of the arguments. @@ -738,13 +738,21 @@ public class JCommander { * Store the help for the command in the passed string builder. */ public void usage(String commandName, StringBuilder out) { + usage(commandName, out, ""); + } + + /** + * Store the help for the command in the passed string builder, indenting + * every line with "indent". + */ + public void usage(String commandName, StringBuilder out, String indent) { String description = getCommandDescription(commandName); JCommander jc = findCommandByAlias(commandName); if (description != null) { - out.append(description); + out.append(indent).append(description); out.append("\n"); } - jc.usage(out); + jc.usage(out, indent); } /** @@ -776,6 +784,10 @@ public class JCommander { * Store the help in the passed string builder. */ public void usage(StringBuilder out) { + usage(out, ""); + } + + public void usage(StringBuilder out, String indent) { if (m_descriptions == null) createDescriptions(); boolean hasCommands = !m_commands.isEmpty(); @@ -783,9 +795,9 @@ public class JCommander { // First line of the usage // String programName = m_programName != null ? m_programName.getDisplayName() : "
          "; - out.append("Usage: " + programName + " [options]"); - if (hasCommands) out.append(" [command] [command options]"); - out.append("\n"); + out.append(indent).append("Usage: " + programName + " [options]"); + if (hasCommands) out.append(indent).append(" [command] [command options]"); +// out.append("\n"); if (m_mainParameterAnnotation != null) { out.append(" " + m_mainParameterAnnotation.description() + "\n"); } @@ -818,18 +830,19 @@ public class JCommander { // // Display all the names and descriptions // - if (sorted.size() > 0) out.append(" Options:\n"); + if (sorted.size() > 0) out.append(indent).append(" Options:\n"); for (ParameterDescription pd : sorted) { int l = pd.getNames().length(); int spaceCount = longestName - l; int start = out.length(); - out.append(" " + out.append(indent).append(" " + (pd.getParameter().required() ? "* " : " ") + pd.getNames() + s(spaceCount)); - int indent = out.length() - start; - wrapDescription(out, indent, pd.getDescription()); + int indentCount = out.length() - start; + wrapDescription(out, indentCount, pd.getDescription()); Object def = pd.getDefault(); - if (def != null) out.append("\n" + spaces(indent + 1)).append("Default: " + def); + if (def != null) out.append("\n" + spaces(indentCount + 1)) + .append("Default: " + def); out.append("\n"); } @@ -840,12 +853,14 @@ public class JCommander { out.append(" Commands:\n"); // The magic value 3 is the number of spaces between the name of the option // and its description - int ln = longestName(m_commands.keySet()) + 3; for (Map.Entry commands : m_commands.entrySet()) { ProgramName progName = commands.getKey(); String dispName = progName.getDisplayName(); - int spaceCount = ln - dispName.length(); - out.append(" " + dispName + s(spaceCount) + getCommandDescription(progName.name) + "\n"); + out.append(indent).append(" " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n"); + + // Options for this command + usage(progName.getName(), out, " "); + out.append("\n"); } } } @@ -1028,7 +1043,7 @@ public class JCommander { throw new ParameterException("Cannot set alias " + alias + " for " + name + " command because it has already been defined for " - + mappedName.name + " command"); + + mappedName.m_name + " command"); } aliasMap.put(alias, progName); } @@ -1038,7 +1053,7 @@ public class JCommander { public Map getCommands() { Map res = Maps.newLinkedHashMap(); for (Map.Entry entry : m_commands.entrySet()) { - res.put(entry.getKey().name, entry.getValue()); + res.put(entry.getKey().m_name, entry.getValue()); } return res; } @@ -1096,24 +1111,24 @@ public class JCommander { } private static final class ProgramName { - private final String name; - private final List aliases; + private final String m_name; + private final List m_aliases; - ProgramName(String name) { - this(name, Collections.emptyList()); + ProgramName(String name, List aliases) { + m_name = name; + m_aliases = aliases; } - ProgramName(String name, List aliases) { - this.name = name; - this.aliases = aliases; + public String getName() { + return m_name; } private String getDisplayName() { StringBuilder sb = new StringBuilder(); - sb.append(name); - if (!aliases.isEmpty()) { + sb.append(m_name); + if (!m_aliases.isEmpty()) { sb.append("("); - Iterator aliasesIt = aliases.iterator(); + Iterator aliasesIt = m_aliases.iterator(); while (aliasesIt.hasNext()) { sb.append(aliasesIt.next()); if (aliasesIt.hasNext()) { @@ -1129,7 +1144,7 @@ public class JCommander { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((m_name == null) ? 0 : m_name.hashCode()); return result; } @@ -1142,10 +1157,10 @@ public class JCommander { if (getClass() != obj.getClass()) return false; ProgramName other = (ProgramName) obj; - if (name == null) { - if (other.name != null) + if (m_name == null) { + if (other.m_name != null) return false; - } else if (!name.equals(other.name)) + } else if (!m_name.equals(other.m_name)) return false; return true; } diff --git a/src/test/java/com/beust/jcommander/command/CommandAliasTest.java b/src/test/java/com/beust/jcommander/command/CommandAliasTest.java index 15d79d4..4eee7f2 100644 --- a/src/test/java/com/beust/jcommander/command/CommandAliasTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandAliasTest.java @@ -139,7 +139,9 @@ public class CommandAliasTest { jc.addCommand("commit", commit, "ci", "cmt"); StringBuilder out = new StringBuilder(); jc.usage(out); - patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 1); + // The usage should display this string twice: one as the command name + // and one after Usage: + patternMatchesTimes("commit\\(ci,cmt\\)", out.toString(), 2); } /** @@ -167,8 +169,7 @@ public class CommandAliasTest { private void patternMatchesTimes(String pattern, String input, int times) { Matcher m = Pattern.compile(pattern).matcher(input); int matches = 0; - while (m.find()) - matches++; + while (m.find()) matches++; Assert.assertEquals(matches, times); } } -- cgit v1.2.3 From 637e2bfe7b9601811ca0d6082a1054cc8fbc3357 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 7 Jul 2011 15:21:39 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.18 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea21119..75ee52c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.18-SNAPSHOT + 1.18 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 2bf65f35304b2402c652052d25fc2f608cb844bf Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 7 Jul 2011 15:21:44 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 75ee52c..a23a704 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.18 + 1.19-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 4f4ea1fb335b79e05f1b24e217d796fdb3e077de Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 14 Jul 2011 11:17:16 -0700 Subject: Fixed: GITHUB-73: descriptionKey was being ignored on main parameters --- CHANGELOG | 7 +++++++ src/main/java/com/beust/jcommander/JCommander.java | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5946d1c..cf51a4f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,12 @@ Current +Current + +Fixed: GITHUB-73: descriptionKey was being ignored on main parameters + +1.18 +2011/07/20 + Added: Default converter factories can be overridden (Scott Clasen) Added: IParameterValidator Added: Don't display "Options:" if none were defined diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 260942f..cd5325e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -798,8 +798,8 @@ public class JCommander { out.append(indent).append("Usage: " + programName + " [options]"); if (hasCommands) out.append(indent).append(" [command] [command options]"); // out.append("\n"); - if (m_mainParameterAnnotation != null) { - out.append(" " + m_mainParameterAnnotation.description() + "\n"); + if (m_mainParameterDescription != null) { + out.append(" " + m_mainParameterDescription.getDescription() + "\n"); } // -- cgit v1.2.3 From a247edde9ad9a1a613262e44405a0e561e80386c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 14 Jul 2011 11:18:36 -0700 Subject: First commit to test the issue just fixed. --- src/test/java/com/beust/jcommander/args/ArgsI18N2New.java | 5 +++++ src/test/resources/MessageBundle_fr_FR.properties | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java b/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java index 1f55306..c760973 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java +++ b/src/test/java/com/beust/jcommander/args/ArgsI18N2New.java @@ -21,9 +21,14 @@ package com.beust.jcommander.args; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; +import java.util.List; + @Parameters(resourceBundle = "MessageBundle") public class ArgsI18N2New { @Parameter(names = "-host", description = "Host", descriptionKey = "host") String hostName; + + @Parameter(descriptionKey = "files") + List files; } diff --git a/src/test/resources/MessageBundle_fr_FR.properties b/src/test/resources/MessageBundle_fr_FR.properties index f3b0144..4ae83a9 100644 --- a/src/test/resources/MessageBundle_fr_FR.properties +++ b/src/test/resources/MessageBundle_fr_FR.properties @@ -16,4 +16,5 @@ # limitations under the License. # -host = Hôte \ No newline at end of file +host = Hôte +files = Les fichiers -- cgit v1.2.3 From 8a3f5625ab132ff8f5d62650cc58455628e51038 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 15 Jul 2011 10:55:52 -0700 Subject: Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 11 ++++++++++- src/main/java/com/beust/jcommander/Parameters.java | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index cf51a4f..1e3d872 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Current Current +Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions Fixed: GITHUB-73: descriptionKey was being ignored on main parameters 1.18 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index cd5325e..3308880 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -766,11 +766,20 @@ public class JCommander { Parameters p = jc.getObjects().get(0).getClass().getAnnotation(Parameters.class); String result = jc.getMainParameterDescription(); - if (p != null) result = p.commandDescription(); + if (p != null) result = getI18nString(p.commandDescriptionKey(), p.commandDescription()); return result; } + /** + * @return The internationalized version of the string if available, otherwise + * return def. + */ + private String getI18nString(String key, String def) { + String s = m_bundle != null ? m_bundle.getString(key) : null; + return s != null ? s : def; + } + /** * Display a the help on System.out. */ diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index cffc030..e25d1f2 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -55,4 +55,9 @@ public @interface Parameters { * description when @{link JCommander#usage} is invoked. */ String commandDescription() default ""; + + /** + * @return the key used to find the command description in the resource bundle. + */ + String commandDescriptionKey() default ""; } -- cgit v1.2.3 From 2ee07bc8765f4873b69423e6185120d176c49a2b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 27 Jul 2011 10:32:36 -0700 Subject: Fixed: "-args=a=b,b=c" was not being parsed correctly (Michael Lancaster) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/JCommanderTest.java | 14 +++++++++++++- src/test/java/com/beust/jcommander/args/ArgsEquals.java | 11 +++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/args/ArgsEquals.java diff --git a/CHANGELOG b/CHANGELOG index 1e3d872..b564e80 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Current Current Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions +Fixed: "-args=a=b,b=c" was not being parsed correctly (Michael Lancaster) Fixed: GITHUB-73: descriptionKey was being ignored on main parameters 1.18 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3308880..af191d7 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -320,7 +320,7 @@ public class JCommander { if (isOption(v1, arg)) { String sep = getSeparatorFor(v1, arg); if (! " ".equals(sep)) { - String[] sp = arg.split("[" + sep + "]"); + String[] sp = arg.split("[" + sep + "]", 2); for (String ssp : sp) { vResult2.add(ssp); } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index e5822ee..124df7c 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -24,6 +24,7 @@ import com.beust.jcommander.args.ArgsArityString; import com.beust.jcommander.args.ArgsBooleanArity; import com.beust.jcommander.args.ArgsBooleanArity0; import com.beust.jcommander.args.ArgsConverter; +import com.beust.jcommander.args.ArgsEquals; import com.beust.jcommander.args.ArgsHelp; import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; @@ -495,9 +496,20 @@ public class JCommanderTest { new JCommander(new Args1(), "@" + f.getAbsolutePath()); } + public void handleEqualSigns() { + ArgsEquals a = new ArgsEquals(); + JCommander jc = new JCommander(a); + jc.parse(new String[] { "-args=a=b,b=c" }); + Assert.assertEquals(a.args, "a=b,b=c"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().validationShouldWorkWithDefaultValues(); + new JCommanderTest().handleEqualSigns(); +// PortsArgs a = new PortsArgs(); +// JCommander jc = new JCommander(a); +// jc.usage(); +// new JCommanderTest().validationShouldWorkWithDefaultValues(); // new JCommanderTest().booleanArity1(); // ArgsLongDescription a = new ArgsLongDescription(); // JCommander jc = new JCommander(a); diff --git a/src/test/java/com/beust/jcommander/args/ArgsEquals.java b/src/test/java/com/beust/jcommander/args/ArgsEquals.java new file mode 100644 index 0000000..016166d --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsEquals.java @@ -0,0 +1,11 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +@Parameters(separators = "=") +public class ArgsEquals { + + @Parameter(names = "-args") + public String args; +} -- cgit v1.2.3 From 54b130ae8ae6a1c455a3290bfd53d26698dc72a6 Mon Sep 17 00:00:00 2001 From: Stevo Slavic Date: Mon, 1 Aug 2011 18:35:18 +0200 Subject: [fix:]Fixes initializing default values --- src/main/java/com/beust/jcommander/JCommander.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index af191d7..c9c1823 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -261,6 +261,10 @@ public class JCommander { for (ParameterDescription pd : m_descriptions.values()) { initializeDefaultValue(pd); } + + for (Map.Entry entry : m_commands.entrySet()) { + entry.getValue().initializeDefaultValues(); + } } } @@ -925,6 +929,10 @@ public class JCommander { */ public void setDefaultProvider(IDefaultProvider defaultProvider) { m_defaultProvider = defaultProvider; + + for (Map.Entry entry : m_commands.entrySet()) { + entry.getValue().setDefaultProvider(defaultProvider); + } } public void addConverterFactory(IStringConverterFactory converterFactory) { @@ -1033,6 +1041,7 @@ public class JCommander { public void addCommand(String name, Object object, String... aliases) { JCommander jc = new JCommander(object); jc.setProgramName(name, aliases); + jc.setDefaultProvider(m_defaultProvider); ProgramName progName = jc.m_programName; m_commands.put(progName, jc); -- cgit v1.2.3 From dce5bdfa910a54978b6192cd32fccddc91bb3604 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 3 Aug 2011 11:04:58 -0700 Subject: Changelog update. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index b564e80..c5c61f7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Current Current Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions +Fixed: defaults for commands were not properly applied (Stevo Slavic) Fixed: "-args=a=b,b=c" was not being parsed correctly (Michael Lancaster) Fixed: GITHUB-73: descriptionKey was being ignored on main parameters -- cgit v1.2.3 From 0282de5011552e652ea8d522f6f73205fa39bdb2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 3 Aug 2011 11:13:08 -0700 Subject: Doc fixes. --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 7be5d96..8386492 100644 --- a/doc/index.html +++ b/doc/index.html @@ -53,7 +53,7 @@ You annotate fields with descriptions of your options:
           import com.beust.jcommander.Parameter;
           
          -public class JCommanderTest {
          +public class JCommanderExample {
             @Parameter
             public List<String> parameters = Lists.newArrayList();
           
          @@ -227,7 +227,7 @@ The factory is straightforward:
           
           
           public class Factory implements IStringConverterFactory {
          -  public Class> getConverter(Class forType) {
          +  public Class<? extends IStringConverter<?>> getConverter(Class forType) {
               if (forType.equals(HostPort.class)) return HostPortConverter.class;
               else return null;
             }
          -- 
          cgit v1.2.3
          
          
          From 23a5f80e74cff03259ba0005fcbaa3d9c6135970 Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Thu, 4 Aug 2011 07:43:55 -0700
          Subject: Doc update
          
          ---
           doc/index.html | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/doc/index.html b/doc/index.html
          index 8386492..37fcaae 100644
          --- a/doc/index.html
          +++ b/doc/index.html
          @@ -71,7 +71,7 @@ public class JCommanderExample {
           and then you simply ask JCommander to parse:
           
           
          -JCommanderTest jct = new JCommanderTest();
          +JCommanderTest jct = new JCommanderExample();
           String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" };
           new JCommander(jct, argv);
           
          -- 
          cgit v1.2.3
          
          
          From f41869dfe757409a5d1ce12f8d96a9569f0367ee Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 8 Aug 2011 12:01:52 -0700
          Subject: Doc fix.
          
          ---
           doc/index.html | 2 +-
           1 file changed, 1 insertion(+), 1 deletion(-)
          
          diff --git a/doc/index.html b/doc/index.html
          index 37fcaae..1cc9a34 100644
          --- a/doc/index.html
          +++ b/doc/index.html
          @@ -71,7 +71,7 @@ public class JCommanderExample {
           and then you simply ask JCommander to parse:
           
           
          -JCommanderTest jct = new JCommanderExample();
          +JCommanderExample jct = new JCommanderExample();
           String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" };
           new JCommander(jct, argv);
           
          -- 
          cgit v1.2.3
          
          
          From 94150e276cbc94c211154bca16f6921a9f1771fd Mon Sep 17 00:00:00 2001
          From: Cedric Beust 
          Date: Mon, 8 Aug 2011 15:12:31 -0700
          Subject: Doc fix.
          
          ---
           doc/index.html | 7 +++----
           1 file changed, 3 insertions(+), 4 deletions(-)
          
          diff --git a/doc/index.html b/doc/index.html
          index 1cc9a34..53a707e 100644
          --- a/doc/index.html
          +++ b/doc/index.html
          @@ -653,8 +653,8 @@ import collection.JavaConversions._
           
           object Main {
             object Args {
          -    // Declared as var because JCommander assigns a new collection; declared
          -    // as java.util.List because that's what JCommander will replace with.
          +    // Declared as var because JCommander assigns a new collection declared
          +    // as java.util.List because that's what JCommander will replace it with.
               // It'd be nice if JCommander would just use the provided List so this
               // could be a val and a Scala LinkedList.
               @Parameter(
          @@ -688,8 +688,7 @@ You can download JCommander from the following locations:
           
           
          • Source on github
          • -
          • Jar file
          • -
          • Or if you are using Maven, add the following dependency to your pom.xml: +
          • If you are using Maven, add the following dependency to your pom.xml:
             
            -- 
            cgit v1.2.3
            
            
            From 876c9776ebe75ca46504847a4807b681ef5d5e4f Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Wed, 17 Aug 2011 11:09:57 -0700
            Subject: Fixed: Fields of type Set (HashSet and SortedSet) are now supported
            
            ---
             CHANGELOG                                                |  1 +
             .../java/com/beust/jcommander/ParameterDescription.java  | 16 +++++++++-------
             src/test/java/com/beust/jcommander/JCommanderTest.java   |  9 +++++++++
             src/test/java/com/beust/jcommander/args/ArgsWithSet.java | 11 +++++++++++
             4 files changed, 30 insertions(+), 7 deletions(-)
             create mode 100644 src/test/java/com/beust/jcommander/args/ArgsWithSet.java
            
            diff --git a/CHANGELOG b/CHANGELOG
            index c5c61f7..4a985d8 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -3,6 +3,7 @@ Current
             Current
             
             Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions
            +Fixed: Fields of type Set (HashSet and SortedSet) are now supported
             Fixed: defaults for commands were not properly applied (Stevo Slavic)
             Fixed: "-args=a=b,b=c" was not being parsed correctly (Michael Lancaster)
             Fixed: GITHUB-73: descriptionKey was being ignored on main parameters
            diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
            index 7b43677..b52c695 100644
            --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
            +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
            @@ -19,16 +19,18 @@
             package com.beust.jcommander;
             
             
            -import com.beust.jcommander.internal.Lists;
            -import com.beust.jcommander.internal.Sets;
             import com.beust.jcommander.validators.NoValidator;
             
             import java.lang.reflect.Field;
            +import java.util.ArrayList;
             import java.util.Collection;
            +import java.util.LinkedHashSet;
             import java.util.List;
             import java.util.Locale;
             import java.util.ResourceBundle;
             import java.util.Set;
            +import java.util.SortedSet;
            +import java.util.TreeSet;
             
             public class ParameterDescription {
               private Object m_object;
            @@ -237,12 +239,12 @@ public class ParameterDescription {
                * Currently only List and Set are supported. Support for
                * Queues and Stacks could be useful.
                */
            +  @SuppressWarnings("unchecked")
               private Collection newCollection(Class type) {
            -    if(List.class.isAssignableFrom(type)){
            -      return Lists.newArrayList();
            -    } else if(Set.class.isAssignableFrom(type)){
            -      return Sets.newLinkedHashSet();
            -    } else {
            +    if (SortedSet.class.isAssignableFrom(type)) return new TreeSet();
            +    else if (LinkedHashSet.class.isAssignableFrom(type)) return new LinkedHashSet();
            +    else if (List.class.isAssignableFrom(type)) return new ArrayList();
            +    else {
                   throw new ParameterException("Parameters of Collection type '" + type.getSimpleName()
                                               + "' are not supported. Please use List or Set instead.");
                 }
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 124df7c..87d0626 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -39,6 +39,7 @@ import com.beust.jcommander.args.ArgsRequired;
             import com.beust.jcommander.args.ArgsSlave;
             import com.beust.jcommander.args.ArgsSlaveBogus;
             import com.beust.jcommander.args.ArgsValidate1;
            +import com.beust.jcommander.args.ArgsWithSet;
             import com.beust.jcommander.args.Arity1;
             import com.beust.jcommander.args.SeparatorColon;
             import com.beust.jcommander.args.SeparatorEqual;
            @@ -62,6 +63,7 @@ import java.util.List;
             import java.util.Locale;
             import java.util.Map;
             import java.util.ResourceBundle;
            +import java.util.TreeSet;
             
             @Test
             public class JCommanderTest {
            @@ -503,6 +505,13 @@ public class JCommanderTest {
                 Assert.assertEquals(a.args, "a=b,b=c");
               }
             
            +  @SuppressWarnings("serial")
            +  public void handleSets() {
            +    ArgsWithSet a = new ArgsWithSet();
            +    new JCommander(a, new String[] { "-s", "3,1,2" });
            +    Assert.assertEquals(a.set, new TreeSet() {{ add(1); add(2); add(3); }});
            +  }
            +
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
                 new JCommanderTest().handleEqualSigns();
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsWithSet.java b/src/test/java/com/beust/jcommander/args/ArgsWithSet.java
            new file mode 100644
            index 0000000..1e41cd3
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/args/ArgsWithSet.java
            @@ -0,0 +1,11 @@
            +package com.beust.jcommander.args;
            +
            +import com.beust.jcommander.Parameter;
            +import com.beust.jcommander.SetConverter;
            +
            +import java.util.SortedSet;
            +
            +public class ArgsWithSet {
            +  @Parameter(names = "-s", converter = SetConverter.class)
            +  public SortedSet set;
            +}
            \ No newline at end of file
            -- 
            cgit v1.2.3
            
            
            From f2430d09b28ed192a4e0f637e264a19d7604d8ba Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Wed, 17 Aug 2011 14:10:51 -0700
            Subject: Forgot a class.
            
            ---
             src/test/java/com/beust/jcommander/SetConverter.java | 16 ++++++++++++++++
             1 file changed, 16 insertions(+)
             create mode 100644 src/test/java/com/beust/jcommander/SetConverter.java
            
            diff --git a/src/test/java/com/beust/jcommander/SetConverter.java b/src/test/java/com/beust/jcommander/SetConverter.java
            new file mode 100644
            index 0000000..c19df11
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/SetConverter.java
            @@ -0,0 +1,16 @@
            +package com.beust.jcommander;
            +
            +import java.util.SortedSet;
            +import java.util.TreeSet;
            +
            +public class SetConverter implements IStringConverter> {
            + 
            +  public SortedSet convert(String value) {
            +    SortedSet set = new TreeSet();
            +    String[] values = value.split(",");
            +    for (String num : values) {
            +      set.add(Integer.parseInt(num));
            +    }
            +    return set;
            +  }
            +}
            -- 
            cgit v1.2.3
            
            
            From 8ce1ca7ee017b4ab886879cc4c0dd878fdbff2f9 Mon Sep 17 00:00:00 2001
            From: Alex Cornejo 
            Date: Tue, 30 Aug 2011 16:42:26 -0400
            Subject: Added support for floats and doubles.
            
            These types are essential for almost any scientific application, I was
            shocked to find they were not already supported.
            ---
             .../com/beust/jcommander/ParameterDescription.java | 10 +++++-
             .../jcommander/converters/DoubleConverter.java     | 42 ++++++++++++++++++++++
             .../jcommander/converters/FloatConverter.java      | 42 ++++++++++++++++++++++
             .../internal/DefaultConverterFactory.java          |  8 ++++-
             4 files changed, 100 insertions(+), 2 deletions(-)
             create mode 100644 src/main/java/com/beust/jcommander/converters/DoubleConverter.java
             create mode 100644 src/main/java/com/beust/jcommander/converters/FloatConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
            index b52c695..e8ac3d5 100644
            --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
            +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
            @@ -261,7 +261,15 @@ public class ParameterDescription {
               public boolean isNumber() {
                 Class type = m_field.getType();
                 return type.equals(Integer.class) || type.equals(int.class)
            -        || type.equals(Long.class) || type.equals(long.class);
            +        || type.equals(Long.class) || type.equals(long.class)
            +        || type.equals(Float.class) || type.equals(float.class)
            +        || type.equals(Double.class) || type.equals(double.class);
            +  }
            +
            +  public boolean isFractional() {
            +      Class type = m_field.getType();
            +      return type.equals(Float.class) || type.equals(float.class)
            +          || type.equals(Double.class) || type.equals(double.class);
               }
             
               private void p(String string) {
            diff --git a/src/main/java/com/beust/jcommander/converters/DoubleConverter.java b/src/main/java/com/beust/jcommander/converters/DoubleConverter.java
            new file mode 100644
            index 0000000..0c36c68
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/DoubleConverter.java
            @@ -0,0 +1,42 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +
            +/**
            + * Convert a string to a double.
            + *
            + * @author acornejo
            + */
            +public class DoubleConverter extends BaseConverter {
            +
            +  public DoubleConverter(String optionName) {
            +    super(optionName);
            +  }
            +
            +  public Double convert(String value) {
            +    try {
            +      return Double.parseDouble(value);
            +    } catch(NumberFormatException ex) {
            +      throw new ParameterException(getErrorString(value, "a double"));
            +    }
            +  }
            +
            +}
            diff --git a/src/main/java/com/beust/jcommander/converters/FloatConverter.java b/src/main/java/com/beust/jcommander/converters/FloatConverter.java
            new file mode 100644
            index 0000000..2e2eff8
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/FloatConverter.java
            @@ -0,0 +1,42 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +
            +/**
            + * Convert a string to a float.
            + *
            + * @author acornejo
            + */
            +public class FloatConverter extends BaseConverter {
            +
            +  public FloatConverter(String optionName) {
            +    super(optionName);
            +  }
            +
            +  public Float convert(String value) {
            +    try {
            +      return Float.parseFloat(value);
            +    } catch(NumberFormatException ex) {
            +      throw new ParameterException(getErrorString(value, "a float"));
            +    }
            +  }
            +
            +}
            diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            index bbe0cd1..26ab0fc 100644
            --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            @@ -24,6 +24,8 @@ import com.beust.jcommander.converters.BooleanConverter;
             import com.beust.jcommander.converters.FileConverter;
             import com.beust.jcommander.converters.IntegerConverter;
             import com.beust.jcommander.converters.LongConverter;
            +import com.beust.jcommander.converters.FloatConverter;
            +import com.beust.jcommander.converters.DoubleConverter;
             import com.beust.jcommander.converters.StringConverter;
             
             import java.io.File;
            @@ -34,7 +36,7 @@ public class DefaultConverterFactory implements IStringConverterFactory {
                * A map of converters per class.
                */
               private static Map>> m_classConverters;
            -  
            +
               static {
                 m_classConverters = Maps.newHashMap();
                 m_classConverters.put(String.class, StringConverter.class);
            @@ -42,6 +44,10 @@ public class DefaultConverterFactory implements IStringConverterFactory {
                 m_classConverters.put(int.class, IntegerConverter.class);
                 m_classConverters.put(Long.class, LongConverter.class);
                 m_classConverters.put(long.class, LongConverter.class);
            +    m_classConverters.put(Float.class, FloatConverter.class);
            +    m_classConverters.put(float.class, FloatConverter.class);
            +    m_classConverters.put(Double.class, DoubleConverter.class);
            +    m_classConverters.put(double.class, DoubleConverter.class);
                 m_classConverters.put(Boolean.class, BooleanConverter.class);
                 m_classConverters.put(boolean.class, BooleanConverter.class);
                 m_classConverters.put(File.class, FileConverter.class);
            -- 
            cgit v1.2.3
            
            
            From ee74c7bf2ea0f7b17093650fdd78b0f8ffa343b9 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Fri, 2 Sep 2011 10:13:11 -0700
            Subject: Fixed silly setter mistake.
            
            ---
             src/main/java/com/beust/jcommander/ParameterDescription.java | 6 +++---
             1 file changed, 3 insertions(+), 3 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
            index b52c695..0137f43 100644
            --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
            +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
            @@ -19,8 +19,6 @@
             package com.beust.jcommander;
             
             
            -import com.beust.jcommander.validators.NoValidator;
            -
             import java.lang.reflect.Field;
             import java.util.ArrayList;
             import java.util.Collection;
            @@ -32,6 +30,8 @@ import java.util.Set;
             import java.util.SortedSet;
             import java.util.TreeSet;
             
            +import com.beust.jcommander.validators.NoValidator;
            +
             public class ParameterDescription {
               private Object m_object;
               private Parameter m_parameterAnnotation;
            @@ -170,7 +170,7 @@ public class ParameterDescription {
             
             
               public void setAssigned(boolean b) {
            -    m_assigned = true;
            +    m_assigned = b;
               }
             
               /**
            -- 
            cgit v1.2.3
            
            
            From 6898c0e774eedf077b243e65a40cbcabcb70c6fa Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Fri, 2 Sep 2011 10:44:40 -0700
            Subject: Bumped testng version.
            
            ---
             build-with-maven | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/build-with-maven b/build-with-maven
            index 3ae2808..1e2c586 100755
            --- a/build-with-maven
            +++ b/build-with-maven
            @@ -1,6 +1,6 @@
             mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign
             
            -v=6.1.2beta
            +v=6.3beta
             export TESTNG=../testng/target/testng-${v}.jar
             
             java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
            -- 
            cgit v1.2.3
            
            
            From d9edcaec709764312eea63f825308e2ae4ddaddd Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Fri, 2 Sep 2011 10:44:53 -0700
            Subject: Minor collection fixes.
            
            ---
             .../java/com/beust/jcommander/ParameterDescription.java  | 16 ++--------------
             1 file changed, 2 insertions(+), 14 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
            index 47e3cd7..5b674ca 100644
            --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
            +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
            @@ -22,6 +22,7 @@ package com.beust.jcommander;
             import java.lang.reflect.Field;
             import java.util.ArrayList;
             import java.util.Collection;
            +import java.util.HashSet;
             import java.util.LinkedHashSet;
             import java.util.List;
             import java.util.Locale;
            @@ -243,6 +244,7 @@ public class ParameterDescription {
               private Collection newCollection(Class type) {
                 if (SortedSet.class.isAssignableFrom(type)) return new TreeSet();
                 else if (LinkedHashSet.class.isAssignableFrom(type)) return new LinkedHashSet();
            +    else if (Set.class.isAssignableFrom(type)) return new HashSet();
                 else if (List.class.isAssignableFrom(type)) return new ArrayList();
                 else {
                   throw new ParameterException("Parameters of Collection type '" + type.getSimpleName()
            @@ -258,20 +260,6 @@ public class ParameterDescription {
                 return (!isDefault && !m_assigned);
               }
             
            -  public boolean isNumber() {
            -    Class type = m_field.getType();
            -    return type.equals(Integer.class) || type.equals(int.class)
            -        || type.equals(Long.class) || type.equals(long.class)
            -        || type.equals(Float.class) || type.equals(float.class)
            -        || type.equals(Double.class) || type.equals(double.class);
            -  }
            -
            -  public boolean isFractional() {
            -      Class type = m_field.getType();
            -      return type.equals(Float.class) || type.equals(float.class)
            -          || type.equals(Double.class) || type.equals(double.class);
            -  }
            -
               private void p(String string) {
                 if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) {
                   System.out.println("[ParameterDescription] " + string);
            -- 
            cgit v1.2.3
            
            
            From 36e3614a3ebf663c723e94f30b873194d33a29d1 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Fri, 2 Sep 2011 10:45:48 -0700
            Subject: Added float/double tests.
            
            ---
             src/test/java/com/beust/jcommander/JCommanderTest.java |  9 ++++++---
             src/test/java/com/beust/jcommander/args/Args1.java     | 10 ++++++++--
             2 files changed, 14 insertions(+), 5 deletions(-)
            
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 87d0626..5e1dc75 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -69,13 +69,16 @@ import java.util.TreeSet;
             public class JCommanderTest {
               public void simpleArgs() {
                 Args1 args = new Args1();
            -    String[] argv = { "-debug", "-log", "2", "-groups", "unit", "a", "b", "c" };
            +    String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3",
            +            "-groups", "unit", "a", "b", "c" };
                 new JCommander(args, argv);
             
                 Assert.assertTrue(args.debug);
                 Assert.assertEquals(args.verbose.intValue(), 2);
                 Assert.assertEquals(args.groups, "unit");
                 Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c"));
            +    Assert.assertEquals(args.floa, 1.2f, 0.1f);
            +    Assert.assertEquals(args.doub, 1.3f, 0.1f);
               }
             
               /**
            @@ -86,7 +89,7 @@ public class JCommanderTest {
                 Args1 args = new Args1();
                 String[] argv = { "-log", "2" };
                 JCommander jc = new JCommander(args, argv);
            -    Assert.assertEquals(jc.getParameters().size(), 4);
            +    Assert.assertEquals(jc.getParameters().size(), 6);
               }
             
               /**
            @@ -514,7 +517,7 @@ public class JCommanderTest {
             
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    new JCommanderTest().handleEqualSigns();
            +    new JCommanderTest().repeatedArgs();
             //    PortsArgs a = new PortsArgs();
             //    JCommander jc = new JCommander(a);
             //    jc.usage();
            diff --git a/src/test/java/com/beust/jcommander/args/Args1.java b/src/test/java/com/beust/jcommander/args/Args1.java
            index 5d5b1b0..cca53d8 100644
            --- a/src/test/java/com/beust/jcommander/args/Args1.java
            +++ b/src/test/java/com/beust/jcommander/args/Args1.java
            @@ -18,11 +18,11 @@
             
             package com.beust.jcommander.args;
             
            -import com.beust.jcommander.Parameter;
            +import java.util.List;
             
             import org.testng.collections.Lists;
             
            -import java.util.List;
            +import com.beust.jcommander.Parameter;
             
             public class Args1 {
               @Parameter
            @@ -39,4 +39,10 @@ public class Args1 {
             
               @Parameter(names = "-long", description = "A long number")
               public long l;
            +
            +  @Parameter(names = "-double", description = "A double number")
            +  public double doub;
            +
            +  @Parameter(names = "-float", description = "A float number")
            +  public float floa;
             }
            -- 
            cgit v1.2.3
            
            
            From d2a567ff013254ee00b600d0eb298770d35b089f Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Mon, 3 Oct 2011 06:04:41 -0700
            Subject: Issue 80: missing new line when no main parameter is present.
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java | 6 +++---
             1 file changed, 3 insertions(+), 3 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index c9c1823..0ae4e85 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -41,8 +41,8 @@ import java.util.Collection;
             import java.util.Collections;
             import java.util.Comparator;
             import java.util.Iterator;
            -import java.util.List;
             import java.util.LinkedList;
            +import java.util.List;
             import java.util.Map;
             import java.util.ResourceBundle;
             
            @@ -812,7 +812,7 @@ public class JCommander {
                 if (hasCommands) out.append(indent).append(" [command] [command options]");
             //    out.append("\n");
                 if (m_mainParameterDescription != null) {
            -      out.append(" " + m_mainParameterDescription.getDescription() + "\n");
            +      out.append(" " + m_mainParameterDescription.getDescription());
                 }
             
                 //
            @@ -843,7 +843,7 @@ public class JCommander {
                 //
                 // Display all the names and descriptions
                 //
            -    if (sorted.size() > 0) out.append(indent).append("  Options:\n");
            +    if (sorted.size() > 0) out.append(indent).append("\n  Options:\n");
                 for (ParameterDescription pd : sorted) {
                   int l = pd.getNames().length();
                   int spaceCount = longestName - l;
            -- 
            cgit v1.2.3
            
            
            From c709e6db81d11fe4aa6c573775ba5577902aa35c Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Mon, 3 Oct 2011 06:53:22 -0700
            Subject: Implemented variable arities.
            
            ---
             .../java/com/beust/jcommander/IVariableArity.java  |  16 ++++
             src/main/java/com/beust/jcommander/JCommander.java | 103 ++++++++++++++-------
             src/main/java/com/beust/jcommander/Parameter.java  |   5 +
             .../java/com/beust/jcommander/JCommanderTest.java  |  29 +++++-
             .../com/beust/jcommander/args/VariableArity.java   |  29 ++++++
             5 files changed, 146 insertions(+), 36 deletions(-)
             create mode 100644 src/main/java/com/beust/jcommander/IVariableArity.java
             create mode 100644 src/test/java/com/beust/jcommander/args/VariableArity.java
            
            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 {
            @@ -623,6 +603,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 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 validateWith() default NoValidator.class;
            +
            +  /**
            +   * @return true if this parameter has a variable arity. See @{IVariableArity}
            +   */
            +  boolean variableArity() default false;
             }
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 5e1dc75..2b5fee2 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -45,6 +45,7 @@ import com.beust.jcommander.args.SeparatorColon;
             import com.beust.jcommander.args.SeparatorEqual;
             import com.beust.jcommander.args.SeparatorMixed;
             import com.beust.jcommander.args.SlashSeparator;
            +import com.beust.jcommander.args.VariableArity;
             import com.beust.jcommander.command.CommandAdd;
             import com.beust.jcommander.command.CommandCommit;
             import com.beust.jcommander.command.CommandMain;
            @@ -515,9 +516,35 @@ public class JCommanderTest {
                 Assert.assertEquals(a.set, new TreeSet() {{ add(1); add(2); add(3); }});
               }
             
            +  private static final List V = Arrays.asList("a", "b", "c", "d");
            +
            +  @DataProvider
            +  public Object[][] variable() {
            +    return new Object[][] {
            +        new Object[] { 0, V.subList(0, 0), V },
            +        new Object[] { 1, V.subList(0, 1), V.subList(1, 4) },
            +        new Object[] { 2, V.subList(0, 2), V.subList(2, 4) },
            +        new Object[] { 3, V.subList(0, 3), V.subList(3, 4) },
            +        new Object[] { 4, V.subList(0, 4), V.subList(4, 4) },
            +    };
            +  }
            +
            +  @Test(dataProvider = "variable")
            +  public void variableArity(int count, List var, List main) {
            +    VariableArity va = new VariableArity(count);
            +    new JCommander(va).parse("-variable", "a", "b", "c", "d");
            +    Assert.assertEquals(var, va.var);
            +    Assert.assertEquals(main, va.main);
            +  }
            +
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    new JCommanderTest().repeatedArgs();
            +    for (int i = 0; i < 5; i++) {
            +      VariableArity va = new VariableArity(i);
            +      new JCommander(va).parse("-variable", "a", "b", "c", "d");
            +      System.out.println(va.var + " *** " + va.main);
            +    }
            +//    new JCommanderTest().repeatedArgs();
             //    PortsArgs a = new PortsArgs();
             //    JCommander jc = new JCommander(a);
             //    jc.usage();
            diff --git a/src/test/java/com/beust/jcommander/args/VariableArity.java b/src/test/java/com/beust/jcommander/args/VariableArity.java
            new file mode 100644
            index 0000000..19611e4
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/args/VariableArity.java
            @@ -0,0 +1,29 @@
            +package com.beust.jcommander.args;
            +
            +import com.beust.jcommander.IVariableArity;
            +import com.beust.jcommander.Parameter;
            +
            +import java.util.ArrayList;
            +import java.util.List;
            +
            +public class VariableArity implements IVariableArity {
            +
            +  private int m_count;
            +
            +  public VariableArity(int count) {
            +    m_count = count;
            +  }
            +
            +  @Parameter
            +  public List main = new ArrayList();
            +
            +  @Parameter(names = "-variable", variableArity = true)
            +  public List var = new ArrayList();
            +
            +  public int processVariableArity(String optionName, String[] options) {
            +    for (int i = 0; i < m_count; i++) {
            +      var.add(options[i]);
            +    }
            +    return m_count;
            +  }
            +}
            -- 
            cgit v1.2.3
            
            
            From cbdb7070bd2101febc1b08b8cb5d26c54e150a74 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Wed, 5 Oct 2011 23:14:20 -0700
            Subject: Added: JCommander#setParameterDescriptionComparator for better
             control over usage().
            
            ---
             CHANGELOG                                          |  1 +
             src/main/java/com/beust/jcommander/JCommander.java | 21 ++++++++++++++++-----
             2 files changed, 17 insertions(+), 5 deletions(-)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index 4a985d8..8c7b2d9 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -3,6 +3,7 @@ Current
             Current
             
             Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions
            +Added: JCommander#setParameterDescriptionComparator for better control over usage()
             Fixed: Fields of type Set (HashSet and SortedSet) are now supported
             Fixed: defaults for commands were not properly applied (Stevo Slavic)
             Fixed: "-args=a=b,b=c" was not being parsed correctly (Michael Lancaster)
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 5735814..b9a93fa 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -135,6 +135,13 @@ public class JCommander {
             
               private ProgramName m_programName;
             
            +  private Comparator m_parameterDescriptionComparator
            +      = new Comparator() {
            +        public int compare(ParameterDescription p0, ParameterDescription p1) {
            +          return p0.getLongestName().compareTo(p1.getLongestName());
            +        }
            +      };
            +
               /**
                * The factories used to look up string converters.
                */
            @@ -867,11 +874,7 @@ public class JCommander {
                 //
                 // Sort the options
                 //
            -    Collections.sort(sorted, new Comparator() {
            -      public int compare(ParameterDescription p0, ParameterDescription p1) {
            -        return p0.getLongestName().compareTo(p1.getLongestName());
            -      }
            -    });
            +    Collections.sort(sorted, getParameterDescriptionComparator());
             
                 //
                 // Display all the names and descriptions
            @@ -911,6 +914,14 @@ public class JCommander {
                 }
               }
             
            +  private Comparator getParameterDescriptionComparator() {
            +    return m_parameterDescriptionComparator;
            +  }
            +
            +  public void setParameterDescriptionComparator(Comparator c) {
            +    m_parameterDescriptionComparator = c;
            +  }
            +
               private void wrapDescription(StringBuilder out, int indent, String description) {
                 int max = 79;
                 String[] words = description.split(" ");
            -- 
            cgit v1.2.3
            
            
            From 1866ef23a7c264e009f7efbef17aa39e9007db29 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Wed, 5 Oct 2011 23:14:29 -0700
            Subject: Build.
            
            ---
             build-with-maven | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/build-with-maven b/build-with-maven
            index 1e2c586..12337d6 100755
            --- a/build-with-maven
            +++ b/build-with-maven
            @@ -1,6 +1,6 @@
             mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign
             
            -v=6.3beta
            +v=6.2.2beta
             export TESTNG=../testng/target/testng-${v}.jar
             
             java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
            -- 
            cgit v1.2.3
            
            
            From 102fba6b0eeafc324b8c7943657382f476d8ad43 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Wed, 5 Oct 2011 23:16:21 -0700
            Subject: Testing the new comparator.
            
            ---
             .../java/com/beust/jcommander/JCommanderTest.java     | 19 ++++++++++++++-----
             1 file changed, 14 insertions(+), 5 deletions(-)
            
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 2b5fee2..2a3fa0b 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -59,6 +59,7 @@ import java.io.FileWriter;
             import java.io.IOException;
             import java.util.ArrayList;
             import java.util.Arrays;
            +import java.util.Comparator;
             import java.util.Iterator;
             import java.util.List;
             import java.util.Locale;
            @@ -539,11 +540,19 @@ public class JCommanderTest {
             
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    for (int i = 0; i < 5; i++) {
            -      VariableArity va = new VariableArity(i);
            -      new JCommander(va).parse("-variable", "a", "b", "c", "d");
            -      System.out.println(va.var + " *** " + va.main);
            -    }
            +    JCommander j = new JCommander(new Args1());
            +    j.setParameterDescriptionComparator(
            +        new Comparator() {
            +          public int compare(ParameterDescription p0, ParameterDescription p1) {
            +            return p1.getLongestName().length() - p0.getLongestName().length();
            +          }
            +        });
            +    j.usage();
            +//    for (int i = 0; i < 5; i++) {
            +//      VariableArity va = new VariableArity(i);
            +//      new JCommander(va).parse("-variable", "a", "b", "c", "d");
            +//      System.out.println(va.var + " *** " + va.main);
            +//    }
             //    new JCommanderTest().repeatedArgs();
             //    PortsArgs a = new PortsArgs();
             //    JCommander jc = new JCommander(a);
            -- 
            cgit v1.2.3
            
            
            From b4b91aac90dc66600cdfee0ca5c5af2d7db7c7f6 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Sun, 16 Oct 2011 13:35:10 -0700
            Subject: [maven-release-plugin] prepare release jcommander-1.19
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index a23a704..d3691b6 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.19-SNAPSHOT
            +  1.19
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 5ea65e5e81846d3a29b76c52c326c3cad1d45bd2 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Sun, 16 Oct 2011 13:35:16 -0700
            Subject: [maven-release-plugin] prepare for next development iteration
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index d3691b6..8f0f96d 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.19
            +  1.20-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 886538c8c4ae9df170c91706634b648916c7f84d Mon Sep 17 00:00:00 2001
            From: Adrian Muraru 
            Date: Thu, 20 Oct 2011 04:53:43 +0300
            Subject: Added support for parameters defined as enum types
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java | 26 +++++++++++++++++-----
             1 file changed, 21 insertions(+), 5 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index b9a93fa..d374a6f 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -40,6 +40,7 @@ import java.util.Arrays;
             import java.util.Collection;
             import java.util.Collections;
             import java.util.Comparator;
            +import java.util.EnumSet;
             import java.util.Iterator;
             import java.util.LinkedList;
             import java.util.List;
            @@ -543,7 +544,7 @@ public class JCommander {
                           // 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)
            @@ -1008,8 +1009,14 @@ public class JCommander {
                 //
                 // Try to find a converter on the annotation
                 //
            -    if (converterClass == null || converterClass == NoConverter.class) {
            -      converterClass = findConverter(type);
            +    if ( converterClass == null || converterClass == NoConverter.class) {
            +      // If no converter specified and type is enum, used enum values to convert
            +      if (type.isEnum()){
            +        converterClass = type;
            +      } else {
            +        converterClass = findConverter(type);
            +      }
            +
                 }
                 if (converterClass == null) {
                   converterClass = StringConverter.class;
            @@ -1035,8 +1042,17 @@ public class JCommander {
                 try {
                   String[] names = annotation.names();
                   String optionName = names.length > 0 ? names[0] : "[Main class]";
            -      converter = instantiateConverter(optionName, converterClass);
            -      result = converter.convert(value);
            +      if (converterClass.isEnum()) {
            +        try {
            +          result = Enum.valueOf((Class) converterClass, value.toUpperCase());
            +        } catch (Exception e) {
            +          throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" +
            +                                       EnumSet.allOf((Class) converterClass));
            +        }
            +      } else {
            +        converter = instantiateConverter(optionName, converterClass);
            +        result = converter.convert(value);
            +      }
                 } catch (InstantiationException e) {
                   throw new ParameterException(e);
                 } catch (IllegalAccessException e) {
            -- 
            cgit v1.2.3
            
            
            From 0638723e74c48bf8960f1401d0c5d99f9b1292b0 Mon Sep 17 00:00:00 2001
            From: Adrian Muraru 
            Date: Thu, 20 Oct 2011 18:57:05 +0300
            Subject: Added tests for EnumArgs
            
            ---
             pom.xml                                            |  6 +++
             .../java/com/beust/jcommander/JCommanderTest.java  | 18 ++++++++-
             .../java/com/beust/jcommander/args/ArgsEnum.java   | 46 ++++++++++++++++++++++
             3 files changed, 69 insertions(+), 1 deletion(-)
             create mode 100644 src/test/java/com/beust/jcommander/args/ArgsEnum.java
            
            diff --git a/pom.xml b/pom.xml
            index 8f0f96d..4091c93 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -164,6 +164,12 @@
               		6.1.1
               		jar
               		test
            +        
            +            
            +                jcommander
            +                com.beust
            +            
            +        
               	
               
             
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 2a3fa0b..4935e5e 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -24,6 +24,7 @@ import com.beust.jcommander.args.ArgsArityString;
             import com.beust.jcommander.args.ArgsBooleanArity;
             import com.beust.jcommander.args.ArgsBooleanArity0;
             import com.beust.jcommander.args.ArgsConverter;
            +import com.beust.jcommander.args.ArgsEnum;
             import com.beust.jcommander.args.ArgsEquals;
             import com.beust.jcommander.args.ArgsHelp;
             import com.beust.jcommander.args.ArgsI18N1;
            @@ -123,7 +124,7 @@ public class JCommanderTest {
                 new JCommander(args, argv);
                 Assert.assertEquals(args.verbose.intValue(), 2);
               }
            -  
            +
               public void multipleNames1() {
                 multipleNames("-log");
               }
            @@ -538,6 +539,21 @@ public class JCommanderTest {
                 Assert.assertEquals(main, va.main);
               }
             
            +  public void enumArgs() {
            +    ArgsEnum args = new ArgsEnum();
            +    String[] argv = { "-choice", "ONE"};
            +    new JCommander(args, argv);
            +
            +    Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE);
            +  }
            +
            +  @Test(expectedExceptions = ParameterException.class)
            +  public void enumArgsFail() {
            +    ArgsEnum args = new ArgsEnum();
            +    String[] argv = { "-choice", "A" };
            +    new JCommander(args, argv);
            +  }
            +
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
                 JCommander j = new JCommander(new Args1());
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsEnum.java b/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            new file mode 100644
            index 0000000..f7db7e5
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            @@ -0,0 +1,46 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.args;
            +
            +import com.beust.jcommander.JCommander;
            +import com.beust.jcommander.Parameter;
            +
            +import org.testng.Assert;
            +
            +/**
            + * Test parameter arity.
            + *
            + * @author cbeust
            + */
            +public class ArgsEnum {
            +
            +  public enum ChoiceType { ONE, TWO, THREE };
            +  @Parameter(names = "-choice", description = "Choice parameter")
            +  public ChoiceType choice = ChoiceType.ONE;
            +
            +  public static void main(String[] args) {
            +      ArgsEnum earg = new ArgsEnum();
            +      String[] argv = { "-choice", "ONE"};
            +      new JCommander(earg, argv);
            +      Assert.assertEquals(earg.choice, ArgsEnum.ChoiceType.ONE);
            +  }
            +
            +}
            +
            +
            -- 
            cgit v1.2.3
            
            
            From f2af8149400676221cc155567d6a41b65bec13d1 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Sun, 23 Oct 2011 12:02:09 -0700
            Subject: Added: Support for enums (Adrian Muraru).
            
            Fixed a few minor thins on top of Adrian's patch.
            ---
             CHANGELOG                                             |  4 ++++
             src/test/java/com/beust/jcommander/args/ArgsEnum.java | 14 ++------------
             2 files changed, 6 insertions(+), 12 deletions(-)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index 8c7b2d9..75b9232 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -2,6 +2,10 @@ Current
             
             Current
             
            +Added: Support for enums (Adrian Muraru)
            +
            +1.19
            +2011/10/10
             Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions
             Added: JCommander#setParameterDescriptionComparator for better control over usage()
             Fixed: Fields of type Set (HashSet and SortedSet) are now supported
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsEnum.java b/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            index f7db7e5..1d886e2 100644
            --- a/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            +++ b/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            @@ -18,15 +18,12 @@
             
             package com.beust.jcommander.args;
             
            -import com.beust.jcommander.JCommander;
             import com.beust.jcommander.Parameter;
             
            -import org.testng.Assert;
            -
             /**
            - * Test parameter arity.
            + * Test enums.
              *
            - * @author cbeust
            + * @author Adrian Muraru
              */
             public class ArgsEnum {
             
            @@ -34,13 +31,6 @@ public class ArgsEnum {
               @Parameter(names = "-choice", description = "Choice parameter")
               public ChoiceType choice = ChoiceType.ONE;
             
            -  public static void main(String[] args) {
            -      ArgsEnum earg = new ArgsEnum();
            -      String[] argv = { "-choice", "ONE"};
            -      new JCommander(earg, argv);
            -      Assert.assertEquals(earg.choice, ArgsEnum.ChoiceType.ONE);
            -  }
            -
             }
             
             
            -- 
            cgit v1.2.3
            
            
            From 25aab24d37d3b9374ae113c5840f541ffa63b033 Mon Sep 17 00:00:00 2001
            From: =?UTF-8?q?C=C3=A9dric=20Beust?= 
            Date: Sun, 23 Oct 2011 12:02:17 -0700
            Subject: Updated to TestNG 6.3.
            
            ---
             build-with-maven | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/build-with-maven b/build-with-maven
            index 12337d6..001ed3d 100755
            --- a/build-with-maven
            +++ b/build-with-maven
            @@ -1,6 +1,6 @@
             mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign
             
            -v=6.2.2beta
            +v=6.3
             export TESTNG=../testng/target/testng-${v}.jar
             
             java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
            -- 
            cgit v1.2.3
            
            
            From 041bdac9067d4ce9c936ff1c0ae3856f2e240f15 Mon Sep 17 00:00:00 2001
            From: Angus 
            Date: Wed, 26 Oct 2011 00:22:53 +0100
            Subject: Added support for BigDecimal arguments and related test.
            
            ---
             .../jcommander/converters/BigDecimalConverter.java | 43 ++++++++++++++++++++++
             .../internal/DefaultConverterFactory.java          |  3 ++
             .../java/com/beust/jcommander/JCommanderTest.java  |  6 ++-
             src/test/java/com/beust/jcommander/args/Args1.java |  4 ++
             4 files changed, 54 insertions(+), 2 deletions(-)
             create mode 100644 src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java b/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java
            new file mode 100644
            index 0000000..cd256a4
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java
            @@ -0,0 +1,43 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +import java.math.BigDecimal;
            +
            +/**
            + * Converts a String to a BigDecimal.
            + *
            + * @author angus
            + */
            +public class BigDecimalConverter extends BaseConverter {
            +
            +  public BigDecimalConverter(String optionName) {
            +    super(optionName);
            +  }
            +
            +  @Override
            +  public BigDecimal convert(String value) {
            +    try {
            +      return new BigDecimal(value);
            +    } catch (NumberFormatException nfe) {
            +      throw new ParameterException(getErrorString(value, "a BigDecimal"));
            +    }
            +  }
            +}
            diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            index 26ab0fc..e622722 100644
            --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            @@ -27,8 +27,10 @@ import com.beust.jcommander.converters.LongConverter;
             import com.beust.jcommander.converters.FloatConverter;
             import com.beust.jcommander.converters.DoubleConverter;
             import com.beust.jcommander.converters.StringConverter;
            +import com.beust.jcommander.converters.BigDecimalConverter;
             
             import java.io.File;
            +import java.math.BigDecimal;
             import java.util.Map;
             
             public class DefaultConverterFactory implements IStringConverterFactory {
            @@ -51,6 +53,7 @@ public class DefaultConverterFactory implements IStringConverterFactory {
                 m_classConverters.put(Boolean.class, BooleanConverter.class);
                 m_classConverters.put(boolean.class, BooleanConverter.class);
                 m_classConverters.put(File.class, FileConverter.class);
            +    m_classConverters.put(BigDecimal.class, BigDecimalConverter.class);
               }
             
               public Class> getConverter(Class forType) {
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 4935e5e..1dd3a25 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -58,6 +58,7 @@ import org.testng.annotations.Test;
             import java.io.File;
             import java.io.FileWriter;
             import java.io.IOException;
            +import java.math.BigDecimal;
             import java.util.ArrayList;
             import java.util.Arrays;
             import java.util.Comparator;
            @@ -72,7 +73,7 @@ import java.util.TreeSet;
             public class JCommanderTest {
               public void simpleArgs() {
                 Args1 args = new Args1();
            -    String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3",
            +    String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3", "-bigdecimal", "1.4",
                         "-groups", "unit", "a", "b", "c" };
                 new JCommander(args, argv);
             
            @@ -82,6 +83,7 @@ public class JCommanderTest {
                 Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c"));
                 Assert.assertEquals(args.floa, 1.2f, 0.1f);
                 Assert.assertEquals(args.doub, 1.3f, 0.1f);
            +    Assert.assertEquals(args.bigd, new BigDecimal("1.4"));
               }
             
               /**
            @@ -92,7 +94,7 @@ public class JCommanderTest {
                 Args1 args = new Args1();
                 String[] argv = { "-log", "2" };
                 JCommander jc = new JCommander(args, argv);
            -    Assert.assertEquals(jc.getParameters().size(), 6);
            +    Assert.assertEquals(jc.getParameters().size(), 7);
               }
             
               /**
            diff --git a/src/test/java/com/beust/jcommander/args/Args1.java b/src/test/java/com/beust/jcommander/args/Args1.java
            index cca53d8..9e55fb5 100644
            --- a/src/test/java/com/beust/jcommander/args/Args1.java
            +++ b/src/test/java/com/beust/jcommander/args/Args1.java
            @@ -18,6 +18,7 @@
             
             package com.beust.jcommander.args;
             
            +import java.math.BigDecimal;
             import java.util.List;
             
             import org.testng.collections.Lists;
            @@ -45,4 +46,7 @@ public class Args1 {
             
               @Parameter(names = "-float", description = "A float number")
               public float floa;
            +
            +  @Parameter(names = "-bigdecimal", description = "A BigDecimal number")
            +  public BigDecimal bigd;
             }
            -- 
            cgit v1.2.3
            
            
            From f923ee57617c8690d293909c53a4e109a8c2ba26 Mon Sep 17 00:00:00 2001
            From: Angus 
            Date: Wed, 26 Oct 2011 00:56:51 +0100
            Subject: Added support for ISO 8601 Date arguments and related test.
            
            We currently only support the format yyyy-MM-dd (as it is all I need
            right now).  In future this should be modified to support all ISO 8601
            formats such as yyyy-MM-dd'T'HH:mm:ssZ.
            ---
             .../converters/ISO8601DateConverter.java           | 49 ++++++++++++++++++++++
             .../internal/DefaultConverterFactory.java          |  3 ++
             .../java/com/beust/jcommander/JCommanderTest.java  | 10 +++--
             src/test/java/com/beust/jcommander/args/Args1.java |  4 ++
             4 files changed, 63 insertions(+), 3 deletions(-)
             create mode 100644 src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java b/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java
            new file mode 100644
            index 0000000..303f410
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java
            @@ -0,0 +1,49 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +import com.beust.jcommander.converters.BaseConverter;
            +import java.text.ParseException;
            +import java.text.SimpleDateFormat;
            +import java.util.Date;
            +
            +/**
            + * Converts a String to a Date.
            + * TODO Modify to work with all valid ISO 8601 date formats (currently only works with yyyy-MM-dd).
            + *
            + * @author angus
            + */
            +public class ISO8601DateConverter extends BaseConverter {
            +
            +  private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
            +
            +  public ISO8601DateConverter(String optionName) {
            +    super(optionName);
            +  }
            +
            +  @Override
            +  public Date convert(String value) {
            +    try {
            +      return DATE_FORMAT.parse(value);
            +    } catch (ParseException pe) {
            +      throw new ParameterException(getErrorString(value, String.format("an ISO-8601 formatted date (%s)", DATE_FORMAT.toPattern())));
            +    }
            +  }
            +}
            diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            index e622722..fed5783 100644
            --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            @@ -28,9 +28,11 @@ import com.beust.jcommander.converters.FloatConverter;
             import com.beust.jcommander.converters.DoubleConverter;
             import com.beust.jcommander.converters.StringConverter;
             import com.beust.jcommander.converters.BigDecimalConverter;
            +import com.beust.jcommander.converters.ISO8601DateConverter;
             
             import java.io.File;
             import java.math.BigDecimal;
            +import java.util.Date;
             import java.util.Map;
             
             public class DefaultConverterFactory implements IStringConverterFactory {
            @@ -54,6 +56,7 @@ public class DefaultConverterFactory implements IStringConverterFactory {
                 m_classConverters.put(boolean.class, BooleanConverter.class);
                 m_classConverters.put(File.class, FileConverter.class);
                 m_classConverters.put(BigDecimal.class, BigDecimalConverter.class);
            +    m_classConverters.put(Date.class, ISO8601DateConverter.class);
               }
             
               public Class> getConverter(Class forType) {
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 1dd3a25..3b5e410 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -59,8 +59,11 @@ import java.io.File;
             import java.io.FileWriter;
             import java.io.IOException;
             import java.math.BigDecimal;
            +import java.text.ParseException;
            +import java.text.SimpleDateFormat;
             import java.util.ArrayList;
             import java.util.Arrays;
            +import java.util.Date;
             import java.util.Comparator;
             import java.util.Iterator;
             import java.util.List;
            @@ -71,10 +74,10 @@ import java.util.TreeSet;
             
             @Test
             public class JCommanderTest {
            -  public void simpleArgs() {
            +  public void simpleArgs() throws ParseException {
                 Args1 args = new Args1();
                 String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3", "-bigdecimal", "1.4",
            -            "-groups", "unit", "a", "b", "c" };
            +            "-date", "2011-10-26", "-groups", "unit", "a", "b", "c" };
                 new JCommander(args, argv);
             
                 Assert.assertTrue(args.debug);
            @@ -84,6 +87,7 @@ public class JCommanderTest {
                 Assert.assertEquals(args.floa, 1.2f, 0.1f);
                 Assert.assertEquals(args.doub, 1.3f, 0.1f);
                 Assert.assertEquals(args.bigd, new BigDecimal("1.4"));
            +    Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26"));
               }
             
               /**
            @@ -94,7 +98,7 @@ public class JCommanderTest {
                 Args1 args = new Args1();
                 String[] argv = { "-log", "2" };
                 JCommander jc = new JCommander(args, argv);
            -    Assert.assertEquals(jc.getParameters().size(), 7);
            +    Assert.assertEquals(jc.getParameters().size(), 8);
               }
             
               /**
            diff --git a/src/test/java/com/beust/jcommander/args/Args1.java b/src/test/java/com/beust/jcommander/args/Args1.java
            index 9e55fb5..093abec 100644
            --- a/src/test/java/com/beust/jcommander/args/Args1.java
            +++ b/src/test/java/com/beust/jcommander/args/Args1.java
            @@ -20,6 +20,7 @@ package com.beust.jcommander.args;
             
             import java.math.BigDecimal;
             import java.util.List;
            +import java.util.Date;
             
             import org.testng.collections.Lists;
             
            @@ -49,4 +50,7 @@ public class Args1 {
             
               @Parameter(names = "-bigdecimal", description = "A BigDecimal number")
               public BigDecimal bigd;
            +
            +  @Parameter(names = "-date", description = "An ISO 8601 formatted date.")
            +  public Date date;
             }
            -- 
            cgit v1.2.3
            
            
            From b02a7c5b3388b64a133847d3630450f099e6e141 Mon Sep 17 00:00:00 2001
            From: Angus 
            Date: Wed, 26 Oct 2011 01:34:50 +0100
            Subject: Changed @author tag to "Angus Smithson" for my additions.
            
            ---
             src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java  | 2 +-
             src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java | 2 +-
             2 files changed, 2 insertions(+), 2 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java b/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java
            index cd256a4..aa8a819 100644
            --- a/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java
            +++ b/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java
            @@ -24,7 +24,7 @@ import java.math.BigDecimal;
             /**
              * Converts a String to a BigDecimal.
              *
            - * @author angus
            + * @author Angus Smithson
              */
             public class BigDecimalConverter extends BaseConverter {
             
            diff --git a/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java b/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java
            index 303f410..7429e0f 100644
            --- a/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java
            +++ b/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java
            @@ -28,7 +28,7 @@ import java.util.Date;
              * Converts a String to a Date.
              * TODO Modify to work with all valid ISO 8601 date formats (currently only works with yyyy-MM-dd).
              *
            - * @author angus
            + * @author Angus Smithson
              */
             public class ISO8601DateConverter extends BaseConverter {
             
            -- 
            cgit v1.2.3
            
            
            From 7021eade4657caf7ae25b19539bdc135619d248c Mon Sep 17 00:00:00 2001
            From: Angus 
            Date: Wed, 26 Oct 2011 01:37:42 +0100
            Subject: Added CommaSeparatedBaseConverter, some subclasses and tests.
            
            Created CommaSeparatedBaseConverter which will make it quicker/easier
            to parse lists of a particular type into ArrayList.  Added
            CommanSeparatedIntConverter and CommaSeparatedBigDecimalConverter,
            moved the old CommaSeparatedConverter to CommaSeparatedStringConverter.
            ---
             .../converters/CommaSeparatedBaseConverter.java    | 51 ++++++++++++++++++++++
             .../CommaSeparatedBigDecimalConverter.java         | 38 ++++++++++++++++
             .../converters/CommaSeparatedConverter.java        | 37 ----------------
             .../converters/CommaSeparatedIntConverter.java     | 36 +++++++++++++++
             .../converters/CommaSeparatedStringConverter.java  | 36 +++++++++++++++
             .../java/com/beust/jcommander/JCommanderTest.java  | 17 ++++++--
             .../com/beust/jcommander/args/ArgsConverter.java   | 15 +++++--
             7 files changed, 186 insertions(+), 44 deletions(-)
             create mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java
             create mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java
             delete mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java
             create mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java
             create mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java
            new file mode 100644
            index 0000000..454bca6
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java
            @@ -0,0 +1,51 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +import java.util.ArrayList;
            +import java.util.List;
            +
            +/**
            + * Base class for comma-separated converters which stores the name of the option and object type in case of errors.
            + *
            + * @author Angus Smithson
            + */
            +abstract class CommaSeparatedBaseConverter extends BaseConverter> {
            +
            +  private String m_typeDescription;
            +
            +  public CommaSeparatedBaseConverter(String optionName, String typeDescription) {
            +    super(optionName);
            +    m_typeDescription = typeDescription;
            +  }
            +
            +  public List convert(String value) {
            +    ArrayList al = new ArrayList();
            +    final String[] values = value.split(",");
            +    try {
            +      for (String s : values) al.add(getIndividualValue(s));
            +    } catch (Throwable t) {
            +      throw new ParameterException(getErrorString(value, String.format("a list of type %s.", m_typeDescription)));
            +    }
            +    return al;
            +  }
            +
            +  abstract T getIndividualValue(String value);
            +}
            diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java
            new file mode 100644
            index 0000000..dae58c2
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java
            @@ -0,0 +1,38 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import java.math.BigDecimal;
            +
            +/**
            + * Convert a string of comma separated numbers into a list of type BigDecimal.
            + *
            + * @author Angus Smithson
            + */
            +public class CommaSeparatedBigDecimalConverter extends CommaSeparatedBaseConverter {
            +
            +  public CommaSeparatedBigDecimalConverter(String optionName) {
            +    super(optionName, "BigDecimal");
            +  }
            +
            +  @Override
            +  BigDecimal getIndividualValue(String value) {
            +    return new BigDecimal(value);
            +  }
            +}
            diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java
            deleted file mode 100644
            index b719bd4..0000000
            --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedConverter.java
            +++ /dev/null
            @@ -1,37 +0,0 @@
            -/**
            - * Copyright (C) 2010 the original author or authors.
            - * See the notice.md file distributed with this work for additional
            - * information regarding copyright ownership.
            - *
            - * Licensed under the Apache License, Version 2.0 (the "License");
            - * you may not use this file except in compliance with the License.
            - * You may obtain a copy of the License at
            - *
            - *     http://www.apache.org/licenses/LICENSE-2.0
            - *
            - * Unless required by applicable law or agreed to in writing, software
            - * distributed under the License is distributed on an "AS IS" BASIS,
            - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            - * See the License for the specific language governing permissions and
            - * limitations under the License.
            - */
            -
            -package com.beust.jcommander.converters;
            -
            -import com.beust.jcommander.IStringConverter;
            -
            -import java.util.Arrays;
            -import java.util.List;
            -
            -/**
            - * Convert a string of comma separated words into a list of string.
            - * 
            - * @author cbeust
            - */
            -public class CommaSeparatedConverter implements IStringConverter> {
            -
            -  public List convert(String value) {
            -    return Arrays.asList(value.split(","));
            -  }
            -
            -}
            diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java
            new file mode 100644
            index 0000000..dc98ecc
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java
            @@ -0,0 +1,36 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +/**
            + * Convert a string of comma separated numbers into a list of type Integer.
            + *
            + * @author Angus Smithson
            + */
            +public class CommaSeparatedIntConverter extends CommaSeparatedBaseConverter {
            +  
            +  public CommaSeparatedIntConverter(String optionName) {
            +    super(optionName, "Integer");
            +  }
            +
            +  @Override
            +  Integer getIndividualValue(String value) {
            +    return Integer.parseInt(value);
            +  }
            +}
            diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java
            new file mode 100644
            index 0000000..a5cddf7
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java
            @@ -0,0 +1,36 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +/**
            + * Convert a string of comma separated words into a list of type String.
            + *
            + * @author Angus Smithson
            + */
            +public class CommaSeparatedStringConverter extends CommaSeparatedBaseConverter {
            +
            +  public CommaSeparatedStringConverter(String optionName) {
            +    super(optionName, "String");
            +  }
            +
            +  @Override
            +  String getIndividualValue(String value) {
            +    return value;
            +  }
            +}
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 3b5e410..25caf66 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -260,11 +260,20 @@ public class JCommanderTest {
               public void converterArgs() {
                 ArgsConverter args = new ArgsConverter();
                 String fileName = "a";
            -    new JCommander(args, "-file", "/tmp/" + fileName, "-days", "Tuesday,Thursday");
            +    new JCommander(args, "-file", "/tmp/" + fileName, 
            +      "-listStrings", "Tuesday,Thursday",
            +      "-listInts", "-1,8",
            +      "-listBigDecimals", "-11.52,100.12");
                 Assert.assertEquals(args.file.getName(), fileName);
            -    Assert.assertEquals(args.days.size(), 2);
            -    Assert.assertEquals(args.days.get(0), "Tuesday");
            -    Assert.assertEquals(args.days.get(1), "Thursday");
            +    Assert.assertEquals(args.listStrings.size(), 2);
            +    Assert.assertEquals(args.listStrings.get(0), "Tuesday");
            +    Assert.assertEquals(args.listStrings.get(1), "Thursday");
            +    Assert.assertEquals(args.listInts.size(), 2);
            +    Assert.assertEquals(args.listInts.get(0).intValue(), -1);
            +    Assert.assertEquals(args.listInts.get(1).intValue(), 8);
            +    Assert.assertEquals(args.listBigDecimals.size(), 2);
            +    Assert.assertEquals(args.listBigDecimals.get(0), new BigDecimal("-11.52"));
            +    Assert.assertEquals(args.listBigDecimals.get(1), new BigDecimal("100.12"));
               }
             
               private void argsBoolean1(String[] params, Boolean expected) {
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            index 8d88022..4e32cae 100644
            --- a/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            @@ -19,10 +19,13 @@
             package com.beust.jcommander.args;
             
             import com.beust.jcommander.Parameter;
            -import com.beust.jcommander.converters.CommaSeparatedConverter;
            +import com.beust.jcommander.converters.CommaSeparatedBigDecimalConverter;
            +import com.beust.jcommander.converters.CommaSeparatedIntConverter;
            +import com.beust.jcommander.converters.CommaSeparatedStringConverter;
             import com.beust.jcommander.converters.FileConverter;
             
             import java.io.File;
            +import java.math.BigDecimal;
             import java.util.List;
             
             public class ArgsConverter {
            @@ -30,6 +33,12 @@ public class ArgsConverter {
               @Parameter(names = "-file", converter = FileConverter.class)
               public File file;
             
            -  @Parameter(names = "-days", converter = CommaSeparatedConverter.class)
            -  public List days;
            +  @Parameter(names = "-listStrings", converter = CommaSeparatedStringConverter.class)
            +  public List listStrings;
            +
            +  @Parameter(names = "-listInts", converter = CommaSeparatedIntConverter.class)
            +  public List listInts;
            +
            +  @Parameter(names = "-listBigDecimals", converter = CommaSeparatedBigDecimalConverter.class)
            +  public List listBigDecimals;
             }
            -- 
            cgit v1.2.3
            
            
            From b04b599b25214e01db50b3545160426b7500d895 Mon Sep 17 00:00:00 2001
            From: rodionmoiseev 
            Date: Sat, 5 Nov 2011 20:20:53 +0900
            Subject: Support for delegated (mixin) parameters (issue #84)
            
            Added a new @ParametersDelegate annotation to tell JCommander parser to process all parametrised fields inside the annotated object. Any number of delegated parameters and any amount of nesting is allowed.
            
            fixes #84
            ---
             src/main/java/com/beust/jcommander/JCommander.java |  10 ++
             .../com/beust/jcommander/ParametersDelegate.java   |  44 ++++++
             .../beust/jcommander/ParametersDelegateTest.java   | 175 +++++++++++++++++++++
             3 files changed, 229 insertions(+)
             create mode 100644 src/main/java/com/beust/jcommander/ParametersDelegate.java
             create mode 100644 src/test/java/com/beust/jcommander/ParametersDelegateTest.java
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index d374a6f..b9fdb11 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -465,6 +465,7 @@ public class JCommander {
                     p("Field:" + cls.getSimpleName() + "." + f.getName());
                     f.setAccessible(true);
                     Annotation annotation = f.getAnnotation(Parameter.class);
            +        Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class);
                     if (annotation != null) {
                       Parameter p = (Parameter) annotation;
                       if (p.names().length == 0) {
            @@ -490,6 +491,15 @@ public class JCommander {
                           if (p.required()) m_requiredFields.put(f, pd);
                         }
                       }
            +        }else if(delegateAnnotation != null){
            +          try {
            +            Object delegateObject = f.get(object);
            +            if(delegateObject == null){
            +              throw new ParameterException("Delegate field '" + f.getName() + "' cannot be null.");
            +            }
            +            addDescription(delegateObject);
            +          } catch (IllegalAccessException e) {
            +          }
                     }
                   }
                   // Traverse the super class until we find Object.class
            diff --git a/src/main/java/com/beust/jcommander/ParametersDelegate.java b/src/main/java/com/beust/jcommander/ParametersDelegate.java
            new file mode 100644
            index 0000000..5a06f8e
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/ParametersDelegate.java
            @@ -0,0 +1,44 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander;
            +
            +import java.lang.annotation.Retention;
            +import java.lang.annotation.Target;
            +
            +import static java.lang.annotation.ElementType.FIELD;
            +
            +/**
            + * 

            When applied to a field all of its child fields annotated + * with {@link Parameter} will be included during arguments + * parsing.

            + * + *

            Mainly useful when creating complex command based CLI interfaces, + * where several commands can share a set of arguments, but using + * object inheritance is not enough, due to no-multiple-inheritance + * restriction. Using {@link ParametersDelegate} any number of + * command sets can be shared by using composition pattern.

            + * + *

            Delegations can be chained (nested).

            + * + * @author rodionmoiseev + */ +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@Target({ FIELD }) +public @interface ParametersDelegate { +} diff --git a/src/test/java/com/beust/jcommander/ParametersDelegateTest.java b/src/test/java/com/beust/jcommander/ParametersDelegateTest.java new file mode 100644 index 0000000..67fb7c4 --- /dev/null +++ b/src/test/java/com/beust/jcommander/ParametersDelegateTest.java @@ -0,0 +1,175 @@ +package com.beust.jcommander; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author rodionmoiseev + */ +public class ParametersDelegateTest { + + @Test + public void delegatingEmptyClassHasNoEffect() { + class EmptyDelegate { + public String nonParamString = "a"; + } + class MainParams { + @Parameter(names = "-a") + public boolean isA; + @Parameter(names = {"-b", "--long-b"}) + public String bValue = ""; + @ParametersDelegate + public EmptyDelegate delegate = new EmptyDelegate(); + } + + MainParams p = new MainParams(); + JCommander cmd = new JCommander(p); + cmd.parse("-a", "-b", "someValue"); + Assert.assertTrue(p.isA); + Assert.assertEquals(p.bValue, "someValue"); + Assert.assertEquals(p.delegate.nonParamString, "a"); + } + + @Test + public void delegatingSetsFieldsOnBothMainParamsAndTheDelegatedParams() { + class ComplexDelegate { + @Parameter(names = "-c") + public boolean isC; + @Parameter(names = {"-d", "--long-d"}) + public Integer d; + } + class MainParams { + @Parameter(names = "-a") + public boolean isA; + @Parameter(names = {"-b", "--long-b"}) + public String bValue = ""; + @ParametersDelegate + public ComplexDelegate delegate = new ComplexDelegate(); + } + + MainParams p = new MainParams(); + JCommander cmd = new JCommander(p); + cmd.parse("-c", "--long-d", "123", "--long-b", "bValue"); + Assert.assertFalse(p.isA); + Assert.assertEquals(p.bValue, "bValue"); + Assert.assertTrue(p.delegate.isC); + Assert.assertEquals(p.delegate.d, Integer.valueOf(123)); + } + + @Test + public void combinedAndNestedDelegates() { + abstract class LeafAbstractDelegate { + abstract float getFloat(); + } + class LeafDelegate { + @Parameter(names = "--list") + public List list = new ArrayList() {{ + add("value1"); + add("value2"); + }}; + @Parameter(names = "--bool") + public boolean bool; + } + class NestedDelegate1 { + @ParametersDelegate + public LeafDelegate leafDelegate = new LeafDelegate(); + @Parameter(names = {"-d", "--long-d"}) + public Integer d; + } + class NestedDelegate2 { + @Parameter(names = "-c") + public boolean isC; + @ParametersDelegate + public NestedDelegate1 nestedDelegate1 = new NestedDelegate1(); + @ParametersDelegate + public LeafAbstractDelegate anonymousDelegate = new LeafAbstractDelegate() { + @Parameter(names = "--anon-float") + public float anon = 999f; + + @Override + float getFloat() { + return anon; + } + }; + } + class MainParams { + @Parameter(names = "-a") + public boolean isA; + @Parameter(names = {"-b", "--long-b"}) + public String bValue = ""; + @ParametersDelegate + public NestedDelegate2 nestedDelegate2 = new NestedDelegate2(); + } + + MainParams p = new MainParams(); + JCommander cmd = new JCommander(p); + cmd.parse("--anon-float 1.2 -d 234 --list a --list b -a".split(" ")); + Assert.assertEquals(p.nestedDelegate2.anonymousDelegate.getFloat(), 1.2f); + Assert.assertEquals(p.nestedDelegate2.nestedDelegate1.leafDelegate.list, new ArrayList() {{ + add("a"); + add("b"); + }}); + Assert.assertFalse(p.nestedDelegate2.nestedDelegate1.leafDelegate.bool); + Assert.assertEquals(p.nestedDelegate2.nestedDelegate1.d, Integer.valueOf(234)); + Assert.assertFalse(p.nestedDelegate2.isC); + Assert.assertTrue(p.isA); + Assert.assertEquals(p.bValue, ""); + } + + @Test + public void commandTest() { + class Delegate { + @Parameter(names = "-a") + public String a = "b"; + } + class Command { + @ParametersDelegate + public Delegate delegate = new Delegate(); + } + + Command c = new Command(); + + JCommander cmd = new JCommander(); + cmd.addCommand("command", c); + + cmd.parse("command -a a".split(" ")); + Assert.assertEquals(c.delegate.a, "a"); + } + + @Test(expectedExceptions = ParameterException.class, + expectedExceptionsMessageRegExp = ".*delegate.*null.*") + public void nullDelegatesAreProhibited() { + class ComplexDelegate { + } + class MainParams { + @ParametersDelegate + public ComplexDelegate delegate; + } + + MainParams p = new MainParams(); + JCommander cmd = new JCommander(p); + cmd.parse(); + } + + @Test(expectedExceptions = ParameterException.class, + expectedExceptionsMessageRegExp = ".*-a.*") + public void duplicateDelegateThrowDuplicateOptionException() { + class Delegate { + @Parameter(names = "-a") + public String a; + } + class MainParams { + @ParametersDelegate + public Delegate d1 = new Delegate(); + @ParametersDelegate + public Delegate d2 = new Delegate(); + } + + MainParams p = new MainParams(); + JCommander cmd = new JCommander(p); + cmd.parse("-a value".split(" ")); + } +} -- cgit v1.2.3 From 6208f14460853eb13ba0a63c6e23db80ccc5437a Mon Sep 17 00:00:00 2001 From: rodionmoiseev Date: Sat, 5 Nov 2011 21:36:17 +0900 Subject: Added ParametersDelegateTest to the suite --- src/test/resources/testng.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 0ba3c9b..2b99230 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -10,6 +10,7 @@ + -- cgit v1.2.3 From e58736cbb9a0621698d71ad669adf050c5a82a46 Mon Sep 17 00:00:00 2001 From: rodionmoiseev Date: Tue, 8 Nov 2011 19:55:10 +0900 Subject: Added more parameters delegate tests --- .../beust/jcommander/ParametersDelegateTest.java | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/test/java/com/beust/jcommander/ParametersDelegateTest.java b/src/test/java/com/beust/jcommander/ParametersDelegateTest.java index 67fb7c4..3041438 100644 --- a/src/test/java/com/beust/jcommander/ParametersDelegateTest.java +++ b/src/test/java/com/beust/jcommander/ParametersDelegateTest.java @@ -139,6 +139,29 @@ public class ParametersDelegateTest { Assert.assertEquals(c.delegate.a, "a"); } + @Test + public void mainParametersTest() { + class Delegate { + @Parameter + public List mainParams = new ArrayList(); + } + class Command { + @ParametersDelegate + public Delegate delegate = new Delegate(); + } + + Command c = new Command(); + + JCommander cmd = new JCommander(); + cmd.addCommand("command", c); + + cmd.parse("command main params".split(" ")); + Assert.assertEquals(c.delegate.mainParams, new ArrayList() {{ + add("main"); + add("params"); + }}); + } + @Test(expectedExceptions = ParameterException.class, expectedExceptionsMessageRegExp = ".*delegate.*null.*") public void nullDelegatesAreProhibited() { @@ -172,4 +195,29 @@ public class ParametersDelegateTest { JCommander cmd = new JCommander(p); cmd.parse("-a value".split(" ")); } + + @Test(expectedExceptions = ParameterException.class, expectedExceptionsMessageRegExp = "Only one.*is allowed.*") + public void duplicateMainParametersAreNotAllowed() { + class Delegate1 { + @Parameter + public List mainParams1 = new ArrayList(); + } + class Delegate2 { + @Parameter + public List mainParams2 = new ArrayList(); + } + class Command { + @ParametersDelegate + public Delegate1 delegate1 = new Delegate1(); + @ParametersDelegate + public Delegate2 delegate2 = new Delegate2(); + } + + Command c = new Command(); + + JCommander cmd = new JCommander(); + cmd.addCommand("command", c); + + cmd.parse("command main params".split(" ")); + } } -- cgit v1.2.3 From 2a1ded0120fad90132582e6ad6345493d87de214 Mon Sep 17 00:00:00 2001 From: rodionmoiseev Date: Tue, 8 Nov 2011 20:01:39 +0900 Subject: Updated changelog to reflect support for parameter delegates --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 75b9232..5474118 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Current Current Added: Support for enums (Adrian Muraru) +Added: Support for delegating parameter definitions to child classes (rodionmoiseev) 1.19 2011/10/10 -- cgit v1.2.3 From 3e7cb52cbf4ca537cafb6617b20387225672ad1a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 22 Nov 2011 14:47:22 -0800 Subject: Better handling for fields of type List. --- src/main/java/com/beust/jcommander/JCommander.java | 45 +++++++++++-- src/main/java/com/beust/jcommander/Parameter.java | 19 +++++- .../jcommander/converters/BigDecimalConverter.java | 2 +- .../converters/CommaParameterSplitter.java | 12 ++++ .../converters/CommaSeparatedBaseConverter.java | 11 +++- .../CommaSeparatedBigDecimalConverter.java | 3 +- .../jcommander/converters/IParameterSplitter.java | 13 ++++ .../converters/ISO8601DateConverter.java | 3 +- .../internal/DefaultConverterFactory.java | 8 +-- src/test/java/com/beust/jcommander/HostPort.java | 5 ++ .../com/beust/jcommander/HostPortConverter.java | 1 + .../java/com/beust/jcommander/JCommanderTest.java | 73 +++++++--------------- .../com/beust/jcommander/args/ArgsConverter.java | 9 +-- .../java/com/beust/jcommander/args/ArgsList.java | 49 +++++++++++++++ 14 files changed, 180 insertions(+), 73 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/converters/CommaParameterSplitter.java create mode 100644 src/main/java/com/beust/jcommander/converters/IParameterSplitter.java create mode 100644 src/test/java/com/beust/jcommander/args/ArgsList.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index d374a6f..0de9004 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -18,6 +18,7 @@ package com.beust.jcommander; +import com.beust.jcommander.converters.IParameterSplitter; import com.beust.jcommander.converters.NoConverter; import com.beust.jcommander.converters.StringConverter; import com.beust.jcommander.internal.DefaultConverterFactory; @@ -1005,21 +1006,25 @@ public class JCommander { public Object convertValue(Field field, Class type, String value) { Parameter annotation = field.getAnnotation(Parameter.class); Class> converterClass = annotation.converter(); + boolean listConverterWasSpecified = annotation.listConverter() != NoConverter.class; // // Try to find a converter on the annotation // - if ( converterClass == null || converterClass == NoConverter.class) { + if (converterClass == null || converterClass == NoConverter.class) { // If no converter specified and type is enum, used enum values to convert if (type.isEnum()){ converterClass = type; } else { converterClass = findConverter(type); } - } + if (converterClass == null) { - converterClass = StringConverter.class; + Type elementType = findFieldGenericType(field); + converterClass = elementType != null + ? findConverter((Class>) elementType) + : StringConverter.class; } // @@ -1051,7 +1056,24 @@ public class JCommander { } } else { converter = instantiateConverter(optionName, converterClass); - result = converter.convert(value); + if (type.isAssignableFrom(List.class) + && field.getGenericType() instanceof ParameterizedType) { + + // The field is a List + if (listConverterWasSpecified) { + // If a list converter was specified, pass the value to it + // for direct conversion + IStringConverter listConverter = + instantiateConverter(optionName, annotation.listConverter()); + result = listConverter.convert(value); + } else { + // No list converter: use the single value converter and pass each + // parsed value to it individually + result = convertToList(value, converter, annotation.splitter()); + } + } else { + result = converter.convert(value); + } } } catch (InstantiationException e) { throw new ParameterException(e); @@ -1064,6 +1086,21 @@ public class JCommander { return result; } + /** + * Use the splitter to split the value into multiple values and then convert + * each of them individually. + */ + private Object convertToList(String value, IStringConverter converter, + Class splitterClass) + throws InstantiationException, IllegalAccessException { + IParameterSplitter splitter = splitterClass.newInstance(); + List result = Lists.newArrayList(); + for (String param : splitter.split(value)) { + result.add(converter.convert(param)); + } + return result; + } + private IStringConverter instantiateConverter(String optionName, Class> converterClass) throws IllegalArgumentException, InstantiationException, IllegalAccessException, diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index c697d2e..1b2a00f 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -20,6 +20,8 @@ package com.beust.jcommander; import static java.lang.annotation.ElementType.FIELD; +import com.beust.jcommander.converters.CommaParameterSplitter; +import com.beust.jcommander.converters.IParameterSplitter; import com.beust.jcommander.converters.NoConverter; import com.beust.jcommander.validators.NoValidator; @@ -65,10 +67,19 @@ public @interface Parameter { boolean password() default false; /** - * The string converter to use for this field. + * The string converter to use for this field. If the field is of type List + * and not listConverter attribute was specified, JCommander will split + * the input in individual values and convert each of them separately. */ Class> converter() default NoConverter.class; + /** + * The list string converter to use for this field. If it's specified, the + * field has to be of type List and the converter needs to return + * a List that's compatible with that type. + */ + Class> listConverter() default NoConverter.class; + /** * If true, this parameter won't appear in the usage(). */ @@ -83,4 +94,10 @@ public @interface Parameter { * @return true if this parameter has a variable arity. See @{IVariableArity} */ boolean variableArity() default false; + + /** + * What splitter to use (applicable only on fields of type List). By default, + * a comma separated splitter will be used. + */ + Class splitter() default CommaParameterSplitter.class; } diff --git a/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java b/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java index aa8a819..dfbba34 100644 --- a/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java +++ b/src/main/java/com/beust/jcommander/converters/BigDecimalConverter.java @@ -19,6 +19,7 @@ package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; + import java.math.BigDecimal; /** @@ -32,7 +33,6 @@ public class BigDecimalConverter extends BaseConverter { super(optionName); } - @Override public BigDecimal convert(String value) { try { return new BigDecimal(value); diff --git a/src/main/java/com/beust/jcommander/converters/CommaParameterSplitter.java b/src/main/java/com/beust/jcommander/converters/CommaParameterSplitter.java new file mode 100644 index 0000000..0e3bb18 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/CommaParameterSplitter.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.converters; + +import java.util.Arrays; +import java.util.List; + +public class CommaParameterSplitter implements IParameterSplitter { + + public List split(String value) { + return Arrays.asList(value.split(",")); + } + +} diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java index 454bca6..7f2d5b0 100644 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java @@ -19,11 +19,13 @@ package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; + import java.util.ArrayList; import java.util.List; /** - * Base class for comma-separated converters which stores the name of the option and object type in case of errors. + * Base class for comma-separated converters which stores the name of the option + * and object type in case of errors. * * @author Angus Smithson */ @@ -40,9 +42,12 @@ abstract class CommaSeparatedBaseConverter extends BaseConverter> { ArrayList al = new ArrayList(); final String[] values = value.split(","); try { - for (String s : values) al.add(getIndividualValue(s)); + for (String s : values) { + al.add(getIndividualValue(s)); + } } catch (Throwable t) { - throw new ParameterException(getErrorString(value, String.format("a list of type %s.", m_typeDescription))); + throw new ParameterException(getErrorString(value, + String.format("a list of type %s.", m_typeDescription))); } return al; } diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java index dae58c2..c546a3b 100644 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java +++ b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java @@ -25,7 +25,8 @@ import java.math.BigDecimal; * * @author Angus Smithson */ -public class CommaSeparatedBigDecimalConverter extends CommaSeparatedBaseConverter { +public class CommaSeparatedBigDecimalConverter extends + CommaSeparatedBaseConverter { public CommaSeparatedBigDecimalConverter(String optionName) { super(optionName, "BigDecimal"); diff --git a/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java b/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java new file mode 100644 index 0000000..e8b87b0 --- /dev/null +++ b/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java @@ -0,0 +1,13 @@ +package com.beust.jcommander.converters; + +import java.util.List; + +/** + * Convert a string representing several parameters (e.g. "a,b,c" or "d/e/f") into a + * list of arguments ([a,b,c] and [d,e,f]). + * + * @param + */ +public interface IParameterSplitter { + List split(String value); +} diff --git a/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java b/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java index 7429e0f..f024f5c 100644 --- a/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java +++ b/src/main/java/com/beust/jcommander/converters/ISO8601DateConverter.java @@ -19,7 +19,7 @@ package com.beust.jcommander.converters; import com.beust.jcommander.ParameterException; -import com.beust.jcommander.converters.BaseConverter; + import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -38,7 +38,6 @@ public class ISO8601DateConverter extends BaseConverter { super(optionName); } - @Override public Date convert(String value) { try { return DATE_FORMAT.parse(value); diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java index fed5783..f98a111 100644 --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java @@ -20,15 +20,15 @@ package com.beust.jcommander.internal; import com.beust.jcommander.IStringConverter; import com.beust.jcommander.IStringConverterFactory; +import com.beust.jcommander.converters.BigDecimalConverter; import com.beust.jcommander.converters.BooleanConverter; +import com.beust.jcommander.converters.DoubleConverter; import com.beust.jcommander.converters.FileConverter; +import com.beust.jcommander.converters.FloatConverter; +import com.beust.jcommander.converters.ISO8601DateConverter; import com.beust.jcommander.converters.IntegerConverter; import com.beust.jcommander.converters.LongConverter; -import com.beust.jcommander.converters.FloatConverter; -import com.beust.jcommander.converters.DoubleConverter; import com.beust.jcommander.converters.StringConverter; -import com.beust.jcommander.converters.BigDecimalConverter; -import com.beust.jcommander.converters.ISO8601DateConverter; import java.io.File; import java.math.BigDecimal; diff --git a/src/test/java/com/beust/jcommander/HostPort.java b/src/test/java/com/beust/jcommander/HostPort.java index e0e5289..a18018e 100644 --- a/src/test/java/com/beust/jcommander/HostPort.java +++ b/src/test/java/com/beust/jcommander/HostPort.java @@ -21,4 +21,9 @@ package com.beust.jcommander; public class HostPort { public String host; public Integer port; + @Override + + public String toString() { + return "[Host:" + host + " port:" + port + "]"; + } } diff --git a/src/test/java/com/beust/jcommander/HostPortConverter.java b/src/test/java/com/beust/jcommander/HostPortConverter.java index 5409d21..f45e3ba 100644 --- a/src/test/java/com/beust/jcommander/HostPortConverter.java +++ b/src/test/java/com/beust/jcommander/HostPortConverter.java @@ -28,4 +28,5 @@ public class HostPortConverter implements IStringConverter { return result; } + } \ No newline at end of file diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 25caf66..f336e52 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -31,6 +31,7 @@ import com.beust.jcommander.args.ArgsI18N1; import com.beust.jcommander.args.ArgsI18N2; import com.beust.jcommander.args.ArgsI18N2New; import com.beust.jcommander.args.ArgsInherited; +import com.beust.jcommander.args.ArgsList; import com.beust.jcommander.args.ArgsMainParameter1; import com.beust.jcommander.args.ArgsMaster; import com.beust.jcommander.args.ArgsMultipleUnparsed; @@ -63,8 +64,6 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; -import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -569,57 +568,29 @@ public class JCommanderTest { new JCommander(args, argv); } + public void testListAndSplitters() { + ArgsList al = new ArgsList(); + JCommander j = new JCommander(al); + j.parse("-groups", "a,b", "-ints", "41,42", "-hp", "localhost:1000;example.com:1001", + "-hp2", "localhost:1000,example.com:1001", "-uppercase", "ab,cd"); + Assert.assertEquals(al.groups.get(0), "a"); + Assert.assertEquals(al.groups.get(1), "b"); + Assert.assertEquals(al.ints.get(0).intValue(), 41); + Assert.assertEquals(al.ints.get(1).intValue(), 42); + Assert.assertEquals(al.hostPorts.get(0).host, "localhost"); + Assert.assertEquals(al.hostPorts.get(0).port.intValue(), 1000); + Assert.assertEquals(al.hostPorts.get(1).host, "example.com"); + Assert.assertEquals(al.hostPorts.get(1).port.intValue(), 1001); + Assert.assertEquals(al.hp2.get(1).host, "example.com"); + Assert.assertEquals(al.hp2.get(1).port.intValue(), 1001); + Assert.assertEquals(al.uppercase.get(0), "AB"); + Assert.assertEquals(al.uppercase.get(1), "CD"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - JCommander j = new JCommander(new Args1()); - j.setParameterDescriptionComparator( - new Comparator() { - public int compare(ParameterDescription p0, ParameterDescription p1) { - return p1.getLongestName().length() - p0.getLongestName().length(); - } - }); - j.usage(); -// for (int i = 0; i < 5; i++) { -// VariableArity va = new VariableArity(i); -// new JCommander(va).parse("-variable", "a", "b", "c", "d"); -// System.out.println(va.var + " *** " + va.main); -// } -// new JCommanderTest().repeatedArgs(); -// PortsArgs a = new PortsArgs(); -// JCommander jc = new JCommander(a); -// jc.usage(); -// new JCommanderTest().validationShouldWorkWithDefaultValues(); -// new JCommanderTest().booleanArity1(); -// ArgsLongDescription a = new ArgsLongDescription(); -// JCommander jc = new JCommander(a); -// jc.usage(); -// ArgsPassword a = new ArgsPassword(); -// JCommander jc = new JCommander(a); -// jc.parse("-password"); -// System.out.println("Password:" + a.password); -// new JCommanderTest().commandsShouldBeShownInOrderOfInsertion(); -// CommandMain cm = new CommandMain(); -// JCommander jc = new JCommander(cm); -// CommandAdd add = new CommandAdd(); -// jc.addCommand("add", add); -// CommandCommit commit = new CommandCommit(); -// jc.addCommand("commit", commit); -// jc.usage(); - -// new JCommanderTest().requiredMainParameters(); -// new CommandTest().commandTest1(); -// new DefaultProviderTest().defaultProvider1(); -// ArgsMainParameter a = new ArgsMainParameter(); -// new JCommander(a, "ex1:10", "ex2:20"); -// System.out.println(a.parameters.get(0).host); -// new JCommander(new Args1()).usage(); -// Separator a = new Separator(); -// String[] argv = new String[] { "-n", "foo" }; -// String[] argv = new String[] { "-v", "t" }; -// String[] argv = { "-log=10" }; -// JCommander jc = new JCommander(a, argv); -// Assert.assertEquals(a.log.intValue(), 10); -// } + new JCommanderTest().testListAndSplitters(); + new JCommanderTest().converterArgs(); } // Tests: diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java index 4e32cae..159ed78 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsConverter.java +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java @@ -19,9 +19,6 @@ package com.beust.jcommander.args; import com.beust.jcommander.Parameter; -import com.beust.jcommander.converters.CommaSeparatedBigDecimalConverter; -import com.beust.jcommander.converters.CommaSeparatedIntConverter; -import com.beust.jcommander.converters.CommaSeparatedStringConverter; import com.beust.jcommander.converters.FileConverter; import java.io.File; @@ -33,12 +30,12 @@ public class ArgsConverter { @Parameter(names = "-file", converter = FileConverter.class) public File file; - @Parameter(names = "-listStrings", converter = CommaSeparatedStringConverter.class) + @Parameter(names = "-listStrings") public List listStrings; - @Parameter(names = "-listInts", converter = CommaSeparatedIntConverter.class) + @Parameter(names = "-listInts") public List listInts; - @Parameter(names = "-listBigDecimals", converter = CommaSeparatedBigDecimalConverter.class) + @Parameter(names = "-listBigDecimals") public List listBigDecimals; } diff --git a/src/test/java/com/beust/jcommander/args/ArgsList.java b/src/test/java/com/beust/jcommander/args/ArgsList.java new file mode 100644 index 0000000..e827773 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/ArgsList.java @@ -0,0 +1,49 @@ +package com.beust.jcommander.args; + +import com.beust.jcommander.HostPort; +import com.beust.jcommander.HostPortConverter; +import com.beust.jcommander.IStringConverter; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.converters.IParameterSplitter; + +import org.testng.collections.Lists; + +import java.util.Arrays; +import java.util.List; + +public class ArgsList { + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public List groups; + + @Parameter(names = "-ints") + public List ints; + + @Parameter(names = "-hp", converter = HostPortConverter.class, splitter = SemiColonSplitter.class) + public List hostPorts; + + @Parameter(names = "-hp2", converter = HostPortConverter.class) + public List hp2; + + @Parameter(names = "-uppercase", listConverter = UppercaseConverter.class) + public List uppercase; + + public static class UppercaseConverter implements IStringConverter> { + public List convert(String value) { + List result = Lists.newArrayList(); + String[] s = value.split(","); + for (String p : s) { + result.add(p.toUpperCase()); + } + return result; + } + } + + public static class SemiColonSplitter implements IParameterSplitter { + + public List split(String value) { + return Arrays.asList(value.split(";")); + } + + } + +} -- cgit v1.2.3 From 86953b9ed40f39a0699c5b20c668d78e2bb5a4c8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 22 Nov 2011 14:47:32 -0800 Subject: Script update. --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index 001ed3d..d4e94ab 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.3 +v=6.3.1 export TESTNG=../testng/target/testng-${v}.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From cc5c9d85d71efdc2a2abe23bfa8a3f6afbec9fe1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 22 Nov 2011 14:50:58 -0800 Subject: Clean up. --- src/main/java/com/beust/jcommander/JCommander.java | 15 ++++++ .../converters/CommaSeparatedBaseConverter.java | 56 ---------------------- .../CommaSeparatedBigDecimalConverter.java | 39 --------------- .../converters/CommaSeparatedIntConverter.java | 36 -------------- .../converters/CommaSeparatedStringConverter.java | 36 -------------- 5 files changed, 15 insertions(+), 167 deletions(-) delete mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java delete mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java delete mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java delete mode 100644 src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 0de9004..66a477d 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -612,6 +612,21 @@ public class JCommander { } + /** + * @return the generic type of the collection for this field, or null if not applicable. + */ + private Type findFieldGenericType(Field field) { + if (field.getGenericType() instanceof ParameterizedType) { + ParameterizedType p = (ParameterizedType) field.getGenericType(); + Type cls = p.getActualTypeArguments()[0]; + if (cls instanceof Class) { + return cls; + } + } + + return null; + } + /** * @return the number of options that were processed. */ diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java deleted file mode 100644 index 7f2d5b0..0000000 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBaseConverter.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright (C) 2010 the original author or authors. - * See the notice.md file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.beust.jcommander.converters; - -import com.beust.jcommander.ParameterException; - -import java.util.ArrayList; -import java.util.List; - -/** - * Base class for comma-separated converters which stores the name of the option - * and object type in case of errors. - * - * @author Angus Smithson - */ -abstract class CommaSeparatedBaseConverter extends BaseConverter> { - - private String m_typeDescription; - - public CommaSeparatedBaseConverter(String optionName, String typeDescription) { - super(optionName); - m_typeDescription = typeDescription; - } - - public List convert(String value) { - ArrayList al = new ArrayList(); - final String[] values = value.split(","); - try { - for (String s : values) { - al.add(getIndividualValue(s)); - } - } catch (Throwable t) { - throw new ParameterException(getErrorString(value, - String.format("a list of type %s.", m_typeDescription))); - } - return al; - } - - abstract T getIndividualValue(String value); -} diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java deleted file mode 100644 index c546a3b..0000000 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedBigDecimalConverter.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (C) 2010 the original author or authors. - * See the notice.md file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.beust.jcommander.converters; - -import java.math.BigDecimal; - -/** - * Convert a string of comma separated numbers into a list of type BigDecimal. - * - * @author Angus Smithson - */ -public class CommaSeparatedBigDecimalConverter extends - CommaSeparatedBaseConverter { - - public CommaSeparatedBigDecimalConverter(String optionName) { - super(optionName, "BigDecimal"); - } - - @Override - BigDecimal getIndividualValue(String value) { - return new BigDecimal(value); - } -} diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java deleted file mode 100644 index dc98ecc..0000000 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedIntConverter.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (C) 2010 the original author or authors. - * See the notice.md file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.beust.jcommander.converters; - -/** - * Convert a string of comma separated numbers into a list of type Integer. - * - * @author Angus Smithson - */ -public class CommaSeparatedIntConverter extends CommaSeparatedBaseConverter { - - public CommaSeparatedIntConverter(String optionName) { - super(optionName, "Integer"); - } - - @Override - Integer getIndividualValue(String value) { - return Integer.parseInt(value); - } -} diff --git a/src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java b/src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java deleted file mode 100644 index a5cddf7..0000000 --- a/src/main/java/com/beust/jcommander/converters/CommaSeparatedStringConverter.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (C) 2010 the original author or authors. - * See the notice.md file distributed with this work for additional - * information regarding copyright ownership. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.beust.jcommander.converters; - -/** - * Convert a string of comma separated words into a list of type String. - * - * @author Angus Smithson - */ -public class CommaSeparatedStringConverter extends CommaSeparatedBaseConverter { - - public CommaSeparatedStringConverter(String optionName) { - super(optionName, "String"); - } - - @Override - String getIndividualValue(String value) { - return value; - } -} -- cgit v1.2.3 From 1b36a0ec1df72193aff0890781d71016658342ab Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 Nov 2011 12:53:55 -0800 Subject: Doc update. --- doc/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/index.html b/doc/index.html index 53a707e..56b681e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -603,6 +603,8 @@ Usage: <main class> [options] -long A long number (default: 0) +You can customize the name of your program by calling setProgramName() on your JCommander object. + Options preceded by an asterisk are required.

            Hiding parameters

            -- cgit v1.2.3 From 3cf4188ad5c30c66b359353289ac2d03967d6cf8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 Nov 2011 12:54:13 -0800 Subject: Added {set,get}ColumnSize() for the usage. --- src/main/java/com/beust/jcommander/JCommander.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 66a477d..3739585 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -144,6 +144,8 @@ public class JCommander { } }; + private int m_columnSize = 79; + /** * The factories used to look up string converters. */ @@ -939,8 +941,16 @@ public class JCommander { m_parameterDescriptionComparator = c; } + public void setColumnSize(int columnSize) { + m_columnSize = columnSize; + } + + public int getColumnSize() { + return m_columnSize; + } + private void wrapDescription(StringBuilder out, int indent, String description) { - int max = 79; + int max = getColumnSize(); String[] words = description.split(" "); int current = indent; int i = 0; -- cgit v1.2.3 From 66e78950950fa85f88043ebc7c2b2dc9aa0814af Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 Nov 2011 13:15:16 -0800 Subject: Added: @Parameter(commandNames) so that command names can be specified with annotations --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 15 ++++++++++++- src/main/java/com/beust/jcommander/Parameters.java | 5 +++++ .../com/beust/jcommander/command/CommandTest.java | 26 +++++++++++++++++++++- .../beust/jcommander/command/NamedCommandAdd.java | 17 ++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/command/NamedCommandAdd.java diff --git a/CHANGELOG b/CHANGELOG index 75b9232..138c033 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Current Current +Added: @Parameter(commandNames) so that command names can be specified with annotations Added: Support for enums (Adrian Muraru) 1.19 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3739585..a3beecb 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1157,6 +1157,18 @@ public class JCommander { addCommand(name, object, new String[0]); } + public void addCommand(Object object) { + Parameters p = object.getClass().getAnnotation(Parameters.class); + if (p != null && p.commandNames().length > 0) { + for (String commandName : p.commandNames()) { + addCommand(commandName, object); + } + } else { + throw new ParameterException("Trying to add command " + object.getClass().getName() + + " without specifying its names in @Parameters"); + } + } + /** * Add a command object and its aliases. */ @@ -1312,6 +1324,7 @@ public class JCommander { @Override public String toString() { return getDisplayName(); + } } -} +} \ No newline at end of file diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index e25d1f2..be5b5ce 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -60,4 +60,9 @@ public @interface Parameters { * @return the key used to find the command description in the resource bundle. */ String commandDescriptionKey() default ""; + + /** + * An array of allowed command names. + */ + String[] commandNames() default {}; } diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java index 0bedeeb..97e0007 100644 --- a/src/test/java/com/beust/jcommander/command/CommandTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -19,6 +19,7 @@ package com.beust.jcommander.command; import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; import org.testng.Assert; import org.testng.annotations.Test; @@ -26,6 +27,29 @@ import org.testng.annotations.Test; import java.util.Arrays; public class CommandTest { + @Test + public void namedCommandTest1() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + NamedCommandAdd add = new NamedCommandAdd(); + jc.addCommand(add); + CommandCommit commit = new CommandCommit(); + jc.addCommand("commit", commit); + jc.parse("add", "-i", "A.java"); + + Assert.assertEquals(jc.getParsedCommand(), "add"); + Assert.assertEquals(add.interactive.booleanValue(), true); + Assert.assertEquals(add.patterns, Arrays.asList("A.java")); + } + + @Test(expectedExceptions = ParameterException.class) + public void shouldComplainIfNoAnnotations() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand(add); + } + @Test public void commandTest1() { CommandMain cm = new CommandMain(); @@ -64,6 +88,6 @@ public class CommandTest { } public static void main(String[] args) { - new CommandTest().commandTest2(); + new CommandTest().shouldComplainIfNoAnnotations(); } } diff --git a/src/test/java/com/beust/jcommander/command/NamedCommandAdd.java b/src/test/java/com/beust/jcommander/command/NamedCommandAdd.java new file mode 100644 index 0000000..0773e18 --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/NamedCommandAdd.java @@ -0,0 +1,17 @@ +package com.beust.jcommander.command; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +import java.util.List; + +@Parameters(commandNames = "add", commandDescription = "Add file contents to the index") +public class NamedCommandAdd { + + @Parameter(description = "Patterns of files to be added") + public List patterns; + + @Parameter(names = "-i") + public Boolean interactive = false; + +} -- cgit v1.2.3 From 5142b72f70b4f6469c94339b0e85c1f0aa8f43e4 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 Nov 2011 13:15:27 -0800 Subject: Updated to TestNG 6.3.2beta. --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index d4e94ab..5a6a9f8 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.3.1 +v=6.3.2beta export TESTNG=../testng/target/testng-${v}.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From 3fd7d20d61b4333e0b325910c854f5df49b4adfa Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 Nov 2011 13:15:34 -0800 Subject: Updated to Surefire 2.10. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4091c93..869f82c 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.7.1 + 2.10 true -- cgit v1.2.3 From b871944ccc7f31a310f0d6b2e1568ac6656f2bec Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 09:17:47 -0800 Subject: ParametersDelegate: doc and some minor formatting. --- doc/index.html | 32 ++++++++++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 4 +-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 56b681e..3482063 100644 --- a/doc/index.html +++ b/doc/index.html @@ -644,6 +644,38 @@ host: Hôte JCommander will then use the default locale to resolve your descriptions. +

            Parameter delegates

            + +If you are writing many different tools in the same project, you will probably find that most of these tools can share configurations. While you can use inheritance with your objects to avoid repeating this code, the restriction to single inheritance of implementation might limit your flexibility. To address this problem, JCommander supports parameter delegates. + +

            + +When JCommander encounters an object annotated with @ParameterDelegate in one of your objects, it acts as if this object had been added as a description object itself: + +

            +class Delegate {
            +  @Parameter(names = "-port")
            +  public int port;
            +}
            +
            +class MainParams {
            +  @Parameter(names = "-v")
            +  public boolean verbose;
            +
            +  @ParametersDelegate
            +  public Delegate delegate = new Delegate();
            +}
            +
            + +The example above specifies a delegate parameter Delegate which is then referenced in MainParams. You only need to add a MainParams object to your JCommander configuration in order to use the delegate: + +
            +MainParams p = new MainParams();
            +new JCommander(p).parse("-v", "-port", "1234");
            +Assert.assertTrue(p.isVerbose);
            +Assert.assertEquals(p.delegate.port, 1234);
            +
            +

            JCommander in Scala

            Here is a quick example of how to use JCommander in Scala (courtesy of Patrick Linskey): diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 2720a58..3848dda 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -494,10 +494,10 @@ public class JCommander { if (p.required()) m_requiredFields.put(f, pd); } } - }else if(delegateAnnotation != null){ + } else if (delegateAnnotation != null) { try { Object delegateObject = f.get(object); - if(delegateObject == null){ + if (delegateObject == null){ throw new ParameterException("Delegate field '" + f.getName() + "' cannot be null."); } addDescription(delegateObject); -- cgit v1.2.3 From 4ba2a3c6a66626c4629266729a16e7f7e07b9ad0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 09:34:05 -0800 Subject: Fixed: Throw if an unknown option is found --- CHANGELOG | 5 ++-- src/main/java/com/beust/jcommander/JCommander.java | 2 ++ .../java/com/beust/jcommander/JCommanderTest.java | 29 ++++++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 00f1ae8..6f5078c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,9 @@ Current -Current - +Added: Support for delegating parameter definitions to child classes (rodionmoiseev) Added: @Parameter(commandNames) so that command names can be specified with annotations Added: Support for enums (Adrian Muraru) -Added: Support for delegating parameter definitions to child classes (rodionmoiseev) +Fixed: Throw if an unknown option is found 1.19 2011/10/10 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3848dda..99b2606 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -569,6 +569,8 @@ public class JCommander { } } } + } else { + throw new ParameterException("Unknown option: " + arg); } } else { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index f336e52..a77b3fb 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -587,10 +587,35 @@ public class JCommanderTest { Assert.assertEquals(al.uppercase.get(1), "CD"); } + @Test(expectedExceptions = ParameterException.class) + public void shouldThrowIfUnknownOption() { + class A { + @Parameter(names = "-long") + public long l; + } + A a = new A(); + new JCommander(a).parse("-lon", "32"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().testListAndSplitters(); - new JCommanderTest().converterArgs(); +// class A { +// @Parameter +// List parameters; +// +// @Parameter(names = "-long") +// public long l; +// } +// A a = new A(); +// new JCommander(a).parse("-lon", "32"); +// System.out.println(a.l); +// System.out.println(a.parameters); +// ArgsList al = new ArgsList(); +// JCommander j = new JCommander(al); +// j.setColumnSize(40); +// j.usage(); +// new JCommanderTest().testListAndSplitters(); +// new JCommanderTest().converterArgs(); } // Tests: -- cgit v1.2.3 From c3507ebf6d4b118ebeb443f0da87a63543ab395a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 10:47:01 -0800 Subject: Fixed: Main parameters are now validated as well (Connor Mullen). --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 2 ++ .../com/beust/jcommander/ParameterDescription.java | 26 +++++++++++----------- .../java/com/beust/jcommander/JCommanderTest.java | 20 +++++++++++++++++ 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6f5078c..64c5a45 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ Added: Support for delegating parameter definitions to child classes (rodionmois Added: @Parameter(commandNames) so that command names can be specified with annotations Added: Support for enums (Adrian Muraru) Fixed: Throw if an unknown option is found +Fixed: Main parameters are now validated as well (Connor Mullen) 1.19 2011/10/10 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 99b2606..65c59fc 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -594,6 +594,8 @@ public class JCommander { } } + ParameterDescription.validateParameter(m_mainParameterAnnotation, "Default", value); + m_mainParameterDescription.setAssigned(true); mp.add(convertedValue); } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 5b674ca..37376e7 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -31,8 +31,6 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; -import com.beust.jcommander.validators.NoValidator; - public class ParameterDescription { private Object m_object; private Parameter m_parameterAnnotation; @@ -221,16 +219,18 @@ public class ParameterDescription { } private void validateParameter(String name, String value) { - Class validator = m_parameterAnnotation.validateWith(); - if (validator != NoValidator.class) { - try { - p("Validating parameter:" + name + " value:" + value + " validator:" + validator); - validator.newInstance().validate(name, value); - } catch (InstantiationException e) { - throw new ParameterException("Can't instantiate validator:" + e); - } catch (IllegalAccessException e) { - throw new ParameterException("Can't instantiate validator:" + e); - } + validateParameter(m_parameterAnnotation, name, value); + } + + public static void validateParameter(Parameter annotation, String name, String value) { + Class validator = annotation.validateWith(); + try { + p("Validating parameter:" + name + " value:" + value + " validator:" + validator); + validator.newInstance().validate(name, value); + } catch (InstantiationException e) { + throw new ParameterException("Can't instantiate validator:" + e); + } catch (IllegalAccessException e) { + throw new ParameterException("Can't instantiate validator:" + e); } } @@ -260,7 +260,7 @@ public class ParameterDescription { return (!isDefault && !m_assigned); } - private void p(String string) { + private static void p(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { System.out.println("[ParameterDescription] " + string); } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index a77b3fb..ed2c779 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -597,8 +597,28 @@ public class JCommanderTest { new JCommander(a).parse("-lon", "32"); } + @Test(expectedExceptions = ParameterException.class) + public void mainParameterShouldBeValidate() { + class V implements IParameterValidator { + + public void validate(String name, String value) throws ParameterException { + Assert.assertEquals("a", value); + } + } + + class A { + @Parameter(validateWith = V.class) + public List m; + } + + A a = new A(); + new JCommander(a).parse("b"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { + + System.out.println("A"); // class A { // @Parameter // List parameters; -- cgit v1.2.3 From e4e33f0b418ca48230157de1c04987fddbd22860 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 11:21:08 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 869f82c..a93c1b8 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.20-SNAPSHOT + 1.20 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 8eac02e311db6a1f1832a0be524e9c0889658adc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 11:21:18 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a93c1b8..412b7f4 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.20 + 1.21-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From d95b69aebc39314baad3c7f8e766b40a67481e3e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 11:24:15 -0800 Subject: Doc typo. --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 3482063..7ce760d 100644 --- a/doc/index.html +++ b/doc/index.html @@ -644,7 +644,7 @@ host: Hôte JCommander will then use the default locale to resolve your descriptions. -

            Parameter delegates

            +

            Parameter delegates

            If you are writing many different tools in the same project, you will probably find that most of these tools can share configurations. While you can use inheritance with your objects to avoid repeating this code, the restriction to single inheritance of implementation might limit your flexibility. To address this problem, JCommander supports parameter delegates. @@ -729,7 +729,7 @@ You can download JCommander from the following locations: <groupId>com.beust</groupId> <artifactId>jcommander</artifactId> - 1.17 + 1.20 -- cgit v1.2.3 From af876df10623913f9faff854fcf5b8c0e5e8061d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 25 Nov 2011 11:30:06 -0800 Subject: CHANGELOG update. --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 64c5a45..bd44fb7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ Current +1.20 +2011/11/24 + Added: Support for delegating parameter definitions to child classes (rodionmoiseev) Added: @Parameter(commandNames) so that command names can be specified with annotations Added: Support for enums (Adrian Muraru) @@ -8,6 +11,7 @@ Fixed: Main parameters are now validated as well (Connor Mullen) 1.19 2011/10/10 + Added: commandDescriptionKey to @Parameters, to allow internationalized command descriptions Added: JCommander#setParameterDescriptionComparator for better control over usage() Fixed: Fields of type Set (HashSet and SortedSet) are now supported -- cgit v1.2.3 From cab863c761dadaf5f664a954f0459bacb5734901 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 28 Nov 2011 00:24:55 -0800 Subject: Google group --- doc/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/index.html b/doc/index.html index 7ce760d..4b2b9eb 100644 --- a/doc/index.html +++ b/doc/index.html @@ -711,6 +711,9 @@ object Main { TestNG uses JCommander to parse its command line, here is its definition file. +

            Mailing list

            + +Join the JCommander Google group if you are interested in discussions about JCommander.

            Javadocs

            -- cgit v1.2.3 From e45913e4d99699a0860df6a3aa7e2007750ec45f Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Tue, 29 Nov 2011 09:40:08 +0100 Subject: Issue #86: Use Console() when possible instead of System.out to preserve non ascii chars. --- CHANGELOG | 2 + src/main/java/com/beust/jcommander/JCommander.java | 56 ++++++++++------------ .../com/beust/jcommander/ParameterDescription.java | 4 +- .../com/beust/jcommander/internal/Console.java | 10 ++++ .../beust/jcommander/internal/DefaultConsole.java | 33 +++++++++++++ .../com/beust/jcommander/internal/JDK6Console.java | 38 +++++++++++++++ 6 files changed, 110 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/internal/Console.java create mode 100644 src/main/java/com/beust/jcommander/internal/DefaultConsole.java create mode 100644 src/main/java/com/beust/jcommander/internal/JDK6Console.java diff --git a/CHANGELOG b/CHANGELOG index bd44fb7..a1a323d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ Current +Fixed: Use JDK 6 Console() when available to improve support of non ascii chars (Julien Henry) + 1.20 2011/11/24 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 65c59fc..9962b2f 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -21,14 +21,16 @@ package com.beust.jcommander; 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 java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; -import java.io.InputStreamReader; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -145,6 +147,8 @@ public class JCommander { }; private int m_columnSize = 79; + + private static Console m_console; /** * The factories used to look up string converters. @@ -197,6 +201,19 @@ public class JCommander { addObject(object); parse(args); } + + public static Console getConsole() { + if (m_console == null) { + try { + Method consoleMethod = System.class.getDeclaredMethod("console", new Class[0]); + Object console = consoleMethod.invoke(null, new Object[0]); + m_console = new JDK6Console(console); + } catch (Throwable t) { + m_console = new DefaultConsole(); + } + } + return m_console; + } /** * Adds the provided arg object to the set of objects that this commander @@ -701,31 +718,8 @@ public class JCommander { * on Java 6. */ private char[] readPassword(String description) { - System.out.print(description + ": "); - try { - Method consoleMethod = System.class.getDeclaredMethod("console", new Class[0]); - Object console = consoleMethod.invoke(null, new Object[0]); - Method readPassword = console.getClass().getDeclaredMethod("readPassword", new Class[0]); - return (char[]) readPassword.invoke(console, new Object[0]); - } catch (Throwable t) { - return readLine(description); - } - } - - /** - * Read a line from stdin (used when java.io.Console is not available) - */ - private char[] readLine(String description) { - try { - InputStreamReader isr = new InputStreamReader(System.in); - BufferedReader in = new BufferedReader(isr); - String result = in.readLine(); - in.close(); - isr.close(); - return result.toCharArray(); - } catch (IOException e) { - throw new ParameterException(e); - } + getConsole().print(description + ": "); + return getConsole().readPassword(); } private String[] subArray(String[] args, int index) { @@ -808,7 +802,7 @@ public class JCommander { public void usage(String commandName) { StringBuilder sb = new StringBuilder(); usage(commandName, sb); - System.out.println(sb.toString()); + getConsole().println(sb.toString()); } /** @@ -858,12 +852,12 @@ public class JCommander { } /** - * Display a the help on System.out. + * Display the help on System.out. */ public void usage() { StringBuilder sb = new StringBuilder(); usage(sb); - System.out.println(sb.toString()); + getConsole().println(sb.toString()); } /** @@ -1005,7 +999,7 @@ public class JCommander { private void p(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { - System.out.println("[JCommander] " + string); + getConsole().println("[JCommander] " + string); } } @@ -1305,7 +1299,7 @@ public class JCommander { } return sb.toString(); } - + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 37376e7..0d85a6a 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -91,7 +91,7 @@ public class ParameterDescription { if (m_bundle != null) { m_description = m_bundle.getString(annotation.descriptionKey()); } else { -// System.out.println("Warning: field " + object.getClass() + "." + field.getName() +// JCommander.getConsole().println("Warning: field " + object.getClass() + "." + field.getName() // + " has a descriptionKey but no bundle was defined with @ResourceBundle, using " + // "default description:'" + m_description + "'"); } @@ -262,7 +262,7 @@ public class ParameterDescription { private static void p(String string) { if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { - System.out.println("[ParameterDescription] " + string); + JCommander.getConsole().println("[ParameterDescription] " + string); } } diff --git a/src/main/java/com/beust/jcommander/internal/Console.java b/src/main/java/com/beust/jcommander/internal/Console.java new file mode 100644 index 0000000..e2bddb3 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/Console.java @@ -0,0 +1,10 @@ +package com.beust.jcommander.internal; + +public interface Console { + + void print(String msg); + + void println(String msg); + + char[] readPassword(); +} diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java new file mode 100644 index 0000000..b838610 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java @@ -0,0 +1,33 @@ +package com.beust.jcommander.internal; + +import com.beust.jcommander.ParameterException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class DefaultConsole implements Console { + + public void print(String msg) { + System.out.print(msg); + } + + public void println(String msg) { + System.out.println(msg); + } + + public char[] readPassword() { + try { + InputStreamReader isr = new InputStreamReader(System.in); + BufferedReader in = new BufferedReader(isr); + String result = in.readLine(); + in.close(); + isr.close(); + return result.toCharArray(); + } + catch (IOException e) { + throw new ParameterException(e); + } + } + +} diff --git a/src/main/java/com/beust/jcommander/internal/JDK6Console.java b/src/main/java/com/beust/jcommander/internal/JDK6Console.java new file mode 100644 index 0000000..f0c60d2 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/JDK6Console.java @@ -0,0 +1,38 @@ +package com.beust.jcommander.internal; + +import com.beust.jcommander.ParameterException; + +import java.io.PrintWriter; +import java.lang.reflect.Method; + +public class JDK6Console implements Console { + + private Object console; + + private PrintWriter writer; + + public JDK6Console(Object console) throws Exception { + this.console = console; + Method writerMethod = console.getClass().getDeclaredMethod("writer", new Class[0]); + writer = (PrintWriter) writerMethod.invoke(console, new Object[0]); + } + + public void print(String msg) { + writer.print(msg); + } + + public void println(String msg) { + writer.println(msg); + } + + public char[] readPassword() { + try { + Method readPasswordMethod = console.getClass().getDeclaredMethod("readPassword", new Class[0]); + return (char[]) readPasswordMethod.invoke(console, new Object[0]); + } + catch (Exception e) { + throw new ParameterException(e); + } + } + +} -- cgit v1.2.3 From 932e1670f1993a228a0d85c8b27cfd4a6a065f6c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 15:13:29 -0800 Subject: First step implementing DynamicParameter. --- .../com/beust/jcommander/DynamicParameter.java | 37 +++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 23 ++++++++++ .../com/beust/jcommander/ParameterDescription.java | 52 +++++++++++++++------- .../java/com/beust/jcommander/internal/Maps.java | 8 ++++ .../java/com/beust/jcommander/dynamic/DSimple.java | 13 ++++++ .../jcommander/dynamic/DynamicParameterTest.java | 20 +++++++++ 6 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/DynamicParameter.java create mode 100644 src/test/java/com/beust/jcommander/dynamic/DSimple.java create mode 100644 src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java diff --git a/src/main/java/com/beust/jcommander/DynamicParameter.java b/src/main/java/com/beust/jcommander/DynamicParameter.java new file mode 100644 index 0000000..52a725c --- /dev/null +++ b/src/main/java/com/beust/jcommander/DynamicParameter.java @@ -0,0 +1,37 @@ +package com.beust.jcommander; + +import static java.lang.annotation.ElementType.FIELD; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@Target({ FIELD }) +public @interface DynamicParameter { + /** + * An array of allowed command line parameters (e.g. "-D", "--define", etc...). + */ + String[] names() default {}; + + /** + * How many parameter values this parameter will consume. For example, + * an arity of 0 allow "-Da=b", 1 allows "-D a=b" and 2, "-D a b". Larger + * arities are not allowed for dynamic parameters. + */ + int arity() default -1; + + /** + * Whether this option is required. + */ + boolean required() default false; + + /** + * A description of this option. + */ + String description() default ""; + + /** + * The key used to find the string in the message bundle. + */ + String descriptionKey() default ""; +} diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 9962b2f..6558d9e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -486,7 +486,11 @@ public class JCommander { f.setAccessible(true); Annotation annotation = f.getAnnotation(Parameter.class); Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class); + Annotation dynamicParameter = f.getAnnotation(DynamicParameter.class); if (annotation != null) { + // + // @Parameter + // Parameter p = (Parameter) annotation; if (p.names().length == 0) { p("Found main parameter:" + f); @@ -512,6 +516,9 @@ public class JCommander { } } } else if (delegateAnnotation != null) { + // + // @ParametersDelegate + // try { Object delegateObject = f.get(object); if (delegateObject == null){ @@ -520,6 +527,22 @@ public class JCommander { addDescription(delegateObject); } catch (IllegalAccessException e) { } + } else if (dynamicParameter != null) { + // + // @DynamicParameter + // + DynamicParameter dp = (DynamicParameter) dynamicParameter; + for (String name : dp.names()) { + if (m_descriptions.containsKey(name)) { + throw new ParameterException("Found the option " + name + " multiple times"); + } + p("Adding description for " + name); + ParameterDescription pd = new ParameterDescription(object, dp, f, m_bundle, this); + m_fields.put(f, pd); + m_descriptions.put(name, pd); + + if (dp.required()) m_requiredFields.put(f, pd); + } } } // Traverse the super class until we find Object.class diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 0d85a6a..af035dd 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -34,6 +34,7 @@ import java.util.TreeSet; public class ParameterDescription { private Object m_object; private Parameter m_parameterAnnotation; + private DynamicParameter m_dynamicParameterAnnotation; private Field m_field; /** Keep track of whether a value was added to flag an error */ private boolean m_assigned = false; @@ -44,9 +45,16 @@ public class ParameterDescription { /** Longest of the names(), used to present usage() alphabetically */ private String m_longestName = ""; + public ParameterDescription(Object object, DynamicParameter annotation, Field field, + ResourceBundle bundle, JCommander jc) { + m_dynamicParameterAnnotation = annotation; + init(object, field, bundle, jc); + } + public ParameterDescription(Object object, Parameter annotation, Field field, ResourceBundle bundle, JCommander jc) { - init(object, annotation, field, bundle, jc); + m_parameterAnnotation = annotation; + init(object, field, bundle, jc); } /** @@ -75,21 +83,11 @@ public class ParameterDescription { return s == null || "".equals(s); } - private void init(Object object, Parameter annotation, Field field, ResourceBundle bundle, - JCommander jCommander) { - m_object = object; - m_parameterAnnotation = annotation; - m_field = field; - m_bundle = bundle; - if (m_bundle == null) { - m_bundle = findResourceBundle(object); - } - m_jCommander = jCommander; - - m_description = annotation.description(); - if (! "".equals(annotation.descriptionKey())) { + private void initDescription(String description, String descriptionKey, String[] names) { + m_description = description; + if (! "".equals(descriptionKey)) { if (m_bundle != null) { - m_description = m_bundle.getString(annotation.descriptionKey()); + m_description = m_bundle.getString(descriptionKey); } else { // JCommander.getConsole().println("Warning: field " + object.getClass() + "." + field.getName() // + " has a descriptionKey but no bundle was defined with @ResourceBundle, using " + @@ -97,9 +95,31 @@ public class ParameterDescription { } } - for (String name : annotation.names()) { + for (String name : names) { if (name.length() > m_longestName.length()) m_longestName = name; } + } + + private void init(Object object, Field field, ResourceBundle bundle, + JCommander jCommander) { + m_object = object; + m_field = field; + m_bundle = bundle; + if (m_bundle == null) { + m_bundle = findResourceBundle(object); + } + m_jCommander = jCommander; + + if (m_parameterAnnotation != null) { + initDescription(m_parameterAnnotation.description(), m_parameterAnnotation.descriptionKey(), + m_parameterAnnotation.names()); + } else if (m_dynamicParameterAnnotation != null) { + initDescription(m_dynamicParameterAnnotation.description(), + m_dynamicParameterAnnotation.descriptionKey(), + m_dynamicParameterAnnotation.names()); + } else { + throw new AssertionError("Shound never happen"); + } try { m_default = m_field.get(m_object); diff --git a/src/main/java/com/beust/jcommander/internal/Maps.java b/src/main/java/com/beust/jcommander/internal/Maps.java index 9238aaa..e272122 100644 --- a/src/main/java/com/beust/jcommander/internal/Maps.java +++ b/src/main/java/com/beust/jcommander/internal/Maps.java @@ -32,4 +32,12 @@ public class Maps { return new LinkedHashMap(); } + public static Map newHashMap(T... parameters) { + Map result = Maps.newHashMap(); + for (int i = 0; i < parameters.length; i += 2) { + result.put(parameters[i], parameters[i + 1]); + } + return result; + } + } diff --git a/src/test/java/com/beust/jcommander/dynamic/DSimple.java b/src/test/java/com/beust/jcommander/dynamic/DSimple.java new file mode 100644 index 0000000..4fa7ab3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/dynamic/DSimple.java @@ -0,0 +1,13 @@ +package com.beust.jcommander.dynamic; + +import com.beust.jcommander.DynamicParameter; + +import org.testng.collections.Maps; + +import java.util.Map; + +public class DSimple { + + @DynamicParameter(names = "-D") + public Map params = Maps.newHashMap(); +} diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java new file mode 100644 index 0000000..68445dc --- /dev/null +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -0,0 +1,20 @@ +package com.beust.jcommander.dynamic; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.internal.Maps; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Map; + +public class DynamicParameterTest { + + @Test + public void simple() { + DSimple ds = new DSimple(); + new JCommander(ds).parse("-Da=b", "-Dc=d"); + Map expected = Maps.newHashMap("a", "b", "c", "d"); + Assert.assertEquals(ds.params, expected); + } +} -- cgit v1.2.3 From 78db59cfd11a5a1fb2eb4602f246b63dea91bf93 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 15:28:43 -0800 Subject: More DynamicParameter work. --- .../com/beust/jcommander/DynamicParameter.java | 5 +++ .../com/beust/jcommander/ParameterDescription.java | 22 ++++++++---- .../com/beust/jcommander/WrappedParameter.java | 41 ++++++++++++++++++++++ .../jcommander/dynamic/DynamicParameterTest.java | 6 +++- 4 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/WrappedParameter.java diff --git a/src/main/java/com/beust/jcommander/DynamicParameter.java b/src/main/java/com/beust/jcommander/DynamicParameter.java index 52a725c..642ab55 100644 --- a/src/main/java/com/beust/jcommander/DynamicParameter.java +++ b/src/main/java/com/beust/jcommander/DynamicParameter.java @@ -34,4 +34,9 @@ public @interface DynamicParameter { * The key used to find the string in the message bundle. */ String descriptionKey() default ""; + + /** + * If true, this parameter won't appear in the usage(). + */ + boolean hidden() default false; } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index af035dd..524b2fa 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -33,8 +33,11 @@ import java.util.TreeSet; public class ParameterDescription { private Object m_object; + + private WrappedParameter m_wrappedParameter; private Parameter m_parameterAnnotation; private DynamicParameter m_dynamicParameterAnnotation; + private Field m_field; /** Keep track of whether a value was added to flag an error */ private boolean m_assigned = false; @@ -48,12 +51,14 @@ public class ParameterDescription { public ParameterDescription(Object object, DynamicParameter annotation, Field field, ResourceBundle bundle, JCommander jc) { m_dynamicParameterAnnotation = annotation; + m_wrappedParameter = new WrappedParameter(m_dynamicParameterAnnotation); init(object, field, bundle, jc); } public ParameterDescription(Object object, Parameter annotation, Field field, ResourceBundle bundle, JCommander jc) { m_parameterAnnotation = annotation; + m_wrappedParameter = new WrappedParameter(m_parameterAnnotation); init(object, field, bundle, jc); } @@ -130,12 +135,17 @@ public class ParameterDescription { // Validate default values, if any and if applicable // if (m_default != null) { - String[] names = m_parameterAnnotation.names(); - String name = names.length > 0 ? names[0] : ""; - validateParameter(name, m_default.toString()); + if (m_parameterAnnotation != null) { + validateDefaultValues(m_parameterAnnotation.names()); + } } } + private void validateDefaultValues(String[] names) { + String name = names.length > 0 ? names[0] : ""; + validateParameter(name, m_default.toString()); + } + public String getLongestName() { return m_longestName; } @@ -163,8 +173,8 @@ public class ParameterDescription { return sb.toString(); } - public Parameter getParameter() { - return m_parameterAnnotation; + WrappedParameter getParameter() { + return m_wrappedParameter; } public Field getField() { @@ -200,7 +210,7 @@ public class ParameterDescription { public void addValue(String value, boolean isDefault) { p("Adding " + (isDefault ? "default " : "") + "value:" + value + " to parameter:" + m_field.getName()); - String name = m_parameterAnnotation.names()[0]; + String name = m_wrappedParameter.names()[0]; if (m_assigned && ! isMultiOption()) { throw new ParameterException("Can only specify option " + name + " once."); diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java new file mode 100644 index 0000000..59beb15 --- /dev/null +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -0,0 +1,41 @@ +package com.beust.jcommander; + +/** + * Encapsulates the operations common to @Parameter and @DynamicParameter + */ +public class WrappedParameter { + private Parameter m_parameter; + private DynamicParameter m_dynamicParameter; + + public WrappedParameter(Parameter p) { + m_parameter = p; + } + + public WrappedParameter(DynamicParameter p) { + m_dynamicParameter = p; + } + + public int arity() { + return m_parameter != null ? m_parameter.arity() : m_dynamicParameter.arity(); + } + + public boolean hidden() { + return m_parameter != null ? m_parameter.hidden() : m_dynamicParameter.hidden(); + } + + public boolean required() { + return m_parameter != null ? m_parameter.required() : m_dynamicParameter.required(); + } + + public boolean password() { + return m_parameter != null ? m_parameter.password() : false; + } + + public String[] names() { + return m_parameter != null ? m_parameter.names() : m_dynamicParameter.names(); + } + + public boolean variableArity() { + return m_parameter != null ? m_parameter.variableArity() : false; + } +} diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java index 68445dc..65cce92 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -13,8 +13,12 @@ public class DynamicParameterTest { @Test public void simple() { DSimple ds = new DSimple(); - new JCommander(ds).parse("-Da=b", "-Dc=d"); + new JCommander(ds).parse("-D", "a=b", "-D", "c=d"); Map expected = Maps.newHashMap("a", "b", "c", "d"); Assert.assertEquals(ds.params, expected); } + + public static void main(String[] args) { + new DynamicParameterTest().simple(); + } } -- cgit v1.2.3 From 5d1bc481ba97db04a176ecf07e3e7444ec9ab031 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 15:28:51 -0800 Subject: gitignore. --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 387cacf..41d1df2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ target .classpath .project -.settings \ No newline at end of file +.settings +test-output -- cgit v1.2.3 From 043d359ca700da0f541f849157d7db2b1b6f93fb Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 16:07:21 -0800 Subject: Working @DynamicParameter. --- .../com/beust/jcommander/DynamicParameter.java | 12 ++++++ src/main/java/com/beust/jcommander/JCommander.java | 7 +++- .../com/beust/jcommander/ParameterDescription.java | 25 +++++++++--- .../com/beust/jcommander/WrappedParameter.java | 44 ++++++++++++++++++++++ .../com/beust/jcommander/dynamic/DSimpleBad.java | 11 ++++++ .../jcommander/dynamic/DynamicParameterTest.java | 18 ++++++++- src/test/resources/testng.xml | 1 + 7 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/dynamic/DSimpleBad.java diff --git a/src/main/java/com/beust/jcommander/DynamicParameter.java b/src/main/java/com/beust/jcommander/DynamicParameter.java index 642ab55..32b68b4 100644 --- a/src/main/java/com/beust/jcommander/DynamicParameter.java +++ b/src/main/java/com/beust/jcommander/DynamicParameter.java @@ -2,6 +2,8 @@ package com.beust.jcommander; import static java.lang.annotation.ElementType.FIELD; +import com.beust.jcommander.validators.NoValidator; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -39,4 +41,14 @@ public @interface DynamicParameter { * If true, this parameter won't appear in the usage(). */ boolean hidden() default false; + + /** + * The validation class to use. + */ + Class validateWith() default NoValidator.class; + + /** + * The character(s) used to assign the values. + */ + String assignment() default "="; } diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 6558d9e..ce138b4 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -634,7 +634,8 @@ public class JCommander { } } - ParameterDescription.validateParameter(m_mainParameterAnnotation, "Default", value); + ParameterDescription.validateParameter(m_mainParameterAnnotation.validateWith(), + "Default", value); m_mainParameterDescription.setAssigned(true); mp.add(convertedValue); @@ -1061,6 +1062,10 @@ public class JCommander { */ public Object convertValue(Field field, Class type, String value) { Parameter annotation = field.getAnnotation(Parameter.class); + + // Do nothing if it's a @DynamicParameter + if (annotation == null) return value; + Class> converterClass = annotation.converter(); boolean listConverterWasSpecified = annotation.listConverter() != NoConverter.class; diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 524b2fa..7c83824 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -18,7 +18,6 @@ package com.beust.jcommander; - import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; @@ -26,6 +25,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import java.util.SortedSet; @@ -50,6 +50,11 @@ public class ParameterDescription { public ParameterDescription(Object object, DynamicParameter annotation, Field field, ResourceBundle bundle, JCommander jc) { + if (! Map.class.isAssignableFrom(field.getType())) { + throw new ParameterException("@DynamicParameter " + field.getName() + " should be of type " + + "Map but is " + field.getType().getName()); + } + m_dynamicParameterAnnotation = annotation; m_wrappedParameter = new WrappedParameter(m_dynamicParameterAnnotation); init(object, field, bundle, jc); @@ -183,7 +188,12 @@ public class ParameterDescription { private boolean isMultiOption() { Class fieldType = m_field.getType(); - return fieldType.equals(List.class) || fieldType.equals(Set.class); + return fieldType.equals(List.class) || fieldType.equals(Set.class) + || isDynamicParameter(m_field); + } + + private boolean isDynamicParameter(Field field) { + return field.getAnnotation(DynamicParameter.class) != null; } public void addValue(String value) { @@ -239,7 +249,7 @@ public class ParameterDescription { // l. } } else { - m_field.set(m_object, convertedValue); + m_wrappedParameter.addValue(m_field, m_object, convertedValue); } if (! isDefault) m_assigned = true; } @@ -249,11 +259,14 @@ public class ParameterDescription { } private void validateParameter(String name, String value) { - validateParameter(m_parameterAnnotation, name, value); + Class validator = m_wrappedParameter.validateWith(); + if (validator != null) { + validateParameter(validator, name, value); + } } - public static void validateParameter(Parameter annotation, String name, String value) { - Class validator = annotation.validateWith(); + public static void validateParameter(Class validator, + String name, String value) { try { p("Validating parameter:" + name + " value:" + value + " validator:" + validator); validator.newInstance().validate(name, value); diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index 59beb15..f603880 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -1,5 +1,9 @@ package com.beust.jcommander; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + /** * Encapsulates the operations common to @Parameter and @DynamicParameter */ @@ -38,4 +42,44 @@ public class WrappedParameter { public boolean variableArity() { return m_parameter != null ? m_parameter.variableArity() : false; } + + public Class validateWith() { + return m_parameter != null ? m_parameter.validateWith() : m_dynamicParameter.validateWith(); + } + + public void addValue(Field field, Object object, Object value) + throws IllegalArgumentException, IllegalAccessException { + if (m_parameter != null) { + field.set(object, value); + } else { + String a = m_dynamicParameter.assignment(); + String sv = value.toString(); + String[] kv = sv.split(a); + if (kv.length != 2) { + throw new ParameterException("Dynamic parameter expected a value of the form a" + a + "b" + + " but got:" + sv); + } + callPut(object, field, kv[0], kv[1]); + } + } + + private void callPut(Object object, Field field, String key, String value) { + try { + Method m; + m = findPut(field.getType()); + m.invoke(field.get(object), key, value); + } catch (SecurityException e) { + e.printStackTrace(); + } catch(IllegalAccessException e) { + e.printStackTrace(); + } catch(InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + + private Method findPut(Class cls) throws SecurityException, NoSuchMethodException { + return cls.getMethod("put", Object.class, Object.class); + } } diff --git a/src/test/java/com/beust/jcommander/dynamic/DSimpleBad.java b/src/test/java/com/beust/jcommander/dynamic/DSimpleBad.java new file mode 100644 index 0000000..f859029 --- /dev/null +++ b/src/test/java/com/beust/jcommander/dynamic/DSimpleBad.java @@ -0,0 +1,11 @@ +package com.beust.jcommander.dynamic; + +import com.beust.jcommander.DynamicParameter; + +import java.util.List; + +public class DSimpleBad { + + @DynamicParameter(names = "-D") + public List params; +} diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java index 65cce92..0a7cb25 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -1,6 +1,7 @@ package com.beust.jcommander.dynamic; import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; import com.beust.jcommander.internal.Maps; import org.testng.Assert; @@ -10,6 +11,18 @@ import java.util.Map; public class DynamicParameterTest { + // test using the wrong separator + @Test(expectedExceptions = ParameterException.class) + public void nonMapShouldThrow() { + new JCommander(new DSimpleBad()).parse("-D", "a=b", "-D", "c=d"); + } + + @Test + public void wrongSeparatorShouldThrow() { + DSimple ds = new DSimple(); + new JCommander(ds).parse("-D", "a:b", "-D", "c=d"); + } + @Test public void simple() { DSimple ds = new DSimple(); @@ -19,6 +32,9 @@ public class DynamicParameterTest { } public static void main(String[] args) { - new DynamicParameterTest().simple(); + DynamicParameterTest dpt = new DynamicParameterTest(); +// new DynamicParameterTest().simple(); +// dpt.nonMapShouldThrow(); + dpt.wrongSeparatorShouldThrow(); } } diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 2b99230..a99ad0d 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -11,6 +11,7 @@ + -- cgit v1.2.3 From b71c28f84999d1eeb2251d7c283e9b86fbf6fcba Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 16:11:42 -0800 Subject: More tests. --- src/test/java/com/beust/jcommander/dynamic/DSimple.java | 3 +++ .../beust/jcommander/dynamic/DynamicParameterTest.java | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/beust/jcommander/dynamic/DSimple.java b/src/test/java/com/beust/jcommander/dynamic/DSimple.java index 4fa7ab3..3d77f32 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DSimple.java +++ b/src/test/java/com/beust/jcommander/dynamic/DSimple.java @@ -10,4 +10,7 @@ public class DSimple { @DynamicParameter(names = "-D") public Map params = Maps.newHashMap(); + + @DynamicParameter(names = "-A", assignment = "@") + public Map params2 = Maps.newHashMap(); } diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java index 0a7cb25..3d9d5de 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -17,7 +17,7 @@ public class DynamicParameterTest { new JCommander(new DSimpleBad()).parse("-D", "a=b", "-D", "c=d"); } - @Test + @Test(expectedExceptions = ParameterException.class) public void wrongSeparatorShouldThrow() { DSimple ds = new DSimple(); new JCommander(ds).parse("-D", "a:b", "-D", "c=d"); @@ -31,10 +31,19 @@ public class DynamicParameterTest { Assert.assertEquals(ds.params, expected); } + @Test + public void differentAssignment() { + DSimple ds = new DSimple(); + new JCommander(ds).parse("-D", "a=b", "-A", "c@d"); + Assert.assertEquals(ds.params, Maps.newHashMap("a", "b")); + Assert.assertEquals(ds.params2, Maps.newHashMap("c", "d")); + } + public static void main(String[] args) { DynamicParameterTest dpt = new DynamicParameterTest(); -// new DynamicParameterTest().simple(); + dpt.simple(); // dpt.nonMapShouldThrow(); - dpt.wrongSeparatorShouldThrow(); +// dpt.wrongSeparatorShouldThrow(); + dpt.differentAssignment(); } } -- cgit v1.2.3 From 7e743acbff5277d087347bfba2409406865af8a0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 16:48:33 -0800 Subject: Automatic handling of arities for @DynamicParameter. --- .../com/beust/jcommander/DynamicParameter.java | 7 ------- src/main/java/com/beust/jcommander/JCommander.java | 18 ++++++++++++++-- .../com/beust/jcommander/ParameterDescription.java | 4 ++++ .../com/beust/jcommander/WrappedParameter.java | 2 +- .../java/com/beust/jcommander/JCommanderTest.java | 18 ++++++++-------- .../jcommander/dynamic/DynamicParameterTest.java | 24 ++++++++++++++-------- 6 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/beust/jcommander/DynamicParameter.java b/src/main/java/com/beust/jcommander/DynamicParameter.java index 32b68b4..77b8632 100644 --- a/src/main/java/com/beust/jcommander/DynamicParameter.java +++ b/src/main/java/com/beust/jcommander/DynamicParameter.java @@ -15,13 +15,6 @@ public @interface DynamicParameter { */ String[] names() default {}; - /** - * How many parameter values this parameter will consume. For example, - * an arity of 0 allow "-Da=b", 1 allows "-D a=b" and 2, "-D a b". Larger - * arities are not allowed for dynamic parameters. - */ - int arity() default -1; - /** * Whether this option is required. */ diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index ce138b4..d94c3df 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -338,11 +338,11 @@ public class JCommander { vResult1.addAll(readFile(fileName)); } else { - vResult1.add(arg); + List expanded = expandDynamicArg(arg); + vResult1.addAll(expanded); } } - // // Expand separators // List vResult2 = Lists.newArrayList(); @@ -367,6 +367,20 @@ public class JCommander { return vResult2.toArray(new String[vResult2.size()]); } + private List expandDynamicArg(String arg) { + for (ParameterDescription pd : m_descriptions.values()) { + if (pd.isDynamicParameter()) { + for (String name : pd.getParameter().names()) { + if (arg.startsWith(name) && !arg.equals(name)) { + return Arrays.asList(name, arg.substring(name.length())); + } + } + } + } + + return Arrays.asList(arg); + } + private boolean isOption(String[] args, String arg) { String prefixes = getOptionPrefixes(args, arg); return prefixes.indexOf(arg.charAt(0)) >= 0; diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 7c83824..008e12a 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -313,4 +313,8 @@ public class ParameterDescription { public String toString() { return "[ParameterDescription " + m_field.getName() + "]"; } + + public boolean isDynamicParameter() { + return m_dynamicParameterAnnotation != null; + } } diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index f603880..a9b3df5 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -20,7 +20,7 @@ public class WrappedParameter { } public int arity() { - return m_parameter != null ? m_parameter.arity() : m_dynamicParameter.arity(); + return m_parameter != null ? m_parameter.arity() : 1; } public boolean hidden() { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index ed2c779..4f1a6d5 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -619,15 +619,15 @@ public class JCommanderTest { public static void main(String[] args) throws Exception { System.out.println("A"); -// class A { -// @Parameter -// List parameters; -// -// @Parameter(names = "-long") -// public long l; -// } -// A a = new A(); -// new JCommander(a).parse("-lon", "32"); + class A { + @Parameter + List parameters; + + @Parameter(names = "-long") + public long l; + } + A a = new A(); + new JCommander(a).parse("-long", "32"); // System.out.println(a.l); // System.out.println(a.parameters); // ArgsList al = new ArgsList(); diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java index 3d9d5de..5e1728f 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -7,11 +7,8 @@ import com.beust.jcommander.internal.Maps; import org.testng.Assert; import org.testng.annotations.Test; -import java.util.Map; - public class DynamicParameterTest { - // test using the wrong separator @Test(expectedExceptions = ParameterException.class) public void nonMapShouldThrow() { new JCommander(new DSimpleBad()).parse("-D", "a=b", "-D", "c=d"); @@ -23,12 +20,20 @@ public class DynamicParameterTest { new JCommander(ds).parse("-D", "a:b", "-D", "c=d"); } - @Test - public void simple() { + private void simple(String... parameters) { DSimple ds = new DSimple(); - new JCommander(ds).parse("-D", "a=b", "-D", "c=d"); - Map expected = Maps.newHashMap("a", "b", "c", "d"); - Assert.assertEquals(ds.params, expected); + new JCommander(ds).parse(parameters); + Assert.assertEquals(ds.params, Maps.newHashMap("a", "b", "c", "d")); + } + + @Test + public void simpleWithSpaces() { + simple("-D", "a=b", "-D", "c=d"); + } + + @Test + public void simpleWithoutSpaces() { + simple("-Da=b", "-Dc=d"); } @Test @@ -41,9 +46,10 @@ public class DynamicParameterTest { public static void main(String[] args) { DynamicParameterTest dpt = new DynamicParameterTest(); - dpt.simple(); +// dpt.simple(); // dpt.nonMapShouldThrow(); // dpt.wrongSeparatorShouldThrow(); dpt.differentAssignment(); +// dpt.arity0(); } } -- cgit v1.2.3 From a559c60fb0a865cbfb448b64415e091523d4d295 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 10 Jan 2012 16:49:06 -0800 Subject: Added: @DynamicParameter. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index a1a323d..16b2a5f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: @DynamicParameter Fixed: Use JDK 6 Console() when available to improve support of non ascii chars (Julien Henry) 1.20 -- cgit v1.2.3 From e923414889a04be46c131af01dbe466d10f10721 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 10:22:37 -0800 Subject: Fixed NPE in usage(). --- .../java/com/beust/jcommander/ParameterDescription.java | 2 +- src/test/java/com/beust/jcommander/dynamic/DSimple.java | 2 +- .../com/beust/jcommander/dynamic/DynamicParameterTest.java | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 008e12a..bf2f3c7 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -169,7 +169,7 @@ public class ParameterDescription { public String getNames() { StringBuilder sb = new StringBuilder(); - String[] names = m_parameterAnnotation.names(); + String[] names = m_wrappedParameter.names(); for (int i = 0; i < names.length; i++) { if (i > 0) sb.append(", "); if (names.length == 1 && names[i].startsWith("--")) sb.append(" "); diff --git a/src/test/java/com/beust/jcommander/dynamic/DSimple.java b/src/test/java/com/beust/jcommander/dynamic/DSimple.java index 3d77f32..deb5a2b 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DSimple.java +++ b/src/test/java/com/beust/jcommander/dynamic/DSimple.java @@ -8,7 +8,7 @@ import java.util.Map; public class DSimple { - @DynamicParameter(names = "-D") + @DynamicParameter(names = "-D", description = "Dynamic parameters go here") public Map params = Maps.newHashMap(); @DynamicParameter(names = "-A", assignment = "@") diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java index 5e1728f..190b8b4 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -7,6 +7,7 @@ import com.beust.jcommander.internal.Maps; import org.testng.Assert; import org.testng.annotations.Test; +@Test public class DynamicParameterTest { @Test(expectedExceptions = ParameterException.class) @@ -26,17 +27,19 @@ public class DynamicParameterTest { Assert.assertEquals(ds.params, Maps.newHashMap("a", "b", "c", "d")); } - @Test public void simpleWithSpaces() { simple("-D", "a=b", "-D", "c=d"); } - @Test public void simpleWithoutSpaces() { simple("-Da=b", "-Dc=d"); } - @Test + public void usage() { + DSimple ds = new DSimple(); + new JCommander(ds).usage(new StringBuilder()); + } + public void differentAssignment() { DSimple ds = new DSimple(); new JCommander(ds).parse("-D", "a=b", "-A", "c@d"); @@ -44,12 +47,14 @@ public class DynamicParameterTest { Assert.assertEquals(ds.params2, Maps.newHashMap("c", "d")); } + @Test(enabled = false) public static void main(String[] args) { DynamicParameterTest dpt = new DynamicParameterTest(); // dpt.simple(); // dpt.nonMapShouldThrow(); // dpt.wrongSeparatorShouldThrow(); - dpt.differentAssignment(); +// dpt.differentAssignment(); // dpt.arity0(); + dpt.usage(); } } -- cgit v1.2.3 From ef85e832405933f6897893581a3df908e9e2a432 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:35:22 -0800 Subject: Show the dynamic parameter syntax in the usage. --- src/main/java/com/beust/jcommander/JCommander.java | 15 ++++++++++++--- src/main/java/com/beust/jcommander/WrappedParameter.java | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index d94c3df..e2ca5a6 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -949,14 +949,23 @@ public class JCommander { int l = pd.getNames().length(); int spaceCount = longestName - l; int start = out.length(); + WrappedParameter parameter = pd.getParameter(); out.append(indent).append(" " - + (pd.getParameter().required() ? "* " : " ") + + (parameter.required() ? "* " : " ") + pd.getNames() + s(spaceCount)); int indentCount = out.length() - start; wrapDescription(out, indentCount, pd.getDescription()); Object def = pd.getDefault(); - if (def != null) out.append("\n" + spaces(indentCount + 1)) - .append("Default: " + def); + if (pd.isDynamicParameter()) { + out.append("\n" + spaces(indentCount + 1)) + .append("Syntax: " + parameter.names()[0] + + "key" + parameter.getAssignment() + + "value"); + } + if (def != null && ! "".equals(def)) { + out.append("\n" + spaces(indentCount + 1)) + .append("Default: " + def); + } out.append("\n"); } diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index a9b3df5..bba888f 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -82,4 +82,8 @@ public class WrappedParameter { private Method findPut(Class cls) throws SecurityException, NoSuchMethodException { return cls.getMethod("put", Object.class, Object.class); } + + public String getAssignment() { + return m_dynamicParameter != null ? m_dynamicParameter.assignment() : ""; + } } -- cgit v1.2.3 From bb90ac944d6f783217afa5847360cc723da885d2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:36:16 -0800 Subject: Updated TestNG to 6.4beta. --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index 5a6a9f8..b281494 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.3.2beta +v=6.4beta export TESTNG=../testng/target/testng-${v}.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From 82241ebd6be1231463509bfede2cd1cf707682d7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:39:08 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.21 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 412b7f4..5d49016 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.21-SNAPSHOT + 1.21 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From cf210210029518727d65a955836f93c642a5ec5d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:39:12 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d49016..934a52d 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.21 + 1.22-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From dc5ad86a31ec259d082eb82496e6a60a769a531c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:41:40 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.22 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 934a52d..854024d 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.22-SNAPSHOT + 1.22 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 13fa783709b4493f984854cd4f78db2faa02d500 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:41:44 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 854024d..f566a6e 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.22 + 1.23-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 107d0fba6ecf0434da07b54466aea10d8b05000f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:43:57 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.23 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f566a6e..d6b89f4 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.23-SNAPSHOT + 1.23 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From b01c46b9b0943599453c3cf2a50e0f1b2a043d3b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 12:44:02 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d6b89f4..ec7cacf 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.23 + 1.24-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 4dd0aec64cc5ea787e2a15246f50eb891ce3a5f5 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 11 Jan 2012 13:30:02 -0800 Subject: Doc for @DynamicParameter. --- doc/index.html | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 4b2b9eb..5d4d426 100644 --- a/doc/index.html +++ b/doc/index.html @@ -5,7 +5,6 @@ - @@ -676,6 +675,17 @@ Assert.assertTrue(p.isVerbose); Assert.assertEquals(p.delegate.port, 1234); +

            Dynamic parameters

            + +JCommander allows you to specify parameters that are not known at compile time, such as "-Da=b -Dc=d". Such parameters are specified with the @DynamicParameter annotation and must be of type Map<String, String>. Dynamic parameters are allowed to appear multiple times on the command line: + +
            +@DynamicParameter(names = "-D", description = "Dynamic parameters go here")
            +public Map<String, String> params = Maps.newHashMap();
            +
            + +You can specify a different assignment string than = by using the attribute assignment. +

            JCommander in Scala

            Here is a quick example of how to use JCommander in Scala (courtesy of Patrick Linskey): @@ -741,5 +751,6 @@ You can download JCommander from the following locations: + -- cgit v1.2.3 From 8ad02daa23243bf515009d16205465f1b811da81 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 12 Jan 2012 13:23:58 -0800 Subject: Fixed: Commands with same prefix as options were not working properly. --- CHANGELOG | 5 +++ src/main/java/com/beust/jcommander/JCommander.java | 4 +-- .../java/com/beust/jcommander/JCommanderTest.java | 42 ++++++++++++++++------ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 16b2a5f..f76d267 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ Current +Fixed: Commands with same prefix as options were not working properly. + +1.23 +2012/01/12 + Added: @DynamicParameter Fixed: Use JDK 6 Console() when available to improve support of non ascii chars (Julien Henry) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index e2ca5a6..cfa23e1 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -587,7 +587,8 @@ public class JCommander { String a = trim(arg); p("Parsing arg:" + a); - if (isOption(args, a)) { + JCommander jc = findCommandByAlias(arg); + if (isOption(args, a) && jc == null) { // // Option // @@ -658,7 +659,6 @@ public class JCommander { // // Command parsing // - JCommander jc = findCommandByAlias(arg); if (jc == null) throw new MissingCommandException("Expected a command, got " + arg); m_parsedCommand = jc.m_programName.m_name; m_parsedAlias = arg; //preserve the original form diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 4f1a6d5..02a7099 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -615,19 +615,39 @@ public class JCommanderTest { new JCommander(a).parse("b"); } - @Test(enabled = false) - public static void main(String[] args) throws Exception { + @Parameters(commandNames = { "--configure" }) + public static class ConfigureArgs { + } - System.out.println("A"); - class A { - @Parameter - List parameters; + public static class BaseArgs { + @Parameter(names = { "-h", "--help" }, description = "Show this help screen") + private boolean help = false; - @Parameter(names = "-long") - public long l; - } - A a = new A(); - new JCommander(a).parse("-long", "32"); + @Parameter(names = { "--version", "-version" }, description = "Show the program version") + private boolean version; + } + + public void commandsWithSamePrefixAsOptionsShouldWork() { + BaseArgs a = new BaseArgs(); + ConfigureArgs conf = new ConfigureArgs(); + JCommander jc = new JCommander(a); + jc.addCommand(conf); + jc.parse("--configure"); + } + + @Test(enabled = false) + public static void main(String[] args) throws Exception { +// System.out.println("Help:" + a.help); +// System.out.println("A"); +// class A { +// @Parameter +// List parameters; +// +// @Parameter(names = "-long") +// public long l; +// } +// A a = new A(); +// new JCommander(a).parse("-long", "32"); // System.out.println(a.l); // System.out.println(a.parameters); // ArgsList al = new ArgsList(); -- cgit v1.2.3 From 16f5c5a4f243f84f6ddd071304b8c8fcacfe8348 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 13 Jan 2012 15:27:36 -0800 Subject: Updated license --- license.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/license.txt b/license.txt index 6b0b127..d0c18cf 100755 --- a/license.txt +++ b/license.txt @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2012, Cedric Beust Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -- cgit v1.2.3 From fbed631f8555c52924a4d5341928a5bfa8762ea7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 13 Jan 2012 15:28:44 -0800 Subject: Merge --- doc/index.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/index.html b/doc/index.html index 5d4d426..187b9a4 100644 --- a/doc/index.html +++ b/doc/index.html @@ -2,8 +2,12 @@ JCommander - + + + @@ -13,15 +17,15 @@ + - - + + + +
            -- cgit v1.2.3 From e638e888f98a59dfeea1870c780582b4c68055fc Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 18 Jan 2012 10:19:08 -0800 Subject: Made the fields private in the doc. --- doc/index.html | 67 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/doc/index.html b/doc/index.html index 187b9a4..29f117a 100644 --- a/doc/index.html +++ b/doc/index.html @@ -25,7 +25,6 @@ - + + +
            @@ -58,16 +57,16 @@ import com.beust.jcommander.Parameter; public class JCommanderExample { @Parameter - public List<String> parameters = Lists.newArrayList(); + private List<String> parameters = Lists.newArrayList(); @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") - public Integer verbose = 1; + private Integer verbose = 1; @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; + private String groups; @Parameter(names = "-debug", description = "Debug mode") - public boolean debug = false; + private boolean debug = false; } @@ -91,7 +90,7 @@ When a Parameter annotation is found on a field of type boolean @Parameter(names = "-debug", description = "Debug mode") -public boolean debug = false; +private boolean debug = false; Such a parameter does not require any additional parameter on the command line and if it's detected during parsing, the corresponding field will be set to true. @@ -102,7 +101,7 @@ When a Parameter annotation is found on a field of type String
             @Parameter(names = "-log", description = "Level of verbosity")
            -public Integer verbose = 1;
            +private Integer verbose = 1;
             
            @@ -123,7 +122,7 @@ When a Parameter annotation is found on a field of type List,
             
             
             @Parameter(names = "-host", description = "The host")
            -public List<String> hosts = new ArrayList<String>();
            +private List<String> hosts = new ArrayList<String>();
             
            will allow you to parse the following command line: @@ -141,7 +140,7 @@ If one of your parameters is a password or some other value that you do not wish
             public class ArgsPassword {
               @Parameter(names = "-password", description = "Connection password", password = true)
            -  public String password;
            +  private String password;
             }
             
            @@ -170,7 +169,7 @@ For example, here is a converter that turns a string into a File:
             public class FileConverter implements IStringConverter<File> {
               @Override
            -  public File convert(String value) {
            +  private File convert(String value) {
                 return new File(value);
               }
             }
            @@ -205,8 +204,8 @@ You define the holder class :
             
             
             public class HostPort {
            -  public String host;
            -  public Integer port;
            +  private String host;
            +  private Integer port;
             }
             
            @@ -241,7 +240,7 @@ You can now use the type HostPort as a parameter without any conver
             public class ArgsConverterFactory {
               @Parameter(names = "-hostport")
            -  public HostPort hostPort;
            +  private HostPort hostPort;
             }
             
            @@ -298,7 +297,7 @@ Specify the name of a class implementing this interface in the validateWith<
             @Parameter(names = "-age", validateWith = PositiveInteger.class)
            -public Integer age;
            +private Integer age;
             
            Attempting to pass a negative integer to this option will cause a ParameterException to be thrown. @@ -309,10 +308,10 @@ So far, all the @Parameter annotations we have seen had defined an attr
             @Parameter(description = "Files")
            -public List<String> files = new ArrayList<String>();
            +private List<String> files = new ArrayList<String>();
             
             @Parameter(names = "-debug", description = "Debugging level")
            -public Integer debug = 1;
            +private Integer debug = 1;
             
            will allow you to parse: @@ -364,7 +363,7 @@ You define the separator with the @Parameters annotation: @Parameters(separators = "=") public class SeparatorEqual { @Parameter(names = "-level") - public Integer level = 2; + private Integer level = 2; }
            @@ -383,7 +382,7 @@ class. For example, you can define the following two classes:
             public class ArgsMaster {
               @Parameter(names = "-master")
            -  public String master;
            +  private String master;
             }
             
            @@ -391,7 +390,7 @@ public class ArgsMaster {
             public class ArgsSlave {
               @Parameter(names = "-slave")
            -  public String slave;
            +  private String slave;
             }
             
            @@ -439,7 +438,7 @@ attribute and make that parameter a List<String>:
             @Parameter(names = "-pairs", arity = 2, description = "Pairs")
            -public List<String> pairs;
            +private List<String> pairs;
             
            You don't need to specify an arity for parameters of type @@ -460,7 +459,7 @@ You can specify more than one option name:
             
               @Parameter(names = { "-d", "--outputDirectory" }, description = "Directory")
            -  public String outputDirectory;
            +  private String outputDirectory;
             
             
            @@ -479,7 +478,7 @@ If some of your parameters are mandatory, you can use the
             
               @Parameter(names = "-host", required = true)
            -  public String host;
            +  private String host;
             
             
            @@ -540,16 +539,16 @@ Words such as "commit" above are called "commands" in JCommander, and you can sp
             @Parameters(separators = "=", commandDescription = "Record changes to the repository")
            -public class CommandCommit {
            +private class CommandCommit {
             
               @Parameter(description = "The list of files to commit")
            -  public List<String> files;
            +  private List<String> files;
             
               @Parameter(names = "--amend", description = "Amend")
            -  public Boolean amend = false;
            +  private Boolean amend = false;
             
               @Parameter(names = "--author")
            -  public String author;
            +  private String author;
             }
             
            @@ -558,10 +557,10 @@ public class CommandCommit { public class CommandAdd { @Parameter(description = "File patterns to add to the index") - public List<String> patterns; + private List<String> patterns; @Parameter(names = "-i") - public Boolean interactive = false; + private Boolean interactive = false; }
            @@ -616,7 +615,7 @@ If you don't want certain parameters to appear in the usage, you can mark them a
             @Parameter(names = "-debug", description = "Debug mode", hidden = true)
            -public boolean debug = false;
            +private boolean debug = false;
             

            Internationalization

            @@ -630,7 +629,7 @@ First you use the @Parameters annotation at the top of your class to de

            I18N.java

             @Parameters(resourceBundle = "MessageBundle")
            -public class ArgsI18N2 {
            +private class ArgsI18N2 {
               @Parameter(names = "-host", description = "Host", descriptionKey = "host")
               String hostName;
             }
            @@ -658,15 +657,15 @@ When JCommander encounters an object annotated with @ParameterDelegate
             
             class Delegate {
               @Parameter(names = "-port")
            -  public int port;
            +  private int port;
             }
             
             class MainParams {
               @Parameter(names = "-v")
            -  public boolean verbose;
            +  private boolean verbose;
             
               @ParametersDelegate
            -  public Delegate delegate = new Delegate();
            +  private Delegate delegate = new Delegate();
             }
             
            @@ -685,7 +684,7 @@ JCommander allows you to specify parameters that are not known at compile time,
             @DynamicParameter(names = "-D", description = "Dynamic parameters go here")
            -public Map<String, String> params = Maps.newHashMap();
            +private Map<String, String> params = Maps.newHashMap();
             
            You can specify a different assignment string than = by using the attribute assignment. -- cgit v1.2.3 From a47f3719a995dc5f5b75d2e384a549b73c229697 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 16 Feb 2012 21:45:14 -0800 Subject: Windows 7 fix: the password prompt doesn't appear until after the password is typed (Erik Costlow). --- src/main/java/com/beust/jcommander/internal/JDK6Console.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/beust/jcommander/internal/JDK6Console.java b/src/main/java/com/beust/jcommander/internal/JDK6Console.java index f0c60d2..62e2a1e 100644 --- a/src/main/java/com/beust/jcommander/internal/JDK6Console.java +++ b/src/main/java/com/beust/jcommander/internal/JDK6Console.java @@ -27,6 +27,7 @@ public class JDK6Console implements Console { public char[] readPassword() { try { + writer.flush(); Method readPasswordMethod = console.getClass().getDeclaredMethod("readPassword", new Class[0]); return (char[]) readPasswordMethod.invoke(console, new Object[0]); } -- cgit v1.2.3 From ed9375231cf2597f42c5da11bd4f0f14c0f09ee3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 16 Feb 2012 21:46:25 -0800 Subject: Using TestNG 6.4.1beta. --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index b281494..3b9ba12 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.4beta +v=6.4.1beta export TESTNG=../testng/target/testng-${v}.jar java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml -- cgit v1.2.3 From a3199885e5e515af41a01c4d693bf96f1dafbd67 Mon Sep 17 00:00:00 2001 From: Adrian Muraru Date: Sat, 25 Feb 2012 04:28:17 +0200 Subject: [Enum Args] If not set, the description of an enum arg is set to the list of options --- .../java/com/beust/jcommander/ParameterDescription.java | 9 ++++++++- src/test/java/com/beust/jcommander/JCommanderTest.java | 6 +++++- src/test/java/com/beust/jcommander/args/ArgsEnum.java | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index bf2f3c7..f90c6a5 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -21,6 +21,7 @@ package com.beust.jcommander; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -121,7 +122,13 @@ public class ParameterDescription { m_jCommander = jCommander; if (m_parameterAnnotation != null) { - initDescription(m_parameterAnnotation.description(), m_parameterAnnotation.descriptionKey(), + String description; + if (Enum.class.isAssignableFrom(field.getType()) && m_parameterAnnotation.description().isEmpty()) { + description = "Options: " + EnumSet.allOf((Class) field.getType()); + }else { + description = m_parameterAnnotation.description(); + } + initDescription(description, m_parameterAnnotation.descriptionKey(), m_parameterAnnotation.names()); } else if (m_dynamicParameterAnnotation != null) { initDescription(m_dynamicParameterAnnotation.description(), diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 02a7099..d2433e7 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -64,6 +64,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -556,9 +557,12 @@ public class JCommanderTest { public void enumArgs() { ArgsEnum args = new ArgsEnum(); String[] argv = { "-choice", "ONE"}; - new JCommander(args, argv); + JCommander jc = new JCommander(args, argv); Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE); + + Assert.assertEquals(jc.getParameters().get(0).getDescription(), "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); + } @Test(expectedExceptions = ParameterException.class) diff --git a/src/test/java/com/beust/jcommander/args/ArgsEnum.java b/src/test/java/com/beust/jcommander/args/ArgsEnum.java index 1d886e2..6661e37 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsEnum.java +++ b/src/test/java/com/beust/jcommander/args/ArgsEnum.java @@ -18,8 +18,13 @@ package com.beust.jcommander.args; +import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; +import org.testng.Assert; + +import java.util.EnumSet; + /** * Test enums. * @@ -28,8 +33,16 @@ import com.beust.jcommander.Parameter; public class ArgsEnum { public enum ChoiceType { ONE, TWO, THREE }; - @Parameter(names = "-choice", description = "Choice parameter") + @Parameter(names = "-choice") public ChoiceType choice = ChoiceType.ONE; + + public static void main(String[] args1) { + ArgsEnum args = new ArgsEnum(); + String[] argv = { "-choice", "ONE"}; + JCommander jc = new JCommander(args, argv); + jc.usage(); + Assert.assertEquals(jc.getParameters().get(0).getDescription(), "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); + } } -- cgit v1.2.3 From 39e431ec5e9c2505973a976f62a91e738b85fe4c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 25 Feb 2012 16:43:59 -0800 Subject: Fixed: GITHUB-97: Required password always complains that it is not specified (timoteoponce) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 1 + .../java/com/beust/jcommander/JCommanderTest.java | 29 ++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f76d267..2de2669 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Current Fixed: Commands with same prefix as options were not working properly. +Fixed: GITHUB-97: Required password always complains that it is not specified (timoteoponce) 1.23 2012/01/12 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index cfa23e1..9d8123a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -601,6 +601,7 @@ public class JCommander { // char[] password = readPassword(pd.getDescription()); pd.addValue(new String(password)); + m_requiredFields.remove(pd.getField()); } else { if (pd.getParameter().variableArity()) { // diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 02a7099..1562b14 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -56,9 +56,11 @@ import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -635,8 +637,35 @@ public class JCommanderTest { jc.parse("--configure"); } + // Tests: + // required unparsed parameter + @Test(enabled = false, + description = "For some reason, this test still asks the password on stdin") + public void askedRequiredPassword() { + class A { + @Parameter(names = { "--password", "-p" }, description = "Private key password", + password = true, required = true) + public String password; + + @Parameter(names = { "--port", "-o" }, description = "Port to bind server to", + required = true) + public int port; + } + A a = new A(); + InputStream stdin = System.in; + try { + System.setIn(new ByteArrayInputStream("password".getBytes())); + new JCommander(a,new String[]{"--port", "7","--password"}); + Assert.assertEquals(a.port, 7); + Assert.assertEquals(a.password, "password"); + } finally { + System.setIn(stdin); + } + } + @Test(enabled = false) public static void main(String[] args) throws Exception { + new JCommanderTest().askedRequiredPassword(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From ea2ebd84d4ac2c47706c4599f528f5263e199f0b Mon Sep 17 00:00:00 2001 From: evigeant Date: Sun, 26 Feb 2012 16:07:35 -0500 Subject: Fixed indentation on Options in command usage. --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 9d8123a..e257d22 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -945,7 +945,7 @@ public class JCommander { // // Display all the names and descriptions // - if (sorted.size() > 0) out.append(indent).append("\n Options:\n"); + if (sorted.size() > 0) out.append(indent).append("\n").append(indent).append(" Options:\n"); for (ParameterDescription pd : sorted) { int l = pd.getNames().length(); int spaceCount = longestName - l; -- cgit v1.2.3 From 8ebf58f752ae0703b70af57cecfe584968442558 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 10 Mar 2012 16:12:16 -0800 Subject: Fixed: GITHUB-108: Dynamic parameters with "=" in them are not parsed correctly (szhem) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/WrappedParameter.java | 12 +++++++----- src/test/java/com/beust/jcommander/JCommanderTest.java | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 2de2669..2ddb9ab 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: GITHUB-108: Dynamic parameters with "=" in them are not parsed correctly (szhem) Fixed: Commands with same prefix as options were not working properly. Fixed: GITHUB-97: Required password always complains that it is not specified (timoteoponce) diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index bba888f..ed7f198 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -54,12 +54,14 @@ public class WrappedParameter { } else { String a = m_dynamicParameter.assignment(); String sv = value.toString(); - String[] kv = sv.split(a); - if (kv.length != 2) { - throw new ParameterException("Dynamic parameter expected a value of the form a" + a + "b" - + " but got:" + sv); + + int aInd = sv.indexOf(a); + if (aInd == -1) { + throw new ParameterException( + "Dynamic parameter expected a value of the form a" + a + "b" + + " but got:" + sv); } - callPut(object, field, kv[0], kv[1]); + callPut(object, field, sv.substring(0, aInd), sv.substring(aInd + 1)); } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 1562b14..632158f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -55,6 +55,7 @@ import com.beust.jcommander.command.CommandMain; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import org.testng.collections.Maps; import java.io.ByteArrayInputStream; import java.io.File; @@ -663,9 +664,21 @@ public class JCommanderTest { } } + public void dynamicParameters() { + class Command { + @DynamicParameter(names = {"-P"}, description = "Additional command parameters") + private Map params = Maps.newHashMap(); + } + JCommander commander = new JCommander(); + Command c = new Command(); + commander.addCommand("command", c); + commander.parse(new String[] { "command", "-Pparam='name=value'" }); + Assert.assertEquals(c.params.get("param"), "'name=value'"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().askedRequiredPassword(); + new JCommanderTest().dynamicParameters(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From 3322ab84f65d3539c45f56cc9ffe4fe1afe85057 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 10 Mar 2012 16:12:25 -0800 Subject: Build fix. --- build-with-maven | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index 3b9ba12..6290f22 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,8 +1,10 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.4.1beta +v=6.5beta export TESTNG=../testng/target/testng-${v}.jar +run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml" +echo "Launching tests: ${run}" java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml echo "To deploy to the snapshot repository: mvn deploy" -- cgit v1.2.3 From 27e06134bd278f493a78cb7b4cea9be35b9ae7e0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Mar 2012 12:09:40 -0700 Subject: Fixed Javadoc warnings. --- src/main/java/com/beust/jcommander/IVariableArity.java | 2 +- src/main/java/com/beust/jcommander/converters/IParameterSplitter.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/IVariableArity.java b/src/main/java/com/beust/jcommander/IVariableArity.java index e7499c9..e8a40ba 100644 --- a/src/main/java/com/beust/jcommander/IVariableArity.java +++ b/src/main/java/com/beust/jcommander/IVariableArity.java @@ -2,7 +2,7 @@ package com.beust.jcommander; /** * Must be implemented by argument classes that contain at least one - * @Parameter with "variableArity = true". + * \@Parameter with "variableArity = true". */ public interface IVariableArity { diff --git a/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java b/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java index e8b87b0..5859f4a 100644 --- a/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java +++ b/src/main/java/com/beust/jcommander/converters/IParameterSplitter.java @@ -5,8 +5,6 @@ import java.util.List; /** * Convert a string representing several parameters (e.g. "a,b,c" or "d/e/f") into a * list of arguments ([a,b,c] and [d,e,f]). - * - * @param */ public interface IParameterSplitter { List split(String value); -- cgit v1.2.3 From 3506d0225bc20b569aeb22db93eaa78b20e6571f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 12 Mar 2012 14:51:40 -0700 Subject: Fixed: GITHUB-105: If no description is given for an enum, use that enum's value (Adrian Muraru) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/ParameterDescription.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 2ddb9ab..b73d3da 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: GITHUB-105: If no description is given for an enum, use that enum's value (Adrian Muraru) Fixed: GITHUB-108: Dynamic parameters with "=" in them are not parsed correctly (szhem) Fixed: Commands with same prefix as options were not working properly. Fixed: GITHUB-97: Required password always complains that it is not specified (timoteoponce) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index f90c6a5..4de95d5 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -111,6 +111,7 @@ public class ParameterDescription { } } + @SuppressWarnings("unchecked") private void init(Object object, Field field, ResourceBundle bundle, JCommander jCommander) { m_object = object; @@ -123,7 +124,8 @@ public class ParameterDescription { if (m_parameterAnnotation != null) { String description; - if (Enum.class.isAssignableFrom(field.getType()) && m_parameterAnnotation.description().isEmpty()) { + if (Enum.class.isAssignableFrom(field.getType()) + && m_parameterAnnotation.description().isEmpty()) { description = "Options: " + EnumSet.allOf((Class) field.getType()); }else { description = m_parameterAnnotation.description(); -- cgit v1.2.3 From 59b3e36fa8add6ec52422fc887d98021ab8ae418 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 13 Mar 2012 14:17:20 -0700 Subject: Query all the option names when trying to find a default value for a parameter. --- src/main/java/com/beust/jcommander/JCommander.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index e257d22..3a1b684 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -565,11 +565,13 @@ public class JCommander { } private void initializeDefaultValue(ParameterDescription pd) { - String optionName = pd.getParameter().names()[0]; - String def = m_defaultProvider.getDefaultValueFor(optionName); - if (def != null) { - p("Initializing " + optionName + " with default value:" + def); - pd.addValue(def, true /* default */); + for (String optionName : pd.getParameter().names()) { + String def = m_defaultProvider.getDefaultValueFor(optionName); + if (def != null) { + p("Initializing " + optionName + " with default value:" + def); + pd.addValue(def, true /* default */); + return; + } } } -- cgit v1.2.3 From cc2bd844ba7a6996a334b624b939a4af61e612b3 Mon Sep 17 00:00:00 2001 From: pmendelson Date: Thu, 15 Mar 2012 10:55:17 -0400 Subject: Modified usage function to display a placeholder for parameters that are designed as passwords --- src/main/java/com/beust/jcommander/JCommander.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3a1b684..d1c670f 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -967,7 +967,7 @@ public class JCommander { } if (def != null && ! "".equals(def)) { out.append("\n" + spaces(indentCount + 1)) - .append("Default: " + def); + .append("Default: " + (parameter.password()?"********":def)); } out.append("\n"); } @@ -1390,3 +1390,4 @@ public class JCommander { } } } + -- cgit v1.2.3 From d38864b2271e805449fea3c92091f1f867a2a32f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 15 Mar 2012 08:09:11 -0700 Subject: Added: Default passwords are no longer displayed in the usage (Paul Mendelson) --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index b73d3da..fff4928 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: Default passwords are no longer displayed in the usage (Paul Mendelson) Fixed: GITHUB-105: If no description is given for an enum, use that enum's value (Adrian Muraru) Fixed: GITHUB-108: Dynamic parameters with "=" in them are not parsed correctly (szhem) Fixed: Commands with same prefix as options were not working properly. -- cgit v1.2.3 From 9d954f1ea53560560273c057b9b6e35d87f5d5c6 Mon Sep 17 00:00:00 2001 From: Jochen Kupperschmidt Date: Thu, 12 Apr 2012 10:21:33 +0200 Subject: Escape angle brackets in HTML docs. --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 29f117a..b72706e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -738,14 +738,14 @@ You can download JCommander from the following locations:
            • Source on github
            • -
            • If you are using Maven, add the following dependency to your pom.xml: +
            • If you are using Maven, add the following dependency to your pom.xml:
               
               
                 <groupId>com.beust</groupId>
                 <artifactId>jcommander</artifactId>
              -  1.20
              +  <version>1.20</version>
               
                 
              -- cgit v1.2.3 From ca0789ba868746845d31c2ee9e354d8bfbdeca6e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 18 Apr 2012 10:14:48 -0700 Subject: Fixed: StringIndexOutOfBoundsException if passing an empty parameter (bomanz) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/JCommanderTest.java | 13 ++++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b73d3da..3e9b5f2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: StringIndexOutOfBoundsException if passing an empty parameter (bomanz) Fixed: GITHUB-105: If no description is given for an enum, use that enum's value (Adrian Muraru) Fixed: GITHUB-108: Dynamic parameters with "=" in them are not parsed correctly (szhem) Fixed: Commands with same prefix as options were not working properly. diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3a1b684..5899bb8 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -383,7 +383,7 @@ public class JCommander { private boolean isOption(String[] args, String arg) { String prefixes = getOptionPrefixes(args, arg); - return prefixes.indexOf(arg.charAt(0)) >= 0; + return arg.length() > 0 && prefixes.indexOf(arg.charAt(0)) >= 0; } private ParameterDescription getPrefixDescriptionFor(String arg) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 74649b5..9477dac 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -680,9 +680,20 @@ public class JCommanderTest { Assert.assertEquals(c.params.get("param"), "'name=value'"); } + public void exeParser() { + class Params { + @Parameter( names= "-i") + private String inputFile; + } + + String args[] = { "-i", "" }; + Params p = new Params(); + new JCommander(p, args); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().dynamicParameters(); + new JCommanderTest().exeParser(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From e5bccc501142272a1fae64371e2ed307bc573815 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 25 Apr 2012 11:28:21 -0700 Subject: Fixed doc not to use Lists and Maps. --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index b72706e..61728d5 100644 --- a/doc/index.html +++ b/doc/index.html @@ -57,7 +57,7 @@ import com.beust.jcommander.Parameter; public class JCommanderExample { @Parameter - private List<String> parameters = Lists.newArrayList(); + private List<String> parameters = new ArrayList<String>(); @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") private Integer verbose = 1; @@ -684,7 +684,7 @@ JCommander allows you to specify parameters that are not known at compile time,
               @DynamicParameter(names = "-D", description = "Dynamic parameters go here")
              -private Map<String, String> params = Maps.newHashMap();
              +private Map<String, String> params = new HashMap<String, String>();
               
              You can specify a different assignment string than = by using the attribute assignment. -- cgit v1.2.3 From 5414de6562cc1a597c0d522fc4889e0f4136306c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 26 Apr 2012 12:28:11 -0700 Subject: Fixed bug with multiple variable arities. --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../java/com/beust/jcommander/JCommanderTest.java | 29 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index b9f83d9..97d1eaa 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -609,7 +609,7 @@ public class JCommander { // // Variable arity? // - i = processVariableArity(args, i, pd); + i += processVariableArity(args, i, pd); } else { // // Regular option diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9477dac..1da032a 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -55,6 +55,7 @@ import com.beust.jcommander.command.CommandMain; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import org.testng.collections.Lists; import org.testng.collections.Maps; import java.io.ByteArrayInputStream; @@ -691,9 +692,35 @@ public class JCommanderTest { new JCommander(p, args); } + public void multiList() { + class Params implements IVariableArity { + @Parameter(names = "-paramA", description = "ParamA", variableArity = true) + private List paramA = Lists.newArrayList(); + + @Parameter(names = "-paramB", description = "ParamB", variableArity = true) + private List paramB = Lists.newArrayList(); + + public int processVariableArity(String optionName, String[] options) { + int i = 0; + while (i < options.length && !options[i].startsWith("-")) { + if ("-paramA".equals(optionName)) paramA.add(options[i]); + else paramB.add(options[i]); + i++; + } + return i; + } + } + + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().exeParser(); + new JCommanderTest().multiList(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From 96a8b0d4f9c23b1fd80cbaba19d5f84d64adad93 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 26 Apr 2012 12:46:14 -0700 Subject: Better variable arity. --- src/main/java/com/beust/jcommander/JCommander.java | 41 ++++++++++++++++------ .../java/com/beust/jcommander/JCommanderTest.java | 16 ++------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 97d1eaa..66aec1e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -701,36 +701,55 @@ public class JCommander { return null; } + private class DefaultVariableArity implements IVariableArity { + + public int processVariableArity(String optionName, String[] options) { + int i = 0; + while (i < options.length && !isOption(options, options[i])) { + i++; + } + return i; + } + } + private final IVariableArity DEFAULT_VARIABLE_ARITY = new DefaultVariableArity(); + /** * @return the number of options that were processed. */ private int processVariableArity(String[] args, int index, ParameterDescription pd) { Object arg = pd.getObject(); + IVariableArity va; if (! (arg instanceof IVariableArity)) { - throw new ParameterException("Arg class " + arg.getClass() - + " should implement IVariableArity"); + va = DEFAULT_VARIABLE_ARITY; + } else { + va = (IVariableArity) arg; } - IVariableArity va = (IVariableArity) arg; List currentArgs = Lists.newArrayList(); for (int j = index + 1; j < args.length; j++) { currentArgs.add(args[j]); } - int result = va.processVariableArity(pd.getParameter().names()[0], + int arity = va.processVariableArity(pd.getParameter().names()[0], currentArgs.toArray(new String[0])); - return result; + + return processFixedArity(args, index, pd, List.class, arity); } 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); + return processFixedArity(args, index, pd, fieldType, n); + } + + private int processFixedArity(String[] args, int index, ParameterDescription pd, + Class fieldType, int arity) { + String arg = args[index]; // Special case for boolean parameters of arity 0 - if (n == 0 && + if (arity == 0 && (Boolean.class.isAssignableFrom(fieldType) || boolean.class.isAssignableFrom(fieldType))) { pd.addValue("true"); @@ -738,14 +757,14 @@ public class JCommander { } 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++) { + if (index + arity < args.length) { + for (int j = 1; j <= arity; j++) { pd.addValue(trim(args[index + j + offset])); m_requiredFields.remove(pd.getField()); } - index += n + offset; + index += arity + offset; } else { - throw new ParameterException("Expected " + n + " values after " + arg); + throw new ParameterException("Expected " + arity + " values after " + arg); } } else { throw new ParameterException("Expected a value after parameter " + arg); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 1da032a..736dc04 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -692,23 +692,13 @@ public class JCommanderTest { new JCommander(p, args); } - public void multiList() { - class Params implements IVariableArity { + public void multiVariableArityList() { + class Params { @Parameter(names = "-paramA", description = "ParamA", variableArity = true) private List paramA = Lists.newArrayList(); @Parameter(names = "-paramB", description = "ParamB", variableArity = true) private List paramB = Lists.newArrayList(); - - public int processVariableArity(String optionName, String[] options) { - int i = 0; - while (i < options.length && !options[i].startsWith("-")) { - if ("-paramA".equals(optionName)) paramA.add(options[i]); - else paramB.add(options[i]); - i++; - } - return i; - } } String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; @@ -720,7 +710,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().multiList(); + new JCommanderTest().multiVariableArityList(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From 74664b26b3b9cdaec4a683ec9666828cbc856e44 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 26 Apr 2012 12:46:14 -0700 Subject: Better variable arity. --- src/main/java/com/beust/jcommander/JCommander.java | 41 ++++++++++++++++------ .../java/com/beust/jcommander/JCommanderTest.java | 16 ++------- .../com/beust/jcommander/args/VariableArity.java | 3 -- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 97d1eaa..66aec1e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -701,36 +701,55 @@ public class JCommander { return null; } + private class DefaultVariableArity implements IVariableArity { + + public int processVariableArity(String optionName, String[] options) { + int i = 0; + while (i < options.length && !isOption(options, options[i])) { + i++; + } + return i; + } + } + private final IVariableArity DEFAULT_VARIABLE_ARITY = new DefaultVariableArity(); + /** * @return the number of options that were processed. */ private int processVariableArity(String[] args, int index, ParameterDescription pd) { Object arg = pd.getObject(); + IVariableArity va; if (! (arg instanceof IVariableArity)) { - throw new ParameterException("Arg class " + arg.getClass() - + " should implement IVariableArity"); + va = DEFAULT_VARIABLE_ARITY; + } else { + va = (IVariableArity) arg; } - IVariableArity va = (IVariableArity) arg; List currentArgs = Lists.newArrayList(); for (int j = index + 1; j < args.length; j++) { currentArgs.add(args[j]); } - int result = va.processVariableArity(pd.getParameter().names()[0], + int arity = va.processVariableArity(pd.getParameter().names()[0], currentArgs.toArray(new String[0])); - return result; + + return processFixedArity(args, index, pd, List.class, arity); } 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); + return processFixedArity(args, index, pd, fieldType, n); + } + + private int processFixedArity(String[] args, int index, ParameterDescription pd, + Class fieldType, int arity) { + String arg = args[index]; // Special case for boolean parameters of arity 0 - if (n == 0 && + if (arity == 0 && (Boolean.class.isAssignableFrom(fieldType) || boolean.class.isAssignableFrom(fieldType))) { pd.addValue("true"); @@ -738,14 +757,14 @@ public class JCommander { } 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++) { + if (index + arity < args.length) { + for (int j = 1; j <= arity; j++) { pd.addValue(trim(args[index + j + offset])); m_requiredFields.remove(pd.getField()); } - index += n + offset; + index += arity + offset; } else { - throw new ParameterException("Expected " + n + " values after " + arg); + throw new ParameterException("Expected " + arity + " values after " + arg); } } else { throw new ParameterException("Expected a value after parameter " + arg); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 1da032a..736dc04 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -692,23 +692,13 @@ public class JCommanderTest { new JCommander(p, args); } - public void multiList() { - class Params implements IVariableArity { + public void multiVariableArityList() { + class Params { @Parameter(names = "-paramA", description = "ParamA", variableArity = true) private List paramA = Lists.newArrayList(); @Parameter(names = "-paramB", description = "ParamB", variableArity = true) private List paramB = Lists.newArrayList(); - - public int processVariableArity(String optionName, String[] options) { - int i = 0; - while (i < options.length && !options[i].startsWith("-")) { - if ("-paramA".equals(optionName)) paramA.add(options[i]); - else paramB.add(options[i]); - i++; - } - return i; - } } String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; @@ -720,7 +710,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().multiList(); + new JCommanderTest().multiVariableArityList(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { diff --git a/src/test/java/com/beust/jcommander/args/VariableArity.java b/src/test/java/com/beust/jcommander/args/VariableArity.java index 19611e4..21a861d 100644 --- a/src/test/java/com/beust/jcommander/args/VariableArity.java +++ b/src/test/java/com/beust/jcommander/args/VariableArity.java @@ -21,9 +21,6 @@ public class VariableArity implements IVariableArity { public List var = new ArrayList(); public int processVariableArity(String optionName, String[] options) { - for (int i = 0; i < m_count; i++) { - var.add(options[i]); - } return m_count; } } -- cgit v1.2.3 From 61e65090c5495518a9a521149dbecbd17e1df193 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 26 Apr 2012 13:58:48 -0700 Subject: Command descriptions (@Parameters(resourceBundle)) were not i18n'ed properly. --- src/main/java/com/beust/jcommander/JCommander.java | 22 ++++++++++++++++++---- .../java/com/beust/jcommander/JCommanderTest.java | 16 +++++++++++++++- src/test/resources/MessageBundle_en_US.properties | 4 +++- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 66aec1e..6b712f7 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -47,6 +47,7 @@ import java.util.EnumSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; @@ -895,9 +896,22 @@ public class JCommander { throw new ParameterException("Asking description for unknown command: " + commandName); } - Parameters p = jc.getObjects().get(0).getClass().getAnnotation(Parameters.class); + Object arg = jc.getObjects().get(0); + Parameters p = arg.getClass().getAnnotation(Parameters.class); String result = jc.getMainParameterDescription(); - if (p != null) result = getI18nString(p.commandDescriptionKey(), p.commandDescription()); + ResourceBundle bundle = null; + if (p != null) { + String bundleName = p.resourceBundle(); + if (!"".equals(bundleName)) { + bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault()); + } else { + bundle = m_bundle; + } + + if (bundle != null) { + result = getI18nString(bundle, p.commandDescriptionKey(), p.commandDescription()); + } + } return result; } @@ -906,8 +920,8 @@ public class JCommander { * @return The internationalized version of the string if available, otherwise * return def. */ - private String getI18nString(String key, String def) { - String s = m_bundle != null ? m_bundle.getString(key) : null; + private String getI18nString(ResourceBundle bundle, String key, String def) { + String s = bundle != null ? bundle.getString(key) : null; return s != null ? s : def; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 736dc04..01b7c1c 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -708,9 +708,23 @@ public class JCommanderTest { Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); } + @Test(enabled = false, + description = "Need to double check that the command description is i18n'ed in the usage") + public void commandKey() { + @Parameters(resourceBundle = "MessageBundle", commandDescriptionKey = "command") + class Args { + @Parameter(names="-myoption", descriptionKey="myoption") + private boolean option; + } + JCommander j = new JCommander(); + Args a = new Args(); + j.addCommand("comm", a); + j.usage(); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().multiVariableArityList(); + new JCommanderTest().commandKey(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { diff --git a/src/test/resources/MessageBundle_en_US.properties b/src/test/resources/MessageBundle_en_US.properties index 915c418..11e19e4 100644 --- a/src/test/resources/MessageBundle_en_US.properties +++ b/src/test/resources/MessageBundle_en_US.properties @@ -16,4 +16,6 @@ # limitations under the License. # -host = Host \ No newline at end of file +host = Host +command = Command from the bundle +myoption = My option \ No newline at end of file -- cgit v1.2.3 From 8f046527914cec812c9b26314469525618988ac6 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 26 Apr 2012 14:00:22 -0700 Subject: CHANGELOG. --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 8d4eb9e..dec8ca6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ Current Added: Default passwords are no longer displayed in the usage (Paul Mendelson) +Added: Variable arities now work magically, no need for IVariableArity any more +Fixed: Commands using @Parameters(resourceBundle) were not i18n'ed properly in the usage() Fixed: StringIndexOutOfBoundsException if passing an empty parameter (bomanz) Fixed: GITHUB-105: If no description is given for an enum, use that enum's value (Adrian Muraru) Fixed: GITHUB-108: Dynamic parameters with "=" in them are not parsed correctly (szhem) -- cgit v1.2.3 From 7f1e037acfb5e2cda7a452e0b897adfc55c1aaa9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:33:14 -0700 Subject: Build update to TestNG 6.5.2. --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index 6290f22..ccaf39c 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,6 +1,6 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.5beta +v=6.5.2 export TESTNG=../testng/target/testng-${v}.jar run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml" -- cgit v1.2.3 From 99c56a910005355446ce0c870405c8e0088b0ed3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:33:45 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.24 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec7cacf..a750e71 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.24-SNAPSHOT + 1.24 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 653fc8db5f1952f6fb97a6a2c12e034d3965ce19 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:35:06 -0700 Subject: pom to 1.25. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a750e71..e2afba0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.24 + 1.25-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From b5dd1313bfdde307c92c79974b58a5fe069af551 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:35:27 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.25 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e2afba0..afb8e9f 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.25-SNAPSHOT + 1.25 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 9952211b8cdbd5c7134edf1c9c63831261ad60c7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:35:34 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index afb8e9f..8486308 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.25 + 1.26-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 5e7a537ec81b5cc7ec482d20b839ee6aa466ae12 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:45:23 -0700 Subject: Added doc for variableArity. --- doc/index.html | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/index.html b/doc/index.html index 61728d5..5dbe469 100644 --- a/doc/index.html +++ b/doc/index.html @@ -426,6 +426,8 @@ java Main @/tmp/parameters

              Arities (multiple values for parameters)

              +

              Fixed arities

              + If some of your parameters require more than one value, such as the following example where two values are expected after -pairs: @@ -452,6 +454,22 @@ parameters that define an arity. You will have to convert these values yourself if the parameters you need are of type Integer or other (this limitation is due to Java's erasure). +

              Variable arities

              + +You can specify that a parameter can receive an indefinite number of parameters, up to the next option. For example: + +
              +program -foo a1 a2 a3 -bar
              +program -foo a1 -bar
              +
              + +Such a parameter must be of type List<String> and have the boolean variableArity set to true + +
              +@Parameter(names = "-foo", variableArity = true)
              +public List<String> foo = new ArrayList<String>();
              +
              +

              Multiple option names

              You can specify more than one option name: -- cgit v1.2.3 From ae55f2ba154156ffe9b25bcc51b9e5666f712085 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:45:23 -0700 Subject: Added doc for variableArity. --- doc/index.html | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 61728d5..de5d755 100644 --- a/doc/index.html +++ b/doc/index.html @@ -37,6 +37,11 @@ Created: July 13th, 2010
            + Last updated: April 25th, 2012 +
            Cédric Beust
            @@ -426,6 +431,8 @@ java Main @/tmp/parameters

            Arities (multiple values for parameters)

            +

            Fixed arities

            + If some of your parameters require more than one value, such as the following example where two values are expected after -pairs: @@ -452,6 +459,22 @@ parameters that define an arity. You will have to convert these values yourself if the parameters you need are of type Integer or other (this limitation is due to Java's erasure). +

            Variable arities

            + +You can specify that a parameter can receive an indefinite number of parameters, up to the next option. For example: + +
            +program -foo a1 a2 a3 -bar
            +program -foo a1 -bar
            +
            + +Such a parameter must be of type List<String> and have the boolean variableArity set to true + +
            +@Parameter(names = "-foo", variableArity = true)
            +public List<String> foo = new ArrayList<String>();
            +
            +

            Multiple option names

            You can specify more than one option name: @@ -745,7 +768,7 @@ You can download JCommander from the following locations: <groupId>com.beust</groupId> <artifactId>jcommander</artifactId> - <version>1.20</version> + <version>1.25</version> -- cgit v1.2.3 From 5f5b78b9d1994cd1348b0a71dc472c5d44c25d96 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Apr 2012 17:50:24 -0700 Subject: Change log. --- CHANGELOG | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index dec8ca6..b39528e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ Current +======================== + +1.25 +2012/04/26 + Added: Default passwords are no longer displayed in the usage (Paul Mendelson) Added: Variable arities now work magically, no need for IVariableArity any more Fixed: Commands using @Parameters(resourceBundle) were not i18n'ed properly in the usage() -- cgit v1.2.3 From c84dbd38b26b5713a776745140881c6e0b7c7aac Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 29 Apr 2012 15:17:05 -0700 Subject: Fixed: variable arities not working when same parameter appears multiple times. --- CHANGELOG | 2 ++ src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../java/com/beust/jcommander/JCommanderTest.java | 22 ++++++++++++++++------ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b39528e..8c5b43d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ Current +Fixed: variable arities not working when same parameter appears multiple times. + ======================== 1.25 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 6b712f7..67eb7c1 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -610,7 +610,7 @@ public class JCommander { // // Variable arity? // - i += processVariableArity(args, i, pd); + i = processVariableArity(args, i, pd); } else { // // Regular option diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 01b7c1c..89e1c02 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -701,11 +701,21 @@ public class JCommanderTest { private List paramB = Lists.newArrayList(); } - String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; - Params p = new Params(); - new JCommander(p, args).parse(); - Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); - Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + { + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + } + + { + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "-paramA", "a3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2", "a3" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1" })); + } } @Test(enabled = false, @@ -724,7 +734,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().commandKey(); + new JCommanderTest().multiVariableArityList(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From 8e9138231db060a796463260b1bc476ef355d744 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 29 Apr 2012 15:17:11 -0700 Subject: Formatting. --- src/main/java/com/beust/jcommander/ParameterDescription.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 4de95d5..abc070c 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -231,8 +231,7 @@ public class ParameterDescription { + " to parameter:" + m_field.getName()); String name = m_wrappedParameter.names()[0]; if (m_assigned && ! isMultiOption()) { - throw new ParameterException("Can only specify option " + name - + " once."); + throw new ParameterException("Can only specify option " + name + " once."); } validateParameter(name, value); -- cgit v1.2.3 From fb38f40b769781cb2cd00763865bc0aef59f392a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 2 May 2012 11:52:39 -0700 Subject: Fixed: bug with several multiple arity parameters (VariableArityTest). --- CHANGELOG | 5 ++ src/main/java/com/beust/jcommander/JCommander.java | 17 +++--- .../com/beust/jcommander/VariableArityTest.java | 66 ++++++++++++++++++++++ src/test/resources/testng.xml | 1 + 4 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/VariableArityTest.java diff --git a/CHANGELOG b/CHANGELOG index dec8ca6..994f07c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ Current +Fixed: bug with several multiple arity parameters (VariableArityTest) + +1.25 +2012/04/22 + Added: Default passwords are no longer displayed in the usage (Paul Mendelson) Added: Variable arities now work magically, no need for IVariableArity any more Fixed: Commands using @Parameters(resourceBundle) were not i18n'ed properly in the usage() diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 6b712f7..0017bd1 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -588,9 +588,10 @@ public class JCommander { while (i < args.length && ! commandParsed) { String arg = args[i]; String a = trim(arg); - p("Parsing arg:" + a); + p("Parsing arg: " + a); JCommander jc = findCommandByAlias(arg); + int increment = 1; if (isOption(args, a) && jc == null) { // // Option @@ -610,7 +611,7 @@ public class JCommander { // // Variable arity? // - i += processVariableArity(args, i, pd); + increment = processVariableArity(args, i, pd); } else { // // Regular option @@ -624,7 +625,7 @@ public class JCommander { pd.addValue("true"); m_requiredFields.remove(pd.getField()); } else { - i = processFixedArity(args, i, pd, fieldType); + increment = processFixedArity(args, i, pd, fieldType); } } } @@ -675,7 +676,7 @@ public class JCommander { } } } - i++; + i += increment; } // Mark the parameter descriptions held in m_fields as assigned @@ -733,7 +734,8 @@ public class JCommander { int arity = va.processVariableArity(pd.getParameter().names()[0], currentArgs.toArray(new String[0])); - return processFixedArity(args, index, pd, List.class, arity); + int result = processFixedArity(args, index, pd, List.class, arity); + return result; } private int processFixedArity(String[] args, int index, ParameterDescription pd, @@ -746,8 +748,9 @@ public class JCommander { return processFixedArity(args, index, pd, fieldType, n); } - private int processFixedArity(String[] args, int index, ParameterDescription pd, + private int processFixedArity(String[] args, int originalIndex, ParameterDescription pd, Class fieldType, int arity) { + int index = originalIndex; String arg = args[index]; // Special case for boolean parameters of arity 0 if (arity == 0 && @@ -771,7 +774,7 @@ public class JCommander { throw new ParameterException("Expected a value after parameter " + arg); } - return index; + return arity + 1; } /** diff --git a/src/test/java/com/beust/jcommander/VariableArityTest.java b/src/test/java/com/beust/jcommander/VariableArityTest.java new file mode 100644 index 0000000..a90392f --- /dev/null +++ b/src/test/java/com/beust/jcommander/VariableArityTest.java @@ -0,0 +1,66 @@ +package com.beust.jcommander; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public class VariableArityTest { + + public static class ModelGenerationConfig { + + @Parameter(names = { "-m", "--matrixData" }, variableArity = true, + description = "File containing a list of instances and their runtimes on various configurations", required = false) + public List modelMatrixFile = new LinkedList(); + + @Parameter(names = { "-f", "--featureData" }, variableArity = true, + description = "File containing a list of instances and their corresponding features", required = true) + public List featureFile = new LinkedList(); + + @Parameter(names = { "-c", "--configData" }, variableArity = true, + description = "File containing a list of configuration parameter values") + public List configFile = new LinkedList(); + + @Parameter(names = { "-o", "--outputFile" }, + description = "File to output the resulting data to. Defaults to ./matrix-generation.zip", required = false) + public String outputFile = "matrix-generation.zip"; + + @Parameter(names = { "--seed" }, description = "Seed used for PRNG [0 means don't use a Seed]") + public long seed = 0; + + public void print() { + System.out.println("modelMatrixFile: " + modelMatrixFile); + System.out.println("featureData: " + featureFile); + System.out.println("configFile: " + configFile); + System.out.println("output: " + outputFile); + System.out.println("seed: " + seed); + + } + } + + @Test + public void verifyVariableArity() { + String input = "-m foo --seed 1024 -c foo -o foo -f foo "; + + String[] split = input.split("\\s+"); + + ModelGenerationConfig config = new ModelGenerationConfig(); + JCommander com = new JCommander(config); + com.setProgramName("modelgen"); + + com.parse(split); + +// config.print(); + Assert.assertNotEquals(config.seed, 0); + Assert.assertEquals(config.modelMatrixFile, Arrays.asList(new String[] { "foo" })); + Assert.assertEquals(config.featureFile, Arrays.asList(new String[] { "foo" })); + Assert.assertEquals(config.seed, 1024); + Assert.assertEquals(config.outputFile, "foo"); + } + + public static void main(String[] args) { + new VariableArityTest().verifyVariableArity(); + } +} \ No newline at end of file diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index a99ad0d..2ccd4ef 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -12,6 +12,7 @@ + -- cgit v1.2.3 From bb0873edf216718d08386bbff6b6f93aacf72708 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 2 May 2012 11:52:51 -0700 Subject: Don't display no-op validations in debug mode. --- src/main/java/com/beust/jcommander/ParameterDescription.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 4de95d5..4b77478 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -18,6 +18,8 @@ package com.beust.jcommander; +import com.beust.jcommander.validators.NoValidator; + import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; @@ -277,7 +279,9 @@ public class ParameterDescription { public static void validateParameter(Class validator, String name, String value) { try { - p("Validating parameter:" + name + " value:" + value + " validator:" + validator); + if (validator != NoValidator.class) { + p("Validating parameter:" + name + " value:" + value + " validator:" + validator); + } validator.newInstance().validate(name, value); } catch (InstantiationException e) { throw new ParameterException("Can't instantiate validator:" + e); -- cgit v1.2.3 From 5219e93646ed740bd837e4e6b6033bc4391135ba Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 2 May 2012 11:58:20 -0700 Subject: Merge. --- CHANGELOG | 4 ++-- doc/index.html | 25 +++++++++++++++++++++- pom.xml | 2 +- .../com/beust/jcommander/ParameterDescription.java | 3 +-- .../java/com/beust/jcommander/JCommanderTest.java | 22 +++++++++++++------ 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 994f07c..624c6dc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,10 @@ Current Fixed: bug with several multiple arity parameters (VariableArityTest) +Fixed: variable arities not working when same parameter appears multiple times. 1.25 -2012/04/22 - +2012/04/26 Added: Default passwords are no longer displayed in the usage (Paul Mendelson) Added: Variable arities now work magically, no need for IVariableArity any more Fixed: Commands using @Parameters(resourceBundle) were not i18n'ed properly in the usage() diff --git a/doc/index.html b/doc/index.html index 61728d5..de5d755 100644 --- a/doc/index.html +++ b/doc/index.html @@ -37,6 +37,11 @@ Created: July 13th, 2010
            + Last updated: April 25th, 2012 +
            Cédric Beust
            @@ -426,6 +431,8 @@ java Main @/tmp/parameters

            Arities (multiple values for parameters)

            +

            Fixed arities

            + If some of your parameters require more than one value, such as the following example where two values are expected after -pairs: @@ -452,6 +459,22 @@ parameters that define an arity. You will have to convert these values yourself if the parameters you need are of type Integer or other (this limitation is due to Java's erasure). +

            Variable arities

            + +You can specify that a parameter can receive an indefinite number of parameters, up to the next option. For example: + +
            +program -foo a1 a2 a3 -bar
            +program -foo a1 -bar
            +
            + +Such a parameter must be of type List<String> and have the boolean variableArity set to true + +
            +@Parameter(names = "-foo", variableArity = true)
            +public List<String> foo = new ArrayList<String>();
            +
            +

            Multiple option names

            You can specify more than one option name: @@ -745,7 +768,7 @@ You can download JCommander from the following locations: <groupId>com.beust</groupId> <artifactId>jcommander</artifactId> - <version>1.20</version> + <version>1.25</version> diff --git a/pom.xml b/pom.xml index ec7cacf..8486308 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.24-SNAPSHOT + 1.26-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 4b77478..832a25b 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -233,8 +233,7 @@ public class ParameterDescription { + " to parameter:" + m_field.getName()); String name = m_wrappedParameter.names()[0]; if (m_assigned && ! isMultiOption()) { - throw new ParameterException("Can only specify option " + name - + " once."); + throw new ParameterException("Can only specify option " + name + " once."); } validateParameter(name, value); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 01b7c1c..89e1c02 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -701,11 +701,21 @@ public class JCommanderTest { private List paramB = Lists.newArrayList(); } - String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; - Params p = new Params(); - new JCommander(p, args).parse(); - Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); - Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + { + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + } + + { + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "-paramA", "a3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2", "a3" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1" })); + } } @Test(enabled = false, @@ -724,7 +734,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().commandKey(); + new JCommanderTest().multiVariableArityList(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From 13a57cd81965605f1050f20ed2d4169e6d6d24df Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 8 May 2012 15:14:12 -0700 Subject: Fixed: 113: getCommandDescription() returns the description of the main parameter instead of that of the command --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 3 ++- .../java/com/beust/jcommander/JCommanderTest.java | 22 ++++++---------------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 624c6dc..344d107 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: 113: getCommandDescription() returns the description of the main parameter instead of that of the command Fixed: bug with several multiple arity parameters (VariableArityTest) Fixed: variable arities not working when same parameter appears multiple times. diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 0017bd1..34e80c4 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -901,9 +901,10 @@ public class JCommander { Object arg = jc.getObjects().get(0); Parameters p = arg.getClass().getAnnotation(Parameters.class); - String result = jc.getMainParameterDescription(); ResourceBundle bundle = null; + String result = null; if (p != null) { + result = p.commandDescription(); String bundleName = p.resourceBundle(); if (!"".equals(bundleName)) { bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault()); diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 89e1c02..01b7c1c 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -701,21 +701,11 @@ public class JCommanderTest { private List paramB = Lists.newArrayList(); } - { - String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; - Params p = new Params(); - new JCommander(p, args).parse(); - Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); - Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); - } - - { - String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "-paramA", "a3" }; - Params p = new Params(); - new JCommander(p, args).parse(); - Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2", "a3" })); - Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1" })); - } + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); } @Test(enabled = false, @@ -734,7 +724,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().multiVariableArityList(); + new JCommanderTest().commandKey(); // System.out.println("Help:" + a.help); // System.out.println("A"); // class A { -- cgit v1.2.3 From c10f00e203d5e2b035b18382df59864363dfa0cd Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 14 May 2012 10:16:08 -0700 Subject: Better handling of plurals. --- src/main/java/com/beust/jcommander/JCommander.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 34e80c4..1d8a373 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -306,7 +306,9 @@ public class JCommander { for (ParameterDescription pd : m_requiredFields.values()) { missingFields.append(pd.getNames()).append(" "); } - throw new ParameterException("The following options are required: " + missingFields); + throw new ParameterException("The following " + + pluralize(m_requiredFields.size(), "option is required: ", "options are required: ") + + missingFields); } if (m_mainParameterDescription != null) { @@ -318,6 +320,10 @@ public class JCommander { } } + private static String pluralize(int quantity, String singular, String plural) { + return quantity == 1 ? singular : plural; + } + /** * Expand the command line parameters to take @ parameters into account. * When @ is encountered, the content of the file that follows is inserted -- cgit v1.2.3 From 9e22cffb2d22829cb5e2d1bf4d64d87df69d2983 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 15 May 2012 14:49:22 -0700 Subject: Fixed: if using a different option prefix, unknown option are mistakenly reported as "no main parameter defined" (kurmasz) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 22 ++++++--- src/main/java/com/beust/jcommander/Strings.java | 7 +++ .../java/com/beust/jcommander/JCommanderTest.java | 57 +++++++++++++++++----- 4 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/Strings.java diff --git a/CHANGELOG b/CHANGELOG index 344d107..8351698 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: if using a different option prefix, unknown option are mistakenly reported as "no main parameter defined" (kurmasz) Fixed: 113: getCommandDescription() returns the description of the main parameter instead of that of the command Fixed: bug with several multiple arity parameters (VariableArityTest) Fixed: variable arities not working when same parameter appears multiple times. diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 1d8a373..c56ecce 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -439,8 +439,22 @@ public class JCommander { .getAnnotation(Parameters.class); if (p != null) return p.optionPrefixes(); } + String result = Parameters.DEFAULT_OPTION_PREFIXES; - return 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; } /** @@ -643,7 +657,7 @@ public class JCommander { // // Main parameter // - if (! isStringEmpty(arg)) { + if (! Strings.isStringEmpty(arg)) { if (m_commands.isEmpty()) { // // Regular (non-command) parsing @@ -800,10 +814,6 @@ public class JCommander { return result; } - private static boolean isStringEmpty(String s) { - return s == null || "".equals(s); - } - /** * @return the field that's meant to receive all the parameters that are not options. * diff --git a/src/main/java/com/beust/jcommander/Strings.java b/src/main/java/com/beust/jcommander/Strings.java new file mode 100644 index 0000000..591a38a --- /dev/null +++ b/src/main/java/com/beust/jcommander/Strings.java @@ -0,0 +1,7 @@ +package com.beust.jcommander; + +public class Strings { + public static boolean isStringEmpty(String s) { + return s == null || "".equals(s); + } +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 01b7c1c..7e9a9bd 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -701,11 +701,21 @@ public class JCommanderTest { private List paramB = Lists.newArrayList(); } - String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; - Params p = new Params(); - new JCommander(p, args).parse(); - Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); - Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + { + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "b2", "b3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1", "b2", "b3" })); + } + + { + String args[] = { "-paramA", "a1", "a2", "-paramB", "b1", "-paramA", "a3" }; + Params p = new Params(); + new JCommander(p, args).parse(); + Assert.assertEquals(p.paramA, Arrays.asList(new String[] { "a1", "a2", "a3" })); + Assert.assertEquals(p.paramB, Arrays.asList(new String[] { "b1" })); + } } @Test(enabled = false, @@ -722,20 +732,45 @@ public class JCommanderTest { j.usage(); } + public void tmp() { + class A { + @Parameter(names = "-b") + public String b; + } + new JCommander(new A()).parse(""); + } + + public void unknownOptionWithDifferentPrefix() { + @Parameters(optionPrefixes = "/") + class SlashSeparator { + + @Parameter(names = "/verbose") + public boolean verbose = false; + + @Parameter(names = "/file") + public String file; + } + SlashSeparator ss = new SlashSeparator(); + try { + new JCommander(ss).parse("/notAParam"); + } catch (ParameterException ex) { + boolean result = ex.getMessage().contains("Unknown option"); + Assert.assertTrue(result); + } + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().commandKey(); -// System.out.println("Help:" + a.help); -// System.out.println("A"); + new JCommanderTest().unknownOptionWithDifferentPrefix(); // class A { -// @Parameter +// @Parameter(names = "-short", required = true) // List parameters; // -// @Parameter(names = "-long") +// @Parameter(names = "-long", required = true) // public long l; // } // A a = new A(); -// new JCommander(a).parse("-long", "32"); +// new JCommander(a).parse(); // System.out.println(a.l); // System.out.println(a.parameters); // ArgsList al = new ArgsList(); -- cgit v1.2.3 From b1112f634c36d088a58d7d623568fe304761b462 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 22 May 2012 14:11:18 -0700 Subject: Clarified the license in the documentation. --- doc/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/index.html b/doc/index.html index de5d755..dd078ed 100644 --- a/doc/index.html +++ b/doc/index.html @@ -755,6 +755,11 @@ Join the JCommander Google g The Javadocs for JCommander can be found here. +

            License

            + +JCommander is released under the Apache 2.0 license. +

            Download

            You can download JCommander from the following locations: -- cgit v1.2.3 From b760ff183fce43d5a0992c18b0de28ac6cb8069e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 May 2012 11:58:00 -0700 Subject: Build script update. --- build-with-maven | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build-with-maven b/build-with-maven index 3d8f9fa..988f7d9 100755 --- a/build-with-maven +++ b/build-with-maven @@ -1,7 +1,8 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign -v=6.5.2beta -export TESTNG=../testng/target/testng-${v}.jar + +#v=6.5.2beta +export TESTNG=`echo ../testng/target/testng*jar` run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml" echo "Launching tests: ${run}" -- cgit v1.2.3 From 2d98ac7055e9d8795989f5859d331a314b853a5b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 May 2012 11:58:18 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.26 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8486308..4b4c1d2 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.26-SNAPSHOT + 1.26 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From bc214eac8b50048166ed4847b355e19c42440728 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 23 May 2012 11:58:24 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b4c1d2..2930e30 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.26 + 1.27-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 5bbf7af0a020eb6da94be078c80300c19b6d77d4 Mon Sep 17 00:00:00 2001 From: Jason Wheeler Date: Tue, 29 May 2012 13:48:17 -0600 Subject: added echoInput parameter to @Parameter annotation to control whether characters are hidden when entering passwords (only works in Java 6 when password == true) --- src/main/java/com/beust/jcommander/JCommander.java | 6 +++--- src/main/java/com/beust/jcommander/Parameter.java | 6 ++++++ src/main/java/com/beust/jcommander/WrappedParameter.java | 4 ++++ src/main/java/com/beust/jcommander/internal/Console.java | 2 +- .../java/com/beust/jcommander/internal/DefaultConsole.java | 2 +- .../java/com/beust/jcommander/internal/JDK6Console.java | 14 ++++++++++---- src/test/java/com/beust/jcommander/JCommanderTest.java | 2 +- 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index c56ecce..61eeae8 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -623,7 +623,7 @@ public class JCommander { // // Password option, use the Console to retrieve the password // - char[] password = readPassword(pd.getDescription()); + char[] password = readPassword(pd.getDescription(), pd.getParameter().echoInput()); pd.addValue(new String(password)); m_requiredFields.remove(pd.getField()); } else { @@ -801,9 +801,9 @@ public class JCommander { * Invoke Console.readPassword through reflection to avoid depending * on Java 6. */ - private char[] readPassword(String description) { + private char[] readPassword(String description, boolean echoInput) { getConsole().print(description + ": "); - return getConsole().readPassword(); + return getConsole().readPassword(echoInput); } private String[] subArray(String[] args, int index) { diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 1b2a00f..0d19dc4 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -100,4 +100,10 @@ public @interface Parameter { * a comma separated splitter will be used. */ Class splitter() default CommaParameterSplitter.class; + + /** + * If true, console will not echo typed input + * Used in conjunction with password = true + */ + boolean echoInput() default false; } diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index ed7f198..991f132 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -46,6 +46,10 @@ public class WrappedParameter { public Class validateWith() { return m_parameter != null ? m_parameter.validateWith() : m_dynamicParameter.validateWith(); } + + public boolean echoInput() { + return m_parameter != null ? m_parameter.echoInput() : false; + } public void addValue(Field field, Object object, Object value) throws IllegalArgumentException, IllegalAccessException { diff --git a/src/main/java/com/beust/jcommander/internal/Console.java b/src/main/java/com/beust/jcommander/internal/Console.java index e2bddb3..95eafe1 100644 --- a/src/main/java/com/beust/jcommander/internal/Console.java +++ b/src/main/java/com/beust/jcommander/internal/Console.java @@ -6,5 +6,5 @@ public interface Console { void println(String msg); - char[] readPassword(); + char[] readPassword(boolean echoInput); } diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java index b838610..65e87ba 100644 --- a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java +++ b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java @@ -16,7 +16,7 @@ public class DefaultConsole implements Console { System.out.println(msg); } - public char[] readPassword() { + public char[] readPassword(boolean echoInput) { try { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader in = new BufferedReader(isr); diff --git a/src/main/java/com/beust/jcommander/internal/JDK6Console.java b/src/main/java/com/beust/jcommander/internal/JDK6Console.java index 62e2a1e..70cb186 100644 --- a/src/main/java/com/beust/jcommander/internal/JDK6Console.java +++ b/src/main/java/com/beust/jcommander/internal/JDK6Console.java @@ -25,15 +25,21 @@ public class JDK6Console implements Console { writer.println(msg); } - public char[] readPassword() { + public char[] readPassword(boolean echoInput) { try { writer.flush(); - Method readPasswordMethod = console.getClass().getDeclaredMethod("readPassword", new Class[0]); - return (char[]) readPasswordMethod.invoke(console, new Object[0]); + Method method; + if (echoInput) { + method = console.getClass().getDeclaredMethod("readLine", new Class[0]); + return ((String) method.invoke(console, new Object[0])).toCharArray(); + } else { + method = console.getClass().getDeclaredMethod("readPassword", new Class[0]); + return (char[]) method.invoke(console, new Object[0]); + } } catch (Exception e) { throw new ParameterException(e); } } -} +} \ No newline at end of file diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 7e9a9bd..60744de 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -666,7 +666,7 @@ public class JCommanderTest { Assert.assertEquals(a.password, "password"); } finally { System.setIn(stdin); - } + } } public void dynamicParameters() { -- cgit v1.2.3 From f8f831066f2571923ca6f457852944dd9a63dfc4 Mon Sep 17 00:00:00 2001 From: Jason Wheeler Date: Tue, 29 May 2012 14:30:30 -0600 Subject: updated doc with info about echoInput --- doc/index.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/index.html b/doc/index.html index de5d755..88a33c2 100644 --- a/doc/index.html +++ b/doc/index.html @@ -157,6 +157,16 @@ Value for -password (Connection password): You will need to type the value at this point before JCommander resumes. +

            Echo Input

            + +In Java 6, by default, you will not be able to see what you type for passwords entered at the prompt (Java 5 and lower will always show the password). However, you can override this by setting echoInput to "true" (default is "false" and this setting only has an effect when password is "true"): +
            +public class ArgsPassword {
            +  @Parameter(names = "-password", description = "Connection password", password = true, echoInput = true)
            +  private String password;
            +}
            +
            +

            Custom types

            By annotation

            -- cgit v1.2.3 From 11b27d31879e17aba45d14a59a972e7b6e40d6f2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 30 May 2012 14:51:50 -0700 Subject: Added: echoInput, used when password=true to echo the characters (Jason Wheeler) --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 8c5b43d..8771e4d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: echoInput, used when password=true to echo the characters (Jason Wheeler) Fixed: variable arities not working when same parameter appears multiple times. ======================== -- cgit v1.2.3 From 9c2bd65ecd9779540bfde5a200ff71d1d503839c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 30 May 2012 22:33:04 -0700 Subject: One more test. --- src/test/java/com/beust/jcommander/JCommanderTest.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 60744de..8b73c3d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -759,9 +759,23 @@ public class JCommanderTest { } } + public void equalSeparator() { + @Parameters(separators = "=", commandDescription = "My command") + class MyClass { + @Parameter(names = { "-p", "--param" }, required = true, + description = "param desc...") + private String param; + } + + MyClass c = new MyClass(); + String expected = "some=value"; + new JCommander(c).parse("--param=" + expected); + Assert.assertEquals(c.param, expected); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().unknownOptionWithDifferentPrefix(); + new JCommanderTest().equalSeparator(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 074b8af3781fbc976f01b43bc3fa0d8ef0431599 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 31 May 2012 11:51:19 -0700 Subject: Fixed: wasn't handling parameters that start with " but don't end with one correctly --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 7 ++----- src/test/java/com/beust/jcommander/JCommanderTest.java | 9 ++++----- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 169a0b3..8b8359c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Current Added: echoInput, used when password=true to echo the characters (Jason Wheeler) +Fixed: wasn't handling parameters that start with " but don't end with one correctly Fixed: if using a different option prefix, unknown option are mistakenly reported as "no main parameter defined" (kurmasz) Fixed: 113: getCommandDescription() returns the description of the main parameter instead of that of the command Fixed: bug with several multiple arity parameters (VariableArityTest) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 61eeae8..dd758ef 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -492,11 +492,8 @@ public class JCommander { */ private static String trim(String string) { String result = string.trim(); - if (result.startsWith("\"")) { - if (result.endsWith("\"")) { - return result.substring(1, result.length() - 1); - } - return result.substring(1); + if (result.startsWith("\"") && result.endsWith("\"")) { + result = result.substring(1, result.length() - 1); } return result; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 8b73c3d..eae0ec8 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -762,15 +762,14 @@ public class JCommanderTest { public void equalSeparator() { @Parameters(separators = "=", commandDescription = "My command") class MyClass { - @Parameter(names = { "-p", "--param" }, required = true, - description = "param desc...") + + @Parameter(names = { "-p", "--param" }, required = true, description = "param desc...") private String param; } - MyClass c = new MyClass(); - String expected = "some=value"; + String expected = "\"hello\"world"; new JCommander(c).parse("--param=" + expected); - Assert.assertEquals(c.param, expected); + Assert.assertEquals(expected, c.param); } @Test(enabled = false) -- cgit v1.2.3 From e903207930001edf324f2623b763df0f75e82a3c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 10 Jun 2012 18:47:55 -0700 Subject: Added: IValueValidator to validate parameter values (typed) as oppoed to IParameterValidator which validates strings --- CHANGELOG | 1 + .../com/beust/jcommander/DynamicParameter.java | 3 ++ .../java/com/beust/jcommander/IValueValidator.java | 14 +++++++++ src/main/java/com/beust/jcommander/Parameter.java | 9 +++++- .../com/beust/jcommander/ParameterDescription.java | 25 +++++++++++++++- .../com/beust/jcommander/WrappedParameter.java | 9 +++++- .../jcommander/validators/NoValueValidator.java | 35 ++++++++++++++++++++++ .../java/com/beust/jcommander/ArgsValidate2.java | 8 ++--- 8 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/IValueValidator.java create mode 100644 src/main/java/com/beust/jcommander/validators/NoValueValidator.java diff --git a/CHANGELOG b/CHANGELOG index 169a0b3..6af59e7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: IValueValidator to validate parameter values (typed) as oppoed to IParameterValidator which validates strings Added: echoInput, used when password=true to echo the characters (Jason Wheeler) Fixed: if using a different option prefix, unknown option are mistakenly reported as "no main parameter defined" (kurmasz) Fixed: 113: getCommandDescription() returns the description of the main parameter instead of that of the command diff --git a/src/main/java/com/beust/jcommander/DynamicParameter.java b/src/main/java/com/beust/jcommander/DynamicParameter.java index 77b8632..2159c1f 100644 --- a/src/main/java/com/beust/jcommander/DynamicParameter.java +++ b/src/main/java/com/beust/jcommander/DynamicParameter.java @@ -3,6 +3,7 @@ package com.beust.jcommander; import static java.lang.annotation.ElementType.FIELD; import com.beust.jcommander.validators.NoValidator; +import com.beust.jcommander.validators.NoValueValidator; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -44,4 +45,6 @@ public @interface DynamicParameter { * The character(s) used to assign the values. */ String assignment() default "="; + + Class validateValueWith() default NoValueValidator.class; } diff --git a/src/main/java/com/beust/jcommander/IValueValidator.java b/src/main/java/com/beust/jcommander/IValueValidator.java new file mode 100644 index 0000000..feed25d --- /dev/null +++ b/src/main/java/com/beust/jcommander/IValueValidator.java @@ -0,0 +1,14 @@ +package com.beust.jcommander; + +public interface IValueValidator { + /** + * Validate the parameter. + * + * @param name The name of the parameter (e.g. "-host"). + * @param value The value of the parameter that we need to validate + * + * @throws ParameterException Thrown if the value of the parameter is invalid. + */ + void validate(String name, T value) throws ParameterException; + +} diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 0d19dc4..c73d69b 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -24,6 +24,7 @@ import com.beust.jcommander.converters.CommaParameterSplitter; import com.beust.jcommander.converters.IParameterSplitter; import com.beust.jcommander.converters.NoConverter; import com.beust.jcommander.validators.NoValidator; +import com.beust.jcommander.validators.NoValueValidator; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -86,10 +87,15 @@ public @interface Parameter { boolean hidden() default false; /** - * The validation class to use. + * Validate the parameter found on the command line. */ Class validateWith() default NoValidator.class; + /** + * Validate the value for this parameter. + */ + Class validateValueWith() default NoValueValidator.class; + /** * @return true if this parameter has a variable arity. See @{IVariableArity} */ @@ -106,4 +112,5 @@ public @interface Parameter { * Used in conjunction with password = true */ boolean echoInput() default false; + } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 832a25b..9299e59 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -19,6 +19,7 @@ package com.beust.jcommander; import com.beust.jcommander.validators.NoValidator; +import com.beust.jcommander.validators.NoValueValidator; import java.lang.reflect.Field; import java.util.ArrayList; @@ -159,7 +160,7 @@ public class ParameterDescription { private void validateDefaultValues(String[] names) { String name = names.length > 0 ? names[0] : ""; - validateParameter(name, m_default.toString()); + validateValueParameter(name, m_default); } public String getLongestName() { @@ -241,6 +242,7 @@ public class ParameterDescription { Class type = m_field.getType(); Object convertedValue = m_jCommander.convertValue(this, value); + validateValueParameter(name, convertedValue); boolean isCollection = Collection.class.isAssignableFrom(type); try { @@ -275,6 +277,27 @@ public class ParameterDescription { } } + private void validateValueParameter(String name, Object value) { + Class validator = m_wrappedParameter.validateValueWith(); + if (validator != null) { + validateValueParameter(validator, name, value); + } + } + + public static void validateValueParameter(Class validator, + String name, Object value) { + try { + if (validator != NoValueValidator.class) { + p("Validating value parameter:" + name + " value:" + value + " validator:" + validator); + } + validator.newInstance().validate(name, value); + } catch (InstantiationException e) { + throw new ParameterException("Can't instantiate validator:" + e); + } catch (IllegalAccessException e) { + throw new ParameterException("Can't instantiate validator:" + e); + } + } + public static void validateParameter(Class validator, String name, String value) { try { diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index 991f132..d49205d 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -46,7 +46,13 @@ public class WrappedParameter { public Class validateWith() { return m_parameter != null ? m_parameter.validateWith() : m_dynamicParameter.validateWith(); } - + + public Class validateValueWith() { + return m_parameter != null + ? m_parameter.validateValueWith() + : m_dynamicParameter.validateValueWith(); + } + public boolean echoInput() { return m_parameter != null ? m_parameter.echoInput() : false; } @@ -92,4 +98,5 @@ public class WrappedParameter { public String getAssignment() { return m_dynamicParameter != null ? m_dynamicParameter.assignment() : ""; } + } diff --git a/src/main/java/com/beust/jcommander/validators/NoValueValidator.java b/src/main/java/com/beust/jcommander/validators/NoValueValidator.java new file mode 100644 index 0000000..21fa820 --- /dev/null +++ b/src/main/java/com/beust/jcommander/validators/NoValueValidator.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2011 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander.validators; + +import com.beust.jcommander.IValueValidator; +import com.beust.jcommander.ParameterException; + +/** + * This is the default value of the validateValueWith attribute. + * + * @author Cedric Beust + */ +public class NoValueValidator implements IValueValidator { + + public void validate(String parameterName, T parameterValue) + throws ParameterException { + } + +} diff --git a/src/test/java/com/beust/jcommander/ArgsValidate2.java b/src/test/java/com/beust/jcommander/ArgsValidate2.java index f45f5df..2b8f07b 100644 --- a/src/test/java/com/beust/jcommander/ArgsValidate2.java +++ b/src/test/java/com/beust/jcommander/ArgsValidate2.java @@ -5,20 +5,20 @@ import com.beust.jcommander.converters.FileConverter; import java.io.File; public class ArgsValidate2 { - public static class FailingValidator implements IParameterValidator { + public static class FailingValidator implements IValueValidator { - public void validate(String name, String value) throws ParameterException { + public void validate(String name, File value) throws ParameterException { throw new ParameterException("Validation will always fail:" + name + " " + value); } } - public static final String POSSIBLE_TEMPLATE_FILE = "mayOrMayNotExist.tempalate"; + public static final String POSSIBLE_TEMPLATE_FILE = "mayOrMayNotExist.template"; @Parameter(names = { "-template"}, description = "The default file may or may not exist", converter = FileConverter.class, - validateWith = FailingValidator.class + validateValueWith = FailingValidator.class ) public File template = new File(POSSIBLE_TEMPLATE_FILE); } -- cgit v1.2.3 From 369d387138b6da9e77e01d82273ef6271580eb47 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 24 Jun 2012 15:12:31 -0700 Subject: Support for setters on top of fields. --- src/main/java/com/beust/jcommander/JCommander.java | 279 ++++++++++++--------- src/main/java/com/beust/jcommander/Parameter.java | 3 +- .../com/beust/jcommander/ParameterDescription.java | 81 +++--- .../java/com/beust/jcommander/Parameterized.java | 224 +++++++++++++++++ .../com/beust/jcommander/WrappedParameter.java | 22 +- .../java/com/beust/jcommander/JCommanderTest.java | 52 +++- .../beust/jcommander/ParametersDelegateTest.java | 4 + .../com/beust/jcommander/args/Args1Setter.java | 93 +++++++ .../jcommander/dynamic/DynamicParameterTest.java | 4 +- 9 files changed, 588 insertions(+), 174 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/Parameterized.java create mode 100644 src/test/java/com/beust/jcommander/args/Args1Setter.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index dd758ef..66ce5f5 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -31,16 +31,13 @@ import com.beust.jcommander.internal.Maps; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; -import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; @@ -79,10 +76,10 @@ public class JCommander { private List m_objects = Lists.newArrayList(); /** - * This field will contain whatever command line parameter is not an option. + * This field/method will contain whatever command line parameter is not an option. * It is expected to be a List. */ - private Field m_mainParameterField = null; + private Parameterized m_mainParameter = null; /** * The object on which we found the main parameter field. @@ -97,19 +94,19 @@ public class JCommander { private ParameterDescription m_mainParameterDescription; /** - * A set of all the fields that are required. During the reflection phase, + * A set of all the parameterizeds that are required. During the reflection phase, * this field receives all the fields that are annotated with required=true * and during the parsing phase, all the fields that are assigned a value * are removed from it. At the end of the parsing phase, if it's not empty, * then some required fields did not receive a value and an exception is * thrown. */ - private Map m_requiredFields = Maps.newHashMap(); + private Map m_requiredFields = Maps.newHashMap(); /** - * A map of all the annotated fields. + * A map of all the parameterized fields/methods/ */ - private Map m_fields = Maps.newHashMap(); + private Map m_fields = Maps.newHashMap(); private ResourceBundle m_bundle; @@ -142,6 +139,7 @@ public class JCommander { private Comparator m_parameterDescriptionComparator = new Comparator() { + @Override public int compare(ParameterDescription p0, ParameterDescription p1) { return p0.getLongestName().compareTo(p1.getLongestName()); } @@ -512,74 +510,138 @@ public class JCommander { private void addDescription(Object object) { Class cls = object.getClass(); - while (!Object.class.equals(cls)) { - for (Field f : cls.getDeclaredFields()) { - p("Field:" + cls.getSimpleName() + "." + f.getName()); - f.setAccessible(true); - Annotation annotation = f.getAnnotation(Parameter.class); - Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class); - Annotation dynamicParameter = f.getAnnotation(DynamicParameter.class); - if (annotation != null) { - // - // @Parameter - // - Parameter p = (Parameter) annotation; - if (p.names().length == 0) { - p("Found main parameter:" + f); - if (m_mainParameterField != null) { - throw new ParameterException("Only one @Parameter with no names attribute is" - + " allowed, found:" + m_mainParameterField + " and " + f); - } - m_mainParameterField = f; - m_mainParameterObject = object; - m_mainParameterAnnotation = p; - m_mainParameterDescription = new ParameterDescription(object, p, f, m_bundle, this); - } else { - for (String name : p.names()) { - if (m_descriptions.containsKey(name)) { - throw new ParameterException("Found the option " + name + " multiple times"); - } - p("Adding description for " + name); - ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle, this); - m_fields.put(f, pd); - m_descriptions.put(name, pd); - - if (p.required()) m_requiredFields.put(f, pd); - } - } - } else if (delegateAnnotation != null) { - // - // @ParametersDelegate - // - try { - Object delegateObject = f.get(object); - if (delegateObject == null){ - throw new ParameterException("Delegate field '" + f.getName() + "' cannot be null."); - } - addDescription(delegateObject); - } catch (IllegalAccessException e) { + List parameterizeds = Parameterized.parseArg(object); + for (Parameterized parameterized : parameterizeds) { + WrappedParameter wp = parameterized.getWrappedParameter(); + if (wp != null && wp.getParameter() != null) { + Parameter annotation = wp.getParameter(); + // + // @Parameter + // + Parameter p = annotation; + if (p.names().length == 0) { + p("Found main parameter:" + parameterized); + if (m_mainParameter != null) { + throw new ParameterException("Only one @Parameter with no names attribute is" + + " allowed, found:" + m_mainParameter + " and " + parameterized); } - } else if (dynamicParameter != null) { - // - // @DynamicParameter - // - DynamicParameter dp = (DynamicParameter) dynamicParameter; - for (String name : dp.names()) { + m_mainParameter = parameterized; + m_mainParameterObject = object; + m_mainParameterAnnotation = p; + m_mainParameterDescription = + new ParameterDescription(object, p, parameterized, m_bundle, this); + } else { + for (String name : p.names()) { if (m_descriptions.containsKey(name)) { throw new ParameterException("Found the option " + name + " multiple times"); } p("Adding description for " + name); - ParameterDescription pd = new ParameterDescription(object, dp, f, m_bundle, this); - m_fields.put(f, pd); + ParameterDescription pd = + new ParameterDescription(object, p, parameterized, m_bundle, this); + m_fields.put(parameterized, pd); m_descriptions.put(name, pd); - if (dp.required()) m_requiredFields.put(f, pd); + if (p.required()) m_requiredFields.put(parameterized, pd); } } + } else if (parameterized.getDelegateAnnotation() != null) { + // + // @ParametersDelegate + // + Object delegateObject = parameterized.get(object); + if (delegateObject == null){ + throw new ParameterException("Delegate field '" + parameterized.getName() + + "' cannot be null."); + } + addDescription(delegateObject); + } else if (wp != null && wp.getDynamicParameter() != null) { + // + // @DynamicParameter + // + DynamicParameter dp = wp.getDynamicParameter(); + for (String name : dp.names()) { + if (m_descriptions.containsKey(name)) { + throw new ParameterException("Found the option " + name + " multiple times"); + } + p("Adding description for " + name); + ParameterDescription pd = + new ParameterDescription(object, dp, parameterized, m_bundle, this); + m_fields.put(parameterized, pd); + m_descriptions.put(name, pd); + + if (dp.required()) m_requiredFields.put(parameterized, pd); + } } - // Traverse the super class until we find Object.class - cls = cls.getSuperclass(); } + +// while (!Object.class.equals(cls)) { +// for (Field f : cls.getDeclaredFields()) { +// p("Field:" + cls.getSimpleName() + "." + f.getName()); +// f.setAccessible(true); +// Annotation annotation = f.getAnnotation(Parameter.class); +// Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class); +// Annotation dynamicParameter = f.getAnnotation(DynamicParameter.class); +// if (annotation != null) { +// // +// // @Parameter +// // +// Parameter p = (Parameter) annotation; +// if (p.names().length == 0) { +// p("Found main parameter:" + f); +// if (m_mainParameterField != null) { +// throw new ParameterException("Only one @Parameter with no names attribute is" +// + " allowed, found:" + m_mainParameterField + " and " + f); +// } +// m_mainParameterField = parameterized; +// m_mainParameterObject = object; +// m_mainParameterAnnotation = p; +// m_mainParameterDescription = new ParameterDescription(object, p, f, m_bundle, this); +// } else { +// for (String name : p.names()) { +// if (m_descriptions.containsKey(name)) { +// throw new ParameterException("Found the option " + name + " multiple times"); +// } +// p("Adding description for " + name); +// ParameterDescription pd = new ParameterDescription(object, p, f, m_bundle, this); +// m_fields.put(f, pd); +// m_descriptions.put(name, pd); +// +// if (p.required()) m_requiredFields.put(f, pd); +// } +// } +// } else if (delegateAnnotation != null) { +// // +// // @ParametersDelegate +// // +// try { +// Object delegateObject = f.get(object); +// if (delegateObject == null){ +// throw new ParameterException("Delegate field '" + f.getName() + "' cannot be null."); +// } +// addDescription(delegateObject); +// } catch (IllegalAccessException e) { +// } +// } else if (dynamicParameter != null) { +// // +// // @DynamicParameter +// // +// DynamicParameter dp = (DynamicParameter) dynamicParameter; +// for (String name : dp.names()) { +// if (m_descriptions.containsKey(name)) { +// throw new ParameterException("Found the option " + name + " multiple times"); +// } +// p("Adding description for " + name); +// ParameterDescription pd = new ParameterDescription(object, dp, f, m_bundle, this); +// m_fields.put(f, pd); +// m_descriptions.put(name, pd); +// +// if (dp.required()) m_requiredFields.put(f, pd); +// } +// } +// } +// // Traverse the super class until we find Object.class +// cls = cls.getSuperclass(); +// } } private void initializeDefaultValue(ParameterDescription pd) { @@ -622,7 +684,7 @@ public class JCommander { // char[] password = readPassword(pd.getDescription(), pd.getParameter().echoInput()); pd.addValue(new String(password)); - m_requiredFields.remove(pd.getField()); + m_requiredFields.remove(pd.getParameterized()); } else { if (pd.getParameter().variableArity()) { // @@ -633,14 +695,14 @@ public class JCommander { // // Regular option // - Class fieldType = pd.getField().getType(); + Class fieldType = pd.getParameterized().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()); + m_requiredFields.remove(pd.getParameterized()); } else { increment = processFixedArity(args, i, pd, fieldType); } @@ -663,11 +725,11 @@ public class JCommander { String value = arg; Object convertedValue = value; - if (m_mainParameterField.getGenericType() instanceof ParameterizedType) { - ParameterizedType p = (ParameterizedType) m_mainParameterField.getGenericType(); + if (m_mainParameter.getGenericType() instanceof ParameterizedType) { + ParameterizedType p = (ParameterizedType) m_mainParameter.getGenericType(); Type cls = p.getActualTypeArguments()[0]; if (cls instanceof Class) { - convertedValue = convertValue(m_mainParameterField, (Class) cls, value); + convertedValue = convertValue(m_mainParameter, (Class) cls, value); } } @@ -699,29 +761,15 @@ public class JCommander { // Mark the parameter descriptions held in m_fields as assigned for (ParameterDescription parameterDescription : m_descriptions.values()) { if (parameterDescription.isAssigned()) { - m_fields.get(parameterDescription.getField()).setAssigned(true); + m_fields.get(parameterDescription.getParameterized()).setAssigned(true); } } } - /** - * @return the generic type of the collection for this field, or null if not applicable. - */ - private Type findFieldGenericType(Field field) { - if (field.getGenericType() instanceof ParameterizedType) { - ParameterizedType p = (ParameterizedType) field.getGenericType(); - Type cls = p.getActualTypeArguments()[0]; - if (cls instanceof Class) { - return cls; - } - } - - return null; - } - private class DefaultVariableArity implements IVariableArity { + @Override public int processVariableArity(String optionName, String[] options) { int i = 0; while (i < options.length && !isOption(options, options[i])) { @@ -774,14 +822,14 @@ public class JCommander { (Boolean.class.isAssignableFrom(fieldType) || boolean.class.isAssignableFrom(fieldType))) { pd.addValue("true"); - m_requiredFields.remove(pd.getField()); + m_requiredFields.remove(pd.getParameterized()); } else if (index < args.length - 1) { int offset = "--".equals(args[index + 1]) ? 1 : 0; if (index + arity < args.length) { for (int j = 1; j <= arity; j++) { pd.addValue(trim(args[index + j + offset])); - m_requiredFields.remove(pd.getField()); + m_requiredFields.remove(pd.getParameterized()); } index += arity + offset; } else { @@ -818,26 +866,21 @@ public class JCommander { * error message). */ private List getMainParameter(String arg) { - if (m_mainParameterField == null) { + if (m_mainParameter == null) { throw new ParameterException( "Was passed main parameter '" + arg + "' but no main parameter was defined"); } - try { - List result = (List) m_mainParameterField.get(m_mainParameterObject); - if (result == null) { - result = Lists.newArrayList(); - if (! List.class.isAssignableFrom(m_mainParameterField.getType())) { - throw new ParameterException("Main parameter field " + m_mainParameterField - + " needs to be of type List, not " + m_mainParameterField.getType()); - } - m_mainParameterField.set(m_mainParameterObject, result); + List result = (List) m_mainParameter.get(m_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()); } - return result; - } - catch(IllegalAccessException ex) { - throw new ParameterException("Couldn't access main parameter: " + ex.getMessage()); + m_mainParameter.set(m_mainParameterObject, result); } + return result; } public String getMainParameterDescription() { @@ -846,15 +889,15 @@ public class JCommander { : null; } - private int longestName(Collection objects) { - int result = 0; - for (Object o : objects) { - int l = o.toString().length(); - if (l > result) result = l; - } - - return result; - } +// private int longestName(Collection objects) { +// int result = 0; +// for (Object o : objects) { +// int l = o.toString().length(); +// if (l > result) result = l; +// } +// +// return result; +// } /** * Set the program name (used only in the usage). @@ -1128,7 +1171,7 @@ public class JCommander { } public Object convertValue(ParameterDescription pd, String value) { - return convertValue(pd.getField(), pd.getField().getType(), value); + return convertValue(pd.getParameterized(), pd.getParameterized().getType(), value); } /** @@ -1136,8 +1179,8 @@ public class JCommander { * @param type The type of the actual parameter * @param value The value to convert */ - public Object convertValue(Field field, Class type, String value) { - Parameter annotation = field.getAnnotation(Parameter.class); + public Object convertValue(Parameterized parameterized, Class type, String value) { + Parameter annotation = parameterized.getParameter(); // Do nothing if it's a @DynamicParameter if (annotation == null) return value; @@ -1158,7 +1201,7 @@ public class JCommander { } if (converterClass == null) { - Type elementType = findFieldGenericType(field); + Type elementType = parameterized.findFieldGenericType(); converterClass = elementType != null ? findConverter((Class>) elementType) : StringConverter.class; @@ -1194,7 +1237,7 @@ public class JCommander { } else { converter = instantiateConverter(optionName, converterClass); if (type.isAssignableFrom(List.class) - && field.getGenericType() instanceof ParameterizedType) { + && parameterized.getGenericType() instanceof ParameterizedType) { // The field is a List if (listConverterWasSpecified) { diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index c73d69b..51b941f 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -19,6 +19,7 @@ package com.beust.jcommander; import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; import com.beust.jcommander.converters.CommaParameterSplitter; import com.beust.jcommander.converters.IParameterSplitter; @@ -30,7 +31,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) -@Target({ FIELD }) +@Target({ FIELD, METHOD }) public @interface Parameter { /** diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 9299e59..5f4a0a7 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -21,7 +21,6 @@ package com.beust.jcommander; import com.beust.jcommander.validators.NoValidator; import com.beust.jcommander.validators.NoValueValidator; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; @@ -42,7 +41,8 @@ public class ParameterDescription { private Parameter m_parameterAnnotation; private DynamicParameter m_dynamicParameterAnnotation; - private Field m_field; + /** The field/method */ + private Parameterized m_parameterized; /** Keep track of whether a value was added to flag an error */ private boolean m_assigned = false; private ResourceBundle m_bundle; @@ -52,23 +52,25 @@ public class ParameterDescription { /** Longest of the names(), used to present usage() alphabetically */ private String m_longestName = ""; - public ParameterDescription(Object object, DynamicParameter annotation, Field field, + public ParameterDescription(Object object, DynamicParameter annotation, + Parameterized parameterized, ResourceBundle bundle, JCommander jc) { - if (! Map.class.isAssignableFrom(field.getType())) { - throw new ParameterException("@DynamicParameter " + field.getName() + " should be of type " - + "Map but is " + field.getType().getName()); + if (! Map.class.isAssignableFrom(parameterized.getType())) { + throw new ParameterException("@DynamicParameter " + parameterized.getName() + + " should be of type " + + "Map but is " + parameterized.getType().getName()); } m_dynamicParameterAnnotation = annotation; m_wrappedParameter = new WrappedParameter(m_dynamicParameterAnnotation); - init(object, field, bundle, jc); + init(object, parameterized, bundle, jc); } - public ParameterDescription(Object object, Parameter annotation, Field field, + public ParameterDescription(Object object, Parameter annotation, Parameterized parameterized, ResourceBundle bundle, JCommander jc) { m_parameterAnnotation = annotation; m_wrappedParameter = new WrappedParameter(m_parameterAnnotation); - init(object, field, bundle, jc); + init(object, parameterized, bundle, jc); } /** @@ -115,10 +117,10 @@ public class ParameterDescription { } @SuppressWarnings("unchecked") - private void init(Object object, Field field, ResourceBundle bundle, + private void init(Object object, Parameterized parameterized, ResourceBundle bundle, JCommander jCommander) { m_object = object; - m_field = field; + m_parameterized = parameterized; m_bundle = bundle; if (m_bundle == null) { m_bundle = findResourceBundle(object); @@ -127,9 +129,9 @@ public class ParameterDescription { if (m_parameterAnnotation != null) { String description; - if (Enum.class.isAssignableFrom(field.getType()) + if (Enum.class.isAssignableFrom(parameterized.getType()) && m_parameterAnnotation.description().isEmpty()) { - description = "Options: " + EnumSet.allOf((Class) field.getType()); + description = "Options: " + EnumSet.allOf((Class) parameterized.getType()); }else { description = m_parameterAnnotation.description(); } @@ -144,7 +146,7 @@ public class ParameterDescription { } try { - m_default = m_field.get(m_object); + m_default = parameterized.get(object); } catch (Exception e) { } @@ -194,18 +196,14 @@ public class ParameterDescription { return m_wrappedParameter; } - public Field getField() { - return m_field; + public Parameterized getParameterized() { + return m_parameterized; } private boolean isMultiOption() { - Class fieldType = m_field.getType(); + Class fieldType = m_parameterized.getType(); return fieldType.equals(List.class) || fieldType.equals(Set.class) - || isDynamicParameter(m_field); - } - - private boolean isDynamicParameter(Field field) { - return field.getAnnotation(DynamicParameter.class) != null; + || m_parameterized.isDynamicParameter(); } public void addValue(String value) { @@ -231,7 +229,7 @@ public class ParameterDescription { */ public void addValue(String value, boolean isDefault) { p("Adding " + (isDefault ? "default " : "") + "value:" + value - + " to parameter:" + m_field.getName()); + + " to parameter:" + m_parameterized.getName()); String name = m_wrappedParameter.names()[0]; if (m_assigned && ! isMultiOption()) { throw new ParameterException("Can only specify option " + name + " once."); @@ -239,35 +237,30 @@ public class ParameterDescription { validateParameter(name, value); - Class type = m_field.getType(); + Class type = m_parameterized.getType(); Object convertedValue = m_jCommander.convertValue(this, value); validateValueParameter(name, convertedValue); boolean isCollection = Collection.class.isAssignableFrom(type); - try { - if (isCollection) { - @SuppressWarnings("unchecked") - Collection l = (Collection) m_field.get(m_object); - if (l == null || fieldIsSetForTheFirstTime(isDefault)) { - l = newCollection(type); - m_field.set(m_object, l); - } - if (convertedValue instanceof Collection) { - l.addAll((Collection) convertedValue); - } else { // if (isMainParameter || m_parameterAnnotation.arity() > 1) { - l.add(convertedValue); + if (isCollection) { + @SuppressWarnings("unchecked") + Collection l = (Collection) m_parameterized.get(m_object); + if (l == null || fieldIsSetForTheFirstTime(isDefault)) { + l = newCollection(type); + m_parameterized.set(m_object, l); + } + if (convertedValue instanceof Collection) { + l.addAll((Collection) convertedValue); + } else { // if (isMainParameter || m_parameterAnnotation.arity() > 1) { + l.add(convertedValue); // } else { // l. - } - } else { - m_wrappedParameter.addValue(m_field, m_object, convertedValue); } - if (! isDefault) m_assigned = true; - } - catch(IllegalAccessException ex) { - ex.printStackTrace(); + } else { + m_wrappedParameter.addValue(m_parameterized, m_object, convertedValue); } + if (! isDefault) m_assigned = true; } private void validateParameter(String name, String value) { @@ -346,7 +339,7 @@ public class ParameterDescription { @Override public String toString() { - return "[ParameterDescription " + m_field.getName() + "]"; + return "[ParameterDescription " + m_parameterized.getName() + "]"; } public boolean isDynamicParameter() { diff --git a/src/main/java/com/beust/jcommander/Parameterized.java b/src/main/java/com/beust/jcommander/Parameterized.java new file mode 100644 index 0000000..ec698fa --- /dev/null +++ b/src/main/java/com/beust/jcommander/Parameterized.java @@ -0,0 +1,224 @@ +package com.beust.jcommander; + +import com.beust.jcommander.internal.Lists; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; + +/** + * Encapsulate a field or a method annotated with @Parameter or @DynamicParameter + */ +public class Parameterized { + + // Either a method or a field + private Field m_field; + private Method m_method; + private Method m_getter; + + // Either of these two + private WrappedParameter m_wrappedParameter; + private ParametersDelegate m_parametersDelegate; + + public Parameterized(WrappedParameter wp, ParametersDelegate pd, + Field field, Method method) { + m_wrappedParameter = wp; + m_method = method; + m_field = field; + if (m_field != null) { + m_field.setAccessible(true); + } + m_parametersDelegate = pd; + } + + public static List parseArg(Object arg) { + List result = Lists.newArrayList(); + + Class cls = arg.getClass(); + while (!Object.class.equals(cls)) { + for (Field f : cls.getDeclaredFields()) { + Annotation annotation = f.getAnnotation(Parameter.class); + Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class); + Annotation dynamicParameter = f.getAnnotation(DynamicParameter.class); + if (annotation != null) { + result.add(new Parameterized(new WrappedParameter((Parameter) annotation), null, + f, null)); + } else if (dynamicParameter != null) { + result.add(new Parameterized(new WrappedParameter((DynamicParameter) dynamicParameter), null, + f, null)); + } else if (delegateAnnotation != null) { + result.add(new Parameterized(null, (ParametersDelegate) delegateAnnotation, + f, null)); + } + } + cls = cls.getSuperclass(); + } + + // Reassigning + cls = arg.getClass(); + while (!Object.class.equals(cls)) { + for (Method m : cls.getDeclaredMethods()) { + Annotation annotation = m.getAnnotation(Parameter.class); + Annotation delegateAnnotation = m.getAnnotation(ParametersDelegate.class); + Annotation dynamicParameter = m.getAnnotation(DynamicParameter.class); + if (annotation != null) { + result.add(new Parameterized(new WrappedParameter((Parameter) annotation), null, + null, m)); + } else if (dynamicParameter != null) { + result.add(new Parameterized(new WrappedParameter((DynamicParameter) annotation), null, + null, m)); + } else if (delegateAnnotation != null) { + result.add(new Parameterized(null, (ParametersDelegate) delegateAnnotation, + null, m)); + } + } + cls = cls.getSuperclass(); + } + + return result; + } + + public WrappedParameter getWrappedParameter() { + return m_wrappedParameter; + } + + public Class getType() { + if (m_method != null) { + return m_method.getParameterTypes()[0]; + } else { + return m_field.getType(); + } + } + + public String getName() { + if (m_method != null) { + return m_method.getName(); + } else { + return m_field.getName(); + } + } + + public Object get(Object object) { + try { + if (m_method != null) { + if (m_getter == null) { + m_getter = m_method.getDeclaringClass() + .getMethod("g" + m_method.getName().substring(1), + new Class[0]); + } + return m_getter.invoke(object); + } else { + return m_field.get(object); + } + } catch (SecurityException e) { + throw new ParameterException(e); + } catch (NoSuchMethodException e) { + throw new ParameterException(e); + } catch (IllegalArgumentException e) { + throw new ParameterException(e); + } catch (IllegalAccessException e) { + throw new ParameterException(e); + } catch (InvocationTargetException e) { + throw new ParameterException(e); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((m_field == null) ? 0 : m_field.hashCode()); + result = prime * result + ((m_method == null) ? 0 : m_method.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Parameterized other = (Parameterized) obj; + if (m_field == null) { + if (other.m_field != null) + return false; + } else if (!m_field.equals(other.m_field)) + return false; + if (m_method == null) { + if (other.m_method != null) + return false; + } else if (!m_method.equals(other.m_method)) + return false; + return true; + } + + public boolean isDynamicParameter(Field field) { + if (m_method != null) { + return m_method.getAnnotation(DynamicParameter.class) != null; + } else { + return m_field.getAnnotation(DynamicParameter.class) != null; + } + } + + public void set(Object object, Object value) { + try { + if (m_method != null) { + m_method.invoke(object, value); + } else { + m_field.set(object, value); + } + } catch (IllegalArgumentException ex) { + throw new ParameterException(ex); + } catch (IllegalAccessException ex) { + throw new ParameterException(ex); + } catch (InvocationTargetException ex) { + throw new ParameterException(ex); + } + } + + public ParametersDelegate getDelegateAnnotation() { + return m_parametersDelegate; + } + + public Type getGenericType() { + if (m_method != null) { + return m_method.getGenericParameterTypes()[0]; + } else { + return m_field.getGenericType(); + } + } + + public Parameter getParameter() { + return m_wrappedParameter.getParameter(); + } + + /** + * @return the generic type of the collection for this field, or null if not applicable. + */ + public Type findFieldGenericType() { + if (m_method != null) { + return null; + } else { + if (m_field.getGenericType() instanceof ParameterizedType) { + ParameterizedType p = (ParameterizedType) m_field.getGenericType(); + Type cls = p.getActualTypeArguments()[0]; + if (cls instanceof Class) { + return cls; + } + } + } + + return null; + } + + public boolean isDynamicParameter() { + return m_wrappedParameter.getDynamicParameter() != null; + } + +} diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index d49205d..1f690a0 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -1,6 +1,5 @@ package com.beust.jcommander; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -19,6 +18,14 @@ public class WrappedParameter { m_dynamicParameter = p; } + public Parameter getParameter() { + return m_parameter; + } + + public DynamicParameter getDynamicParameter() { + return m_dynamicParameter; + } + public int arity() { return m_parameter != null ? m_parameter.arity() : 1; } @@ -57,10 +64,9 @@ public class WrappedParameter { return m_parameter != null ? m_parameter.echoInput() : false; } - public void addValue(Field field, Object object, Object value) - throws IllegalArgumentException, IllegalAccessException { + public void addValue(Parameterized parameterized, Object object, Object value) { if (m_parameter != null) { - field.set(object, value); + parameterized.set(object, value); } else { String a = m_dynamicParameter.assignment(); String sv = value.toString(); @@ -71,15 +77,15 @@ public class WrappedParameter { "Dynamic parameter expected a value of the form a" + a + "b" + " but got:" + sv); } - callPut(object, field, sv.substring(0, aInd), sv.substring(aInd + 1)); + callPut(object, parameterized, sv.substring(0, aInd), sv.substring(aInd + 1)); } } - private void callPut(Object object, Field field, String key, String value) { + private void callPut(Object object, Parameterized parameterized, String key, String value) { try { Method m; - m = findPut(field.getType()); - m.invoke(field.get(object), key, value); + m = findPut(parameterized.getType()); + m.invoke(parameterized.get(object), key, value); } catch (SecurityException e) { e.printStackTrace(); } catch(IllegalAccessException e) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index eae0ec8..2f05590 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -19,6 +19,7 @@ package com.beust.jcommander; import com.beust.jcommander.args.Args1; +import com.beust.jcommander.args.Args1Setter; import com.beust.jcommander.args.Args2; import com.beust.jcommander.args.ArgsArityString; import com.beust.jcommander.args.ArgsBooleanArity; @@ -241,6 +242,38 @@ public class JCommanderTest { Assert.assertEquals(args.rest.get(0), "rest"); } + public void arityStringsSetter() { + class ArgsArityStringSetter { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public void setPairs(List pairs) { + this.pairs = pairs; + } + public List getPairs() { + return this.pairs; + } + public List pairs; + + @Parameter(description = "Rest") + public void setRest(List rest) { + this.rest = rest; + } + public List getRest() { + return this.rest; + } + public List rest; + } + ArgsArityStringSetter args = new ArgsArityStringSetter(); + String[] argv = { "-pairs", "pair0", "pair1", "rest" }; + new JCommander(args, argv); + + Assert.assertEquals(args.pairs.size(), 2); + Assert.assertEquals(args.pairs.get(0), "pair0"); + Assert.assertEquals(args.pairs.get(1), "pair1"); + Assert.assertEquals(args.rest.size(), 1); + Assert.assertEquals(args.rest.get(0), "rest"); + } + @Test(expectedExceptions = ParameterException.class) public void arity2Fail() { ArgsArityString args = new ArgsArityString(); @@ -609,6 +642,7 @@ public class JCommanderTest { public void mainParameterShouldBeValidate() { class V implements IParameterValidator { + @Override public void validate(String name, String value) throws ParameterException { Assert.assertEquals("a", value); } @@ -772,9 +806,25 @@ public class JCommanderTest { Assert.assertEquals(expected, c.param); } + public void simpleArgsSetter() throws ParseException { + Args1Setter args = new Args1Setter(); + String[] argv = { "-debug", "-log", "2", "-float", "1.2", "-double", "1.3", "-bigdecimal", "1.4", + "-date", "2011-10-26", "-groups", "unit", "a", "b", "c" }; + new JCommander(args, argv); + + Assert.assertTrue(args.debug); + Assert.assertEquals(args.verbose.intValue(), 2); + Assert.assertEquals(args.groups, "unit"); + Assert.assertEquals(args.parameters, Arrays.asList("a", "b", "c")); + Assert.assertEquals(args.floa, 1.2f, 0.1f); + Assert.assertEquals(args.doub, 1.3f, 0.1f); + Assert.assertEquals(args.bigd, new BigDecimal("1.4")); + Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26")); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().equalSeparator(); + new JCommanderTest().arityStringsSetter(); // class A { // @Parameter(names = "-short", required = true) // List parameters; diff --git a/src/test/java/com/beust/jcommander/ParametersDelegateTest.java b/src/test/java/com/beust/jcommander/ParametersDelegateTest.java index 3041438..46c7c6a 100644 --- a/src/test/java/com/beust/jcommander/ParametersDelegateTest.java +++ b/src/test/java/com/beust/jcommander/ParametersDelegateTest.java @@ -220,4 +220,8 @@ public class ParametersDelegateTest { cmd.parse("command main params".split(" ")); } + + public static void main(String[] args) { + new ParametersDelegateTest().commandTest(); + } } diff --git a/src/test/java/com/beust/jcommander/args/Args1Setter.java b/src/test/java/com/beust/jcommander/args/Args1Setter.java new file mode 100644 index 0000000..10f9ef3 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/Args1Setter.java @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2010 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.internal.Lists; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +public class Args1Setter { + @Parameter + public void setParameters(List p) { + parameters = p; + } + + public List getParameters() { + return this.parameters; + } + public List parameters = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity", required = true) + public void setVerbose(Integer v) { + verbose = v; + } + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public void setGroups(String g) { + groups = g; + } + + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public void setDebug(boolean d) { + debug = d; + } + + public boolean debug = false; + + @Parameter(names = "-long", description = "A long number") + public void setLong(long ll) { + l = ll; + } + + public long l; + + @Parameter(names = "-double", description = "A double number") + public void setDouble(double d) { + doub = d; + } + + public double doub; + + @Parameter(names = "-float", description = "A float number") + public void setFloat(float f) { + floa = f; + } + + public float floa; + + @Parameter(names = "-bigdecimal", description = "A BigDecimal number") + public void setBigDecimal(BigDecimal bd) { + bigd = bd; + } + + public BigDecimal bigd; + + @Parameter(names = "-date", description = "An ISO 8601 formatted date.") + public void setDate(Date d) { + date = d; + } + + public Date date; +} diff --git a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java index 190b8b4..98327bd 100644 --- a/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java +++ b/src/test/java/com/beust/jcommander/dynamic/DynamicParameterTest.java @@ -50,11 +50,11 @@ public class DynamicParameterTest { @Test(enabled = false) public static void main(String[] args) { DynamicParameterTest dpt = new DynamicParameterTest(); -// dpt.simple(); + dpt.simpleWithSpaces(); // dpt.nonMapShouldThrow(); // dpt.wrongSeparatorShouldThrow(); // dpt.differentAssignment(); // dpt.arity0(); - dpt.usage(); +// dpt.usage(); } } -- cgit v1.2.3 From c675ef5201552ed809a1cb12e18f2fc3e25a7c9a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 4 Jul 2012 13:23:31 -0700 Subject: Added: @Parameter(help = true) --- CHANGELOG | 1 + doc/index.html | 11 +++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 11 +++++++++++ src/main/java/com/beust/jcommander/Parameter.java | 5 +++++ .../java/com/beust/jcommander/ParameterDescription.java | 4 ++++ .../java/com/beust/jcommander/WrappedParameter.java | 4 ++++ src/test/java/com/beust/jcommander/JCommanderTest.java | 17 ++++++++++++++++- 7 files changed, 52 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 4066619..cbff6f6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Current Added: IValueValidator to validate parameter values (typed) as oppoed to IParameterValidator which validates strings Added: echoInput, used when password=true to echo the characters (Jason Wheeler) +Added: @Parameter(help = true) Fixed: wasn't handling parameters that start with " but don't end with one correctly Fixed: if using a different option prefix, unknown option are mistakenly reported as "no main parameter defined" (kurmasz) Fixed: 113: getCommandDescription() returns the description of the main parameter instead of that of the command diff --git a/doc/index.html b/doc/index.html index 5f76020..0dc79b3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -560,6 +560,17 @@ JCommander jc = new JCommander(new Args()); jc.setDefaultProvider(DEFAULT_PROVIDER); +

            Help parameter

            + +If one of your parameters is used to display some help or usage, you need use the help attribute: + +
            +  @Parameter(names = "--help", help = true)
            +  private boolean help;
            +
            + +If you omit this boolean, JCommander will instead issue an error message when it tries to validate your command and it finds that you didn't specify some of the required parameters. +

            More complex syntaxes (commands)

            Complex tools such as git or svn understand a whole set of commands, each of which with their own specific syntax: diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 66ce5f5..63b935c 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -146,6 +146,8 @@ public class JCommander { }; private int m_columnSize = 79; + + private boolean m_helpWasSpecified; private static Console m_console; @@ -299,6 +301,11 @@ public class JCommander { * Make sure that all the required parameters have received a value. */ private void validateOptions() { + // No validation if we found a help parameter + if (m_helpWasSpecified) { + return; + } + if (! m_requiredFields.isEmpty()) { StringBuilder missingFields = new StringBuilder(); for (ParameterDescription pd : m_requiredFields.values()) { @@ -706,6 +713,10 @@ public class JCommander { } else { increment = processFixedArity(args, i, pd, fieldType); } + // If it's a help option, remember for later + if (pd.isHelp()) { + m_helpWasSpecified = true; + } } } } else { diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 51b941f..974eeaa 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -114,4 +114,9 @@ public @interface Parameter { */ boolean echoInput() default false; + /** + * If true, this parameter is for help. If such a parameter is specified, + * required parameters are no longer checked for their presence. + */ + boolean help() default false; } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 5f4a0a7..6480ea7 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -345,4 +345,8 @@ public class ParameterDescription { public boolean isDynamicParameter() { return m_dynamicParameterAnnotation != null; } + + public boolean isHelp() { + return m_wrappedParameter.isHelp(); + } } diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index 1f690a0..52cafc4 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -105,4 +105,8 @@ public class WrappedParameter { return m_dynamicParameter != null ? m_dynamicParameter.assignment() : ""; } + public boolean isHelp() { + return m_parameter != null && m_parameter.help(); + } + } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 2f05590..9dba74d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -822,9 +822,24 @@ public class JCommanderTest { Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26")); } + public void verifyHelp() { + class Arg { + @Parameter(names = "--help", help = true) + public boolean help = false; + + @Parameter(names = "file", required = true) + public String file; + } + Arg arg = new Arg(); + String[] argv = { "--help" }; + new JCommander(arg, argv); + + Assert.assertTrue(arg.help); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().arityStringsSetter(); + new JCommanderTest().verifyHelp(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 4fffe9695cd7de30af26aa8f5f26b3752df93e35 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Jul 2012 11:01:22 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.27 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2930e30..ab8c938 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.27-SNAPSHOT + 1.27 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From ff095d8ec88edd62b9657c9af73bfae4b4230e7f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Jul 2012 11:01:34 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ab8c938..a5e2b54 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.27 + 1.28-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 38a6e3956ec3eed56b8d7b8c4de110a5c6493887 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 5 Jul 2012 11:11:32 -0700 Subject: 1.27 --- doc/index.html | 4 ++-- upload | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/index.html b/doc/index.html index 0dc79b3..aabfa53 100644 --- a/doc/index.html +++ b/doc/index.html @@ -39,7 +39,7 @@ - Last updated: April 25th, 2012 + Last updated: July 5th, 2012 Cédric Beust @@ -794,7 +794,7 @@ You can download JCommander from the following locations: <groupId>com.beust</groupId> <artifactId>jcommander</artifactId> - <version>1.25</version> + <version>1.27</version> diff --git a/upload b/upload index a177639..ee46516 100755 --- a/upload +++ b/upload @@ -1,4 +1,4 @@ -scp doc/index.html target/jcommander-1.7.jar beust.com@beust.com:domains/jcommander.org/html +scp doc/index.html target/jcommander-1.27.jar beust.com@beust.com:domains/jcommander.org/html mvn javadoc:javadoc scp -r target/site/apidocs beust.com@beust.com:domains/jcommander.org/html -- cgit v1.2.3 From a85606887e78c48622d46032b39887542496f2c8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 6 Jul 2012 23:25:36 -0700 Subject: CHANGELOG. --- CHANGELOG | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index cbff6f6..72e483f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Current -Added: IValueValidator to validate parameter values (typed) as oppoed to IParameterValidator which validates strings + +1.27 +1012/08/05 +Added: IValueValidator to validate parameter values (typed) as opposed to IParameterValidator which validates strings Added: echoInput, used when password=true to echo the characters (Jason Wheeler) Added: @Parameter(help = true) Fixed: wasn't handling parameters that start with " but don't end with one correctly -- cgit v1.2.3 From e0c1cdc5cea32d7551cf92069adfd529fc48a756 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Fri, 6 Jul 2012 23:26:16 -0700 Subject: If a setter throws ParameterException, don't wrap it into another ParameterException. --- src/main/java/com/beust/jcommander/Parameterized.java | 7 ++++++- .../java/com/beust/jcommander/JCommanderTest.java | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/Parameterized.java b/src/main/java/com/beust/jcommander/Parameterized.java index ec698fa..302d2b6 100644 --- a/src/main/java/com/beust/jcommander/Parameterized.java +++ b/src/main/java/com/beust/jcommander/Parameterized.java @@ -178,7 +178,12 @@ public class Parameterized { } catch (IllegalAccessException ex) { throw new ParameterException(ex); } catch (InvocationTargetException ex) { - throw new ParameterException(ex); + // If a ParameterException was thrown, don't wrap it into another one + if (ex.getTargetException() instanceof ParameterException) { + throw (ParameterException) ex.getTargetException(); + } else { + throw new ParameterException(ex); + } } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9dba74d..8b1e761 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -837,9 +837,26 @@ public class JCommanderTest { Assert.assertTrue(arg.help); } + public void setterThatThrows() { + class Arg { + @Parameter(names = "--host") + public void setHost(String host) { + throw new ParameterException("Illegal host"); + } + } + boolean passed = false; + try { + new JCommander(new Arg(), new String[] { "--host", "host" }); + } catch(ParameterException ex) { + Assert.assertEquals(ex.getCause(), null); + passed = true; + } + Assert.assertTrue(passed, "Should have thrown an exception"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().verifyHelp(); + new JCommanderTest().setterThatThrows(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 6e35863858ca9c8c0584a98797981bfa9867ff02 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Jul 2012 08:57:33 -0700 Subject: Make getter methods optional. --- src/main/java/com/beust/jcommander/Parameterized.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/Parameterized.java b/src/main/java/com/beust/jcommander/Parameterized.java index 302d2b6..14ce975 100644 --- a/src/main/java/com/beust/jcommander/Parameterized.java +++ b/src/main/java/com/beust/jcommander/Parameterized.java @@ -117,7 +117,7 @@ public class Parameterized { } catch (SecurityException e) { throw new ParameterException(e); } catch (NoSuchMethodException e) { - throw new ParameterException(e); + return null; } catch (IllegalArgumentException e) { throw new ParameterException(e); } catch (IllegalAccessException e) { -- cgit v1.2.3 From 1b0c674e93eb5d4a34607797783d163800e73a1e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Jul 2012 08:57:53 -0700 Subject: Moved the method tests in their own class. --- .../java/com/beust/jcommander/JCommanderTest.java | 51 +---------------- .../com/beust/jcommander/MethodSetterTest.java | 66 ++++++++++++++++++++++ src/test/resources/testng.xml | 1 + 3 files changed, 68 insertions(+), 50 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/MethodSetterTest.java diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 8b1e761..428fdfe 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -242,38 +242,6 @@ public class JCommanderTest { Assert.assertEquals(args.rest.get(0), "rest"); } - public void arityStringsSetter() { - class ArgsArityStringSetter { - - @Parameter(names = "-pairs", arity = 2, description = "Pairs") - public void setPairs(List pairs) { - this.pairs = pairs; - } - public List getPairs() { - return this.pairs; - } - public List pairs; - - @Parameter(description = "Rest") - public void setRest(List rest) { - this.rest = rest; - } - public List getRest() { - return this.rest; - } - public List rest; - } - ArgsArityStringSetter args = new ArgsArityStringSetter(); - String[] argv = { "-pairs", "pair0", "pair1", "rest" }; - new JCommander(args, argv); - - Assert.assertEquals(args.pairs.size(), 2); - Assert.assertEquals(args.pairs.get(0), "pair0"); - Assert.assertEquals(args.pairs.get(1), "pair1"); - Assert.assertEquals(args.rest.size(), 1); - Assert.assertEquals(args.rest.get(0), "rest"); - } - @Test(expectedExceptions = ParameterException.class) public void arity2Fail() { ArgsArityString args = new ArgsArityString(); @@ -837,26 +805,9 @@ public class JCommanderTest { Assert.assertTrue(arg.help); } - public void setterThatThrows() { - class Arg { - @Parameter(names = "--host") - public void setHost(String host) { - throw new ParameterException("Illegal host"); - } - } - boolean passed = false; - try { - new JCommander(new Arg(), new String[] { "--host", "host" }); - } catch(ParameterException ex) { - Assert.assertEquals(ex.getCause(), null); - passed = true; - } - Assert.assertTrue(passed, "Should have thrown an exception"); - } - @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().setterThatThrows(); + new JCommanderTest().verifyHelp(); // class A { // @Parameter(names = "-short", required = true) // List parameters; diff --git a/src/test/java/com/beust/jcommander/MethodSetterTest.java b/src/test/java/com/beust/jcommander/MethodSetterTest.java new file mode 100644 index 0000000..8790e4c --- /dev/null +++ b/src/test/java/com/beust/jcommander/MethodSetterTest.java @@ -0,0 +1,66 @@ +package com.beust.jcommander; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * Tests for @Parameter on top of methods. + */ +@Test +public class MethodSetterTest { + public void arityStringsSetter() { + class ArgsArityStringSetter { + + @Parameter(names = "-pairs", arity = 2, description = "Pairs") + public void setPairs(List pairs) { + this.pairs = pairs; + } + public List getPairs() { + return this.pairs; + } + public List pairs; + + @Parameter(description = "Rest") + public void setRest(List rest) { + this.rest = rest; + } +// public List getRest() { +// return this.rest; +// } + public List rest; + } + ArgsArityStringSetter args = new ArgsArityStringSetter(); + String[] argv = { "-pairs", "pair0", "pair1", "rest" }; + new JCommander(args, argv); + + Assert.assertEquals(args.pairs.size(), 2); + Assert.assertEquals(args.pairs.get(0), "pair0"); + Assert.assertEquals(args.pairs.get(1), "pair1"); + Assert.assertEquals(args.rest.size(), 1); + Assert.assertEquals(args.rest.get(0), "rest"); + } + + public void setterThatThrows() { + class Arg { + @Parameter(names = "--host") + public void setHost(String host) { + throw new ParameterException("Illegal host"); + } + } + boolean passed = false; + try { + new JCommander(new Arg(), new String[] { "--host", "host" }); + } catch(ParameterException ex) { + Assert.assertEquals(ex.getCause(), null); + passed = true; + } + Assert.assertTrue(passed, "Should have thrown an exception"); + } + + @Test(enabled = false) + public static void main(String[] args) throws Exception { + new MethodSetterTest().arityStringsSetter(); + } +} diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 2ccd4ef..c9639d4 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -13,6 +13,7 @@ + -- cgit v1.2.3 From 465c23886b71843fa1987f8b8802a46214d48e23 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Jul 2012 09:02:39 -0700 Subject: Test for getter returning non strings. --- .../java/com/beust/jcommander/MethodSetterTest.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/MethodSetterTest.java b/src/test/java/com/beust/jcommander/MethodSetterTest.java index 8790e4c..8f6320b 100644 --- a/src/test/java/com/beust/jcommander/MethodSetterTest.java +++ b/src/test/java/com/beust/jcommander/MethodSetterTest.java @@ -59,8 +59,27 @@ public class MethodSetterTest { Assert.assertTrue(passed, "Should have thrown an exception"); } + public void getterReturningNonString() { + class Arg { + private Integer port; + + @Parameter(names = "--port") + public void setPort(String port) { + this.port = Integer.parseInt(port); + } + + public Integer getPort() { + return port; + } + } + Arg arg = new Arg(); + new JCommander(arg, new String[] { "--port", "42" }); + + Assert.assertEquals(arg.port, new Integer(42)); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new MethodSetterTest().arityStringsSetter(); + new MethodSetterTest().getterReturningNonString(); } } -- cgit v1.2.3 From f4ed64c254096dd10305a92c4d96656048f35b15 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Jul 2012 14:07:14 -0700 Subject: If we have a setter but no getter, try to find a field to calculate the default value. --- src/main/java/com/beust/jcommander/Parameterized.java | 17 ++++++++++++++++- .../java/com/beust/jcommander/MethodSetterTest.java | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/Parameterized.java b/src/main/java/com/beust/jcommander/Parameterized.java index 14ce975..ff8753b 100644 --- a/src/main/java/com/beust/jcommander/Parameterized.java +++ b/src/main/java/com/beust/jcommander/Parameterized.java @@ -117,7 +117,22 @@ public class Parameterized { } catch (SecurityException e) { throw new ParameterException(e); } catch (NoSuchMethodException e) { - return null; + // Try to find a field + String name = m_method.getName(); + String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4); + Object result = null; + try { + Field field = m_method.getDeclaringClass().getDeclaredField(fieldName); + if (field != null) { + field.setAccessible(true); + result = field.get(object); + } + } catch(NoSuchFieldException ex) { + // ignore + } catch(IllegalAccessException ex) { + // ignore + } + return result; } catch (IllegalArgumentException e) { throw new ParameterException(e); } catch (IllegalAccessException e) { diff --git a/src/test/java/com/beust/jcommander/MethodSetterTest.java b/src/test/java/com/beust/jcommander/MethodSetterTest.java index 8f6320b..f995ad6 100644 --- a/src/test/java/com/beust/jcommander/MethodSetterTest.java +++ b/src/test/java/com/beust/jcommander/MethodSetterTest.java @@ -78,8 +78,23 @@ public class MethodSetterTest { Assert.assertEquals(arg.port, new Integer(42)); } + public void noGetterButWithField() { + class Arg { + private Integer port = 43; + + @Parameter(names = "--port") + public void setPort(String port) { + this.port = Integer.parseInt(port); + } + } + Arg arg = new Arg(); + JCommander jc = new JCommander(arg, new String[] { "--port", "42" }); + ParameterDescription pd = jc.getParameters().get(0); + Assert.assertEquals(pd.getDefault(), 43); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new MethodSetterTest().getterReturningNonString(); + new MethodSetterTest().noGetterButWithField(); } } -- cgit v1.2.3 From dfb5854988a7ad9cf54ddf101c7fbbff1df3c205 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Jul 2012 15:21:37 -0700 Subject: Added JCommander#setVerbose. --- src/main/java/com/beust/jcommander/JCommander.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 63b935c..71bac67 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -791,6 +791,8 @@ public class JCommander { } private final IVariableArity DEFAULT_VARIABLE_ARITY = new DefaultVariableArity(); + private int m_verbose = 0; + /** * @return the number of options that were processed. */ @@ -1152,7 +1154,7 @@ public class JCommander { } private void p(String string) { - if (System.getProperty(JCommander.DEBUG_PROPERTY) != null) { + if (m_verbose > 0 || System.getProperty(JCommander.DEBUG_PROPERTY) != null) { getConsole().println("[JCommander] " + string); } } @@ -1493,5 +1495,9 @@ public class JCommander { } } + + public void setVerbose(int verbose) { + m_verbose = verbose; + } } -- cgit v1.2.3 From e97a09f79f6947d4499de3ae54eebc4299a94641 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 7 Jul 2012 15:41:12 -0700 Subject: Misc clean up. --- pom.xml | 1 + src/main/java/com/beust/jcommander/JCommander.java | 23 +++++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index a5e2b54..0c72fca 100644 --- a/pom.xml +++ b/pom.xml @@ -223,6 +223,7 @@ maven-gpg-plugin + 1.4 sign-artifacts diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 71bac67..cc80420 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -27,6 +27,7 @@ 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; import java.io.BufferedReader; import java.io.FileReader; @@ -48,8 +49,6 @@ import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; - - /** * 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 @@ -60,7 +59,7 @@ import java.util.ResourceBundle; * or an instance of Iterable. In the case of an array or Iterable, JCommander will collect * the \@Parameter annotations from all the objects passed in parameter. * - * @author cbeust + * @author Cedric Beust */ public class JCommander { public static final String DEBUG_PROPERTY = "jcommander.debug"; @@ -104,7 +103,7 @@ public class JCommander { private Map m_requiredFields = Maps.newHashMap(); /** - * A map of all the parameterized fields/methods/ + * A map of all the parameterized fields/methods. */ private Map m_fields = Maps.newHashMap(); @@ -119,6 +118,7 @@ public class JCommander { * List of commands and their instance. */ private Map m_commands = Maps.newLinkedHashMap(); + /** * Alias database for reverse lookup */ @@ -178,7 +178,7 @@ public class JCommander { * @param object The arg object expected to contain {@link Parameter} annotations. * @param bundle The bundle to use for the descriptions. Can be null. */ - public JCommander(Object object, ResourceBundle bundle) { + public JCommander(Object object, @Nullable ResourceBundle bundle) { addObject(object); setDescriptionsBundle(bundle); } @@ -1188,11 +1188,11 @@ public class JCommander { } /** - * @param field The field * @param type The type of the actual parameter * @param value The value to convert */ - public Object convertValue(Parameterized parameterized, Class type, String value) { + public Object convertValue(Parameterized parameterized, Class type, + String value) { Parameter annotation = parameterized.getParameter(); // Do nothing if it's a @DynamicParameter @@ -1313,9 +1313,11 @@ public class JCommander { IStringConverter result = stringCtor != null ? stringCtor.newInstance(optionName) - : ctor.newInstance(); + : (ctor != null + ? ctor.newInstance() + : null); - return result; + return result; } /** @@ -1430,6 +1432,9 @@ public class JCommander { return jc; } + /** + * Encapsulation of either a main application or an individual command. + */ private static final class ProgramName { private final String m_name; private final List m_aliases; -- cgit v1.2.3 From 75d579a2fc672582cfadefc360fe18b05caa7e21 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 8 Jul 2012 10:37:23 -0700 Subject: Forgot Nullable.java --- src/main/java/com/beust/jcommander/internal/Nullable.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/com/beust/jcommander/internal/Nullable.java diff --git a/src/main/java/com/beust/jcommander/internal/Nullable.java b/src/main/java/com/beust/jcommander/internal/Nullable.java new file mode 100644 index 0000000..b988373 --- /dev/null +++ b/src/main/java/com/beust/jcommander/internal/Nullable.java @@ -0,0 +1,12 @@ +package com.beust.jcommander.internal; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.PARAMETER; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@Target({FIELD, PARAMETER}) +public @interface Nullable { +} -- cgit v1.2.3 From 8767867f2bafe965e2892ba333574a8c6c9a2f05 Mon Sep 17 00:00:00 2001 From: Joe Littlejohn Date: Sat, 14 Jul 2012 01:39:19 +0200 Subject: Update readme to add syntax highlighting --- README.markdown | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/README.markdown b/README.markdown index ade1ab9..bf479db 100644 --- a/README.markdown +++ b/README.markdown @@ -5,26 +5,30 @@ This is an annotation based parameter parsing framework for Java. Here is a quick example: - public class JCommanderTest { - @Parameter - public List parameters = Lists.newArrayList(); - - @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") - public Integer verbose = 1; - - @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") - public String groups; - - @Parameter(names = "-debug", description = "Debug mode") - public boolean debug = false; - } +```java +public class JCommanderTest { + @Parameter + public List parameters = Lists.newArrayList(); + + @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") + public Integer verbose = 1; + + @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") + public String groups; + + @Parameter(names = "-debug", description = "Debug mode") + public boolean debug = false; +} +``` and how you use it: - JCommanderTest jct = new JCommanderTest(); - String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; - new JCommander(jct, argv); +```java +CommanderTest jct = new JCommanderTest(); +String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; +new JCommander(jct, argv); - Assert.assertEquals(jct.verbose.intValue(), 2); +Assert.assertEquals(jct.verbose.intValue(), 2); +``` The full doc is available at http://beust.com/jcommander -- cgit v1.2.3 From 94e08e73342f858518b14a70624c38479c0365d3 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 17 Jul 2012 22:25:26 -0700 Subject: Fixed: Parameters with a single double quote were not working properly --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 2 +- .../java/com/beust/jcommander/JCommanderTest.java | 42 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 72e483f..d0540d8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: Parameters with a single double quote were not working properly 1.27 1012/08/05 diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index cc80420..9a751ba 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -497,7 +497,7 @@ public class JCommander { */ private static String trim(String string) { String result = string.trim(); - if (result.startsWith("\"") && result.endsWith("\"")) { + if (result.startsWith("\"") && result.endsWith("\"") && result.length() > 1) { result = result.substring(1, result.length() - 1); } return result; diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 428fdfe..0b5a4ad 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -805,6 +805,48 @@ public class JCommanderTest { Assert.assertTrue(arg.help); } + public void helpTest() { + class Arg { + @Parameter(names = { "?", "-help", "--help" }, description = "Shows help", help = true) + private boolean help = false; + } + Arg arg = new Arg(); + JCommander jc = new JCommander(arg); + jc.parse(new String[] { "-help" }); + System.out.println(arg.help); + } + + @Test(enabled = false, description = "Should only be enable once multiple parameters are allowed") + public void duplicateParameterNames() { + class ArgBase { + @Parameter(names = { "-host" }) + protected String host; + } + + class Arg1 extends ArgBase {} + Arg1 arg1 = new Arg1(); + + class Arg2 extends ArgBase {} + Arg2 arg2 = new Arg2(); + + JCommander jc = new JCommander(new Object[] { arg1, arg2}); + jc.parse(new String[] { "-host", "foo" }); + Assert.assertEquals(arg1.host, "foo"); + Assert.assertEquals(arg2.host, "foo"); + } + + public void parameterWithOneDoubleQuote() { + @Parameters(separators = "=") + class Arg { + + @Parameter(names = { "-p", "--param" }) + private String param; + } + + JCommander jc = new JCommander(new MyClass()); + jc.parse("-p=\""); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { new JCommanderTest().verifyHelp(); -- cgit v1.2.3 From f65b16085ead5063dbb7c9a6f366ebedb2227f68 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 17 Jul 2012 22:44:09 -0700 Subject: Fixed: Bugs with the PositiveInteger validator --- CHANGELOG | 1 + .../com/beust/jcommander/ParameterDescription.java | 2 + .../com/beust/jcommander/PositiveIntegerTest.java | 65 ++++++++++++++++++++++ src/test/resources/testng-single.xml | 13 +++++ src/test/resources/testng.xml | 1 + 5 files changed, 82 insertions(+) create mode 100644 src/test/java/com/beust/jcommander/PositiveIntegerTest.java create mode 100644 src/test/resources/testng-single.xml diff --git a/CHANGELOG b/CHANGELOG index d0540d8..5d62313 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: Bugs with the PositiveInteger validator Fixed: Parameters with a single double quote were not working properly 1.27 diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 6480ea7..d886e30 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -302,6 +302,8 @@ public class ParameterDescription { throw new ParameterException("Can't instantiate validator:" + e); } catch (IllegalAccessException e) { throw new ParameterException("Can't instantiate validator:" + e); + } catch(Exception ex) { + throw new ParameterException(ex); } } diff --git a/src/test/java/com/beust/jcommander/PositiveIntegerTest.java b/src/test/java/com/beust/jcommander/PositiveIntegerTest.java new file mode 100644 index 0000000..ec7d273 --- /dev/null +++ b/src/test/java/com/beust/jcommander/PositiveIntegerTest.java @@ -0,0 +1,65 @@ +package com.beust.jcommander; + +import com.beust.jcommander.validators.PositiveInteger; + +import org.testng.annotations.Test; + +public class PositiveIntegerTest { + + @Test + public void validateTest() { + class Arg { + @Parameter(names = { "-p", "--port" }, description = "Shows help", validateWith = PositiveInteger.class) + private int port = 0; + } + Arg arg = new Arg(); + JCommander jc = new JCommander(arg); + jc.parse(new String[] { "-p", "8080" }); + + } + + @Test(expectedExceptions = ParameterException.class) + public void validateTest2() { + class Arg { + @Parameter(names = { "-p", "--port" }, description = "Shows help", validateWith = PositiveInteger.class) + private int port = 0; + } + Arg arg = new Arg(); + JCommander jc = new JCommander(arg); + jc.parse(new String[] { "-p", "" }); + } + + @Test(expectedExceptions = ParameterException.class) + public void validateTest3() { + class Arg { + @Parameter(names = { "-p", "--port" }, description = "Shows help", validateWith = PositiveInteger.class) + private int port = 0; + } + Arg arg = new Arg(); + JCommander jc = new JCommander(arg); + jc.parse(new String[] { "-p", "-1" }); + } + + @Test(expectedExceptions = ParameterException.class) + public void validateTest4() { + class Arg { + @Parameter(names = { "-p", "--port" }, description = "Port Number", validateWith = PositiveInteger.class) + private int port = 0; + } + Arg arg = new Arg(); + JCommander jc = new JCommander(arg); + jc.parse(new String[] { "-p", "abc" }); + } + + @Test(expectedExceptions = ParameterException.class) + public void validateTest5() { + class Arg { + @Parameter(names = { "-p", "--port" }, description = "Port Number", validateWith = PositiveInteger.class) + private int port = 0; + } + + Arg arg = new Arg(); + JCommander jc = new JCommander(arg); + jc.parse(new String[] { "--port", " " }); + } +} \ No newline at end of file diff --git a/src/test/resources/testng-single.xml b/src/test/resources/testng-single.xml new file mode 100644 index 0000000..a50651a --- /dev/null +++ b/src/test/resources/testng-single.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index c9639d4..7dc97c9 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -14,6 +14,7 @@ + -- cgit v1.2.3 From e79760c8a3806df3369adcbaa4dbaeceb93f9a65 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 25 Jul 2012 14:53:22 -0700 Subject: Fixed: Empty string defaults now displayed as "" in the usage --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 7 +++++-- src/test/java/com/beust/jcommander/JCommanderTest.java | 13 ++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5d62313..a7619ca 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: Empty string defaults now displayed as "" in the usage Fixed: Bugs with the PositiveInteger validator Fixed: Parameters with a single double quote were not working properly diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 9a751ba..bd9bad8 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1071,9 +1071,12 @@ public class JCommander { + "key" + parameter.getAssignment() + "value"); } - if (def != null && ! "".equals(def)) { + if (def != null) { + String displayedDef = Strings.isStringEmpty(def.toString()) + ? "" + : def.toString(); out.append("\n" + spaces(indentCount + 1)) - .append("Default: " + (parameter.password()?"********":def)); + .append("Default: " + (parameter.password()?"********" : displayedDef)); } out.append("\n"); } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 0b5a4ad..c516e0f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -847,9 +847,20 @@ public class JCommanderTest { jc.parse("-p=\""); } + public void emptyStringAsDefault() { + class Arg { + @Parameter(names = "-x") + String s = ""; + } + Arg a = new Arg(); + StringBuilder sb = new StringBuilder(); + new JCommander(a).usage(sb); + Assert.assertTrue(sb.toString().contains("Default: ")); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().verifyHelp(); + new JCommanderTest().emptyStringAsDefault(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 7c9f6fec0666ce491801f475f0dcdd0044fe7744 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Jul 2012 22:23:22 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.28 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0c72fca..542d467 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.28-SNAPSHOT + 1.28 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 7bd25256af79b8f79e78ce9259ba80b7d2dd0d4a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Jul 2012 22:23:30 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 542d467..bed4987 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.28 + 1.29-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 1225b8c4595305a86155a32e55d766be769d509f Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Jul 2012 22:26:05 -0700 Subject: Forgot one class. --- src/test/java/com/beust/jcommander/MyClass.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/java/com/beust/jcommander/MyClass.java diff --git a/src/test/java/com/beust/jcommander/MyClass.java b/src/test/java/com/beust/jcommander/MyClass.java new file mode 100644 index 0000000..3bf46b5 --- /dev/null +++ b/src/test/java/com/beust/jcommander/MyClass.java @@ -0,0 +1,14 @@ +package com.beust.jcommander; + +@Parameters(separators = "=") +public class MyClass { + + @Parameter(names = { "-p", "--param" }) + private String param; + + public static void main(String[] args) { + JCommander jCommander = new JCommander(new MyClass()); + jCommander.parse("-p=\""); + } + +} \ No newline at end of file -- cgit v1.2.3 From 9b0e40293867dbba249018cb3c882fe880bbd93e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Jul 2012 22:26:31 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.29 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bed4987..8b73bda 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.29-SNAPSHOT + 1.29 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From d767682421d2ee1eef99f87b91bf21b145398587 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sat, 28 Jul 2012 22:26:49 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b73bda..35e5a4d 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.29 + 1.30-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From e0de481742a2d1ef7454c9bf462753bcb756507e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 30 Jul 2012 22:09:42 -0700 Subject: Removed the duplicate spaces() method. --- src/main/java/com/beust/jcommander/JCommander.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index bd9bad8..bc0e658 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1066,7 +1066,7 @@ public class JCommander { wrapDescription(out, indentCount, pd.getDescription()); Object def = pd.getDefault(); if (pd.isDynamicParameter()) { - out.append("\n" + spaces(indentCount + 1)) + out.append("\n" + s(indentCount + 1)) .append("Syntax: " + parameter.names()[0] + "key" + parameter.getAssignment() + "value"); @@ -1075,7 +1075,7 @@ public class JCommander { String displayedDef = Strings.isStringEmpty(def.toString()) ? "" : def.toString(); - out.append("\n" + spaces(indentCount + 1)) + out.append("\n" + s(indentCount + 1)) .append("Default: " + (parameter.password()?"********" : displayedDef)); } out.append("\n"); @@ -1127,19 +1127,13 @@ public class JCommander { out.append(" ").append(word); current += word.length() + 1; } else { - out.append("\n").append(spaces(indent + 1)).append(word); + out.append("\n").append(s(indent + 1)).append(word); current = indent; } i++; } } - private String spaces(int indent) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < indent; i++) sb.append(" "); - return sb.toString(); - } - /** * @return a Collection of all the \@Parameter annotations found on the * target class. This can be used to display the usage() in a different -- cgit v1.2.3 From 0b2c479e2db4ba4ed88952e801f99e594b84a948 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 30 Jul 2012 22:09:57 -0700 Subject: Reformatting. --- src/test/java/com/beust/jcommander/args/ArgsEnum.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/args/ArgsEnum.java b/src/test/java/com/beust/jcommander/args/ArgsEnum.java index 6661e37..16643cd 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsEnum.java +++ b/src/test/java/com/beust/jcommander/args/ArgsEnum.java @@ -41,7 +41,8 @@ public class ArgsEnum { String[] argv = { "-choice", "ONE"}; JCommander jc = new JCommander(args, argv); jc.usage(); - Assert.assertEquals(jc.getParameters().get(0).getDescription(), "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); + Assert.assertEquals(jc.getParameters().get(0).getDescription(), + "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); } } -- cgit v1.2.3 From 1322b1a0011d7ac5c15f73a062a0e7b4b0879840 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 30 Jul 2012 22:10:09 -0700 Subject: Comment out println. --- src/test/java/com/beust/jcommander/JCommanderTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index c516e0f..3c7eba5 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -566,7 +566,8 @@ public class JCommanderTest { Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE); - Assert.assertEquals(jc.getParameters().get(0).getDescription(), "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); + Assert.assertEquals(jc.getParameters().get(0).getDescription(), + "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); } @@ -813,7 +814,7 @@ public class JCommanderTest { Arg arg = new Arg(); JCommander jc = new JCommander(arg); jc.parse(new String[] { "-help" }); - System.out.println(arg.help); +// System.out.println("helpTest:" + arg.help); } @Test(enabled = false, description = "Should only be enable once multiple parameters are allowed") @@ -860,7 +861,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().emptyStringAsDefault(); + new JCommanderTest().parameterWithOneDoubleQuote(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 5f260731d31e274e89cf01ba71b26f0423192baf Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 30 Jul 2012 22:23:27 -0700 Subject: Description of commands is now displayed on the next line and indented. Makes long descriptions easier to read. --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a7619ca..86cd01c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Fixed: The description of commands is now displayed on the next line and indented. Fixed: Empty string defaults now displayed as "" in the usage Fixed: Bugs with the PositiveInteger validator Fixed: Parameters with a single double quote were not working properly diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index bc0e658..8c8072e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1053,16 +1053,16 @@ public class JCommander { // // Display all the names and descriptions // + int descriptionIndent = 6; if (sorted.size() > 0) out.append(indent).append("\n").append(indent).append(" Options:\n"); for (ParameterDescription pd : sorted) { - int l = pd.getNames().length(); - int spaceCount = longestName - l; - int start = out.length(); WrappedParameter parameter = pd.getParameter(); out.append(indent).append(" " + (parameter.required() ? "* " : " ") - + pd.getNames() + s(spaceCount)); - int indentCount = out.length() - start; + + pd.getNames() + + "\n" + + indent + s(descriptionIndent)); + int indentCount = indent.length() + descriptionIndent; wrapDescription(out, indentCount, pd.getDescription()); Object def = pd.getDefault(); if (pd.isDynamicParameter()) { -- cgit v1.2.3 From a8f4de2555e41fad6cab4fbcff4e91cc32350db7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 Jul 2012 11:24:27 -0700 Subject: Added: JCommander#setCaseSensitiveOptions (default: true) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 51 ++++++++++++++++++++-- .../java/com/beust/jcommander/JCommanderTest.java | 27 +++++++++++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 86cd01c..1482f1a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: JCommander#setCaseSensitiveOptions (default: true) Fixed: The description of commands is now displayed on the next line and indented. Fixed: Empty string defaults now displayed as "" in the usage Fixed: Bugs with the PositiveInteger validator diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 8c8072e..69a4a3e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -682,7 +682,7 @@ public class JCommander { // // Option // - ParameterDescription pd = m_descriptions.get(a); + ParameterDescription pd = findParameterDescription(a); if (pd != null) { if (pd.getParameter().password()) { @@ -793,6 +793,9 @@ public class JCommander { private int m_verbose = 0; + private boolean m_caseSensitiveOptions = true; + private boolean m_caseSensitiveCommands = true; + /** * @return the number of options that were processed. */ @@ -1412,15 +1415,49 @@ public class JCommander { return m_objects; } + private V findCaseSensitiveMap(Map map, String name) { + if (m_caseSensitiveOptions) { + return map.get(name); + } else { + for (String c : map.keySet()) { + if (c.equalsIgnoreCase(name)) { + return map.get(c); + } + } + } + return null; + } + + private ParameterDescription findParameterDescription(String arg) { + return findCaseSensitiveMap(m_descriptions, arg); + } + + private JCommander findCommand(ProgramName name) { + if (! m_caseSensitiveCommands) { + return m_commands.get(name); + } else { + for (ProgramName c : m_commands.keySet()) { + if (c.getName().equalsIgnoreCase(name.getName())) { + return m_commands.get(c); + } + } + } + return null; + } + + private ProgramName findProgramName(String name) { + return findCaseSensitiveMap(aliasMap, name); + } + /* * Reverse lookup JCommand object by command's name or its alias */ private JCommander findCommandByAlias(String commandOrAlias) { - ProgramName progName = aliasMap.get(commandOrAlias); + ProgramName progName = findProgramName(commandOrAlias); if (progName == null) { return null; } - JCommander jc = m_commands.get(progName); + JCommander jc = findCommand(progName); if (jc == null) { throw new IllegalStateException( "There appears to be inconsistency in the internal command database. " + @@ -1501,5 +1538,13 @@ public class JCommander { public void setVerbose(int verbose) { m_verbose = verbose; } + + public void setCaseSensitiveOptions(boolean b) { + m_caseSensitiveOptions = b; + } + +// public void setCaseSensitiveCommands(boolean b) { +// m_caseSensitiveCommands = b; +// } } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 3c7eba5..c380721 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -859,9 +859,34 @@ public class JCommanderTest { Assert.assertTrue(sb.toString().contains("Default: ")); } + public void caseInsensitiveOption() { + class Arg { + + @Parameter(names = { "-p", "--param" }) + private String param; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setCaseSensitiveOptions(false); + jc.parse(new String[] { "--PARAM", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + public void caseInsensitiveCommand() { + BaseArgs a = new BaseArgs(); + ConfigureArgs conf = new ConfigureArgs(); + JCommander jc = new JCommander(a); + jc.addCommand(conf); + jc.setCaseSensitiveOptions(false); +// jc.setCaseSensitiveCommands(false); + jc.parse("--CONFIGURE"); + String command = jc.getParsedCommand(); + Assert.assertEquals(command, "--configure"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().parameterWithOneDoubleQuote(); + new JCommanderTest().caseInsensitiveCommand(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 3d5343bd6a916feca9bfcfdf5fac9450b2f5fe1c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 Jul 2012 13:49:28 -0700 Subject: Doc update. --- doc/index.html | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/index.html b/doc/index.html index aabfa53..b61ad0c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -100,6 +100,22 @@ private boolean debug = false; Such a parameter does not require any additional parameter on the command line and if it's detected during parsing, the corresponding field will be set to true. +

            + + If you want to define a boolean parameter that's true by default, you can declare it as having an arity of 1. Users will then have to specify the value they want explicitly: + +

            +    @Parameter(names = "-debug", description = "Debug mode", arity = 1)
            +    private boolean debug = true;
            +  
            + + Invoke with either of: + +
            +    program -debug true
            +    program -debug false
            +  
            +

            String, Integer, Long

            When a Parameter annotation is found on a field of type String, Integer, int, Long or long, JCommander will parse the following parameter and it will attempt to cast it to the right type: -- cgit v1.2.3 From 14bcad3aea8700c3cd3fc9f5b380355b074c94c7 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 31 Jul 2012 13:50:53 -0700 Subject: Doc update. --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index b61ad0c..e8522e1 100644 --- a/doc/index.html +++ b/doc/index.html @@ -39,7 +39,7 @@ - Last updated: July 5th, 2012 + Last updated: July 31st, 2012 Cédric Beust -- cgit v1.2.3 From 2c092c0c1966a21f1b585eac22b4e36045a43549 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 1 Aug 2012 08:50:32 -0700 Subject: Added: JCommander#allowAbbreviatedOptions (default: false) --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 43 ++++++++++++++-- .../java/com/beust/jcommander/JCommanderTest.java | 58 +++++++++++++++++++++- 3 files changed, 97 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1482f1a..fdc3a1c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ Current +Added: JCommander#allowAbbreviatedOptions (default: false) Added: JCommander#setCaseSensitiveOptions (default: true) Fixed: The description of commands is now displayed on the next line and indented. Fixed: Empty string defaults now displayed as "" in the usage diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 69a4a3e..6060dfc 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -795,6 +795,7 @@ public class JCommander { private boolean m_caseSensitiveOptions = true; private boolean m_caseSensitiveCommands = true; + private boolean m_allowAbbreviatedOptions = false; /** * @return the number of options that were processed. @@ -1415,13 +1416,43 @@ public class JCommander { return m_objects; } + private V findAbbreviatedOption(Map map, String name, boolean caseSensitive) { + Map results = Maps.newHashMap(); + for (String c : map.keySet()) { + boolean match = (caseSensitive && c.startsWith(name)) + || ((! caseSensitive) && c.toLowerCase().startsWith(name.toLowerCase())); + if (match) { + results.put(c, map.get(c)); + } + } + V result; + if (results.size() > 1) { + throw new ParameterException("Ambiguous option: " + name + + " matches " + results.keySet()); + } else if (results.size() == 1) { + result = results.values().iterator().next(); + } else { + result = null; + } + + return result; + } + private V findCaseSensitiveMap(Map map, String name) { if (m_caseSensitiveOptions) { - return map.get(name); + if (m_allowAbbreviatedOptions) { + return findAbbreviatedOption(map, name, m_caseSensitiveOptions); + } else { + return map.get(name); + } } else { - for (String c : map.keySet()) { - if (c.equalsIgnoreCase(name)) { - return map.get(c); + if (m_allowAbbreviatedOptions) { + return findAbbreviatedOption(map, name, m_caseSensitiveOptions); + } else { + for (String c : map.keySet()) { + if (c.equalsIgnoreCase(name)) { + return map.get(c); + } } } } @@ -1543,6 +1574,10 @@ public class JCommander { m_caseSensitiveOptions = b; } + public void setAllowAbbreviatedOptions(boolean b) { + m_allowAbbreviatedOptions = b; + } + // public void setCaseSensitiveCommands(boolean b) { // m_caseSensitiveCommands = b; // } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index c380721..fa79d1f 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -884,9 +884,65 @@ public class JCommanderTest { Assert.assertEquals(command, "--configure"); } + public void abbreviatedOptions() { + class Arg { + @Parameter(names = { "-p", "--param" }) + private String param; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--par", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + public void abbreviatedOptionsCaseInsensitive() { + class Arg { + @Parameter(names = { "-p", "--param" }) + private String param; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setCaseSensitiveOptions(false); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--PAR", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + @Test(expectedExceptions = ParameterException.class) + public void ambiguousAbbreviatedOptions() { + class Arg { + @Parameter(names = { "--param" }) + private String param; + @Parameter(names = { "--parb" }) + private String parb; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--par", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + @Test(expectedExceptions = ParameterException.class) + public void ambiguousAbbreviatedOptionsCaseInsensitive() { + class Arg { + @Parameter(names = { "--param" }) + private String param; + @Parameter(names = { "--parb" }) + private String parb; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setCaseSensitiveOptions(false); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--PAR", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().caseInsensitiveCommand(); + new JCommanderTest().ambiguousAbbreviatedOptionsCaseInsensitive(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 18acf239feebe9f079a4d31e1852556b7cd2fd4c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 1 Aug 2012 09:23:01 -0700 Subject: Moved the finder tests in their own class. --- src/main/java/com/beust/jcommander/JCommander.java | 3 +- src/test/java/com/beust/jcommander/FinderTest.java | 97 ++++++++++++++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 83 +----------------- src/test/resources/testng-single.xml | 2 +- src/test/resources/testng.xml | 1 + 5 files changed, 101 insertions(+), 85 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/FinderTest.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 6060dfc..fccbb9e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -794,7 +794,6 @@ public class JCommander { private int m_verbose = 0; private boolean m_caseSensitiveOptions = true; - private boolean m_caseSensitiveCommands = true; private boolean m_allowAbbreviatedOptions = false; /** @@ -1464,7 +1463,7 @@ public class JCommander { } private JCommander findCommand(ProgramName name) { - if (! m_caseSensitiveCommands) { + if (! m_caseSensitiveOptions) { return m_commands.get(name); } else { for (ProgramName c : m_commands.keySet()) { diff --git a/src/test/java/com/beust/jcommander/FinderTest.java b/src/test/java/com/beust/jcommander/FinderTest.java new file mode 100644 index 0000000..94bf812 --- /dev/null +++ b/src/test/java/com/beust/jcommander/FinderTest.java @@ -0,0 +1,97 @@ +package com.beust.jcommander; + +import com.beust.jcommander.JCommanderTest.BaseArgs; +import com.beust.jcommander.JCommanderTest.ConfigureArgs; + +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test +public class FinderTest { + public void caseInsensitiveOption() { + class Arg { + + @Parameter(names = { "-p", "--param" }) + private String param; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setCaseSensitiveOptions(false); + jc.parse(new String[] { "--PARAM", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + public void caseInsensitiveCommand() { + BaseArgs a = new BaseArgs(); + ConfigureArgs conf = new ConfigureArgs(); + JCommander jc = new JCommander(a); + jc.addCommand(conf); + jc.setCaseSensitiveOptions(false); +// jc.setCaseSensitiveCommands(false); + jc.parse("--CONFIGURE"); + String command = jc.getParsedCommand(); + Assert.assertEquals(command, "--configure"); + } + + public void abbreviatedOptions() { + class Arg { + @Parameter(names = { "-p", "--param" }) + private String param; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--par", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + public void abbreviatedOptionsCaseInsensitive() { + class Arg { + @Parameter(names = { "-p", "--param" }) + private String param; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setCaseSensitiveOptions(false); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--PAR", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + @Test(expectedExceptions = ParameterException.class) + public void ambiguousAbbreviatedOptions() { + class Arg { + @Parameter(names = { "--param" }) + private String param; + @Parameter(names = { "--parb" }) + private String parb; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--par", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + @Test(expectedExceptions = ParameterException.class) + public void ambiguousAbbreviatedOptionsCaseInsensitive() { + class Arg { + @Parameter(names = { "--param" }) + private String param; + @Parameter(names = { "--parb" }) + private String parb; + } + Arg a = new Arg(); + JCommander jc = new JCommander(a); + jc.setCaseSensitiveOptions(false); + jc.setAllowAbbreviatedOptions(true); + jc.parse(new String[] { "--PAR", "foo" }); + Assert.assertEquals(a.param, "foo"); + } + + @Test(enabled = false) + public static void main(String[] args) throws Exception { + new FinderTest().ambiguousAbbreviatedOptionsCaseInsensitive(); + } + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index fa79d1f..741f16a 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -859,90 +859,9 @@ public class JCommanderTest { Assert.assertTrue(sb.toString().contains("Default: ")); } - public void caseInsensitiveOption() { - class Arg { - - @Parameter(names = { "-p", "--param" }) - private String param; - } - Arg a = new Arg(); - JCommander jc = new JCommander(a); - jc.setCaseSensitiveOptions(false); - jc.parse(new String[] { "--PARAM", "foo" }); - Assert.assertEquals(a.param, "foo"); - } - - public void caseInsensitiveCommand() { - BaseArgs a = new BaseArgs(); - ConfigureArgs conf = new ConfigureArgs(); - JCommander jc = new JCommander(a); - jc.addCommand(conf); - jc.setCaseSensitiveOptions(false); -// jc.setCaseSensitiveCommands(false); - jc.parse("--CONFIGURE"); - String command = jc.getParsedCommand(); - Assert.assertEquals(command, "--configure"); - } - - public void abbreviatedOptions() { - class Arg { - @Parameter(names = { "-p", "--param" }) - private String param; - } - Arg a = new Arg(); - JCommander jc = new JCommander(a); - jc.setAllowAbbreviatedOptions(true); - jc.parse(new String[] { "--par", "foo" }); - Assert.assertEquals(a.param, "foo"); - } - - public void abbreviatedOptionsCaseInsensitive() { - class Arg { - @Parameter(names = { "-p", "--param" }) - private String param; - } - Arg a = new Arg(); - JCommander jc = new JCommander(a); - jc.setCaseSensitiveOptions(false); - jc.setAllowAbbreviatedOptions(true); - jc.parse(new String[] { "--PAR", "foo" }); - Assert.assertEquals(a.param, "foo"); - } - - @Test(expectedExceptions = ParameterException.class) - public void ambiguousAbbreviatedOptions() { - class Arg { - @Parameter(names = { "--param" }) - private String param; - @Parameter(names = { "--parb" }) - private String parb; - } - Arg a = new Arg(); - JCommander jc = new JCommander(a); - jc.setAllowAbbreviatedOptions(true); - jc.parse(new String[] { "--par", "foo" }); - Assert.assertEquals(a.param, "foo"); - } - - @Test(expectedExceptions = ParameterException.class) - public void ambiguousAbbreviatedOptionsCaseInsensitive() { - class Arg { - @Parameter(names = { "--param" }) - private String param; - @Parameter(names = { "--parb" }) - private String parb; - } - Arg a = new Arg(); - JCommander jc = new JCommander(a); - jc.setCaseSensitiveOptions(false); - jc.setAllowAbbreviatedOptions(true); - jc.parse(new String[] { "--PAR", "foo" }); - Assert.assertEquals(a.param, "foo"); - } - @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().ambiguousAbbreviatedOptionsCaseInsensitive(); +// new JCommanderTest().ambiguousAbbreviatedOptionsCaseInsensitive(); // class A { // @Parameter(names = "-short", required = true) // List parameters; diff --git a/src/test/resources/testng-single.xml b/src/test/resources/testng-single.xml index a50651a..c3cdd46 100644 --- a/src/test/resources/testng-single.xml +++ b/src/test/resources/testng-single.xml @@ -4,7 +4,7 @@ - + diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 7dc97c9..c3592e0 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -15,6 +15,7 @@ + -- cgit v1.2.3 From dbccffb3047aa721e3c09ecda4e6b12a00152dd1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 1 Aug 2012 10:45:27 -0700 Subject: Refactoring: introducing FuzzyMap and IKey. --- src/main/java/com/beust/jcommander/FuzzyMap.java | 61 ++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 94 +++++++--------------- src/main/java/com/beust/jcommander/StringKey.java | 48 +++++++++++ .../java/com/beust/jcommander/JCommanderTest.java | 2 +- src/test/resources/testng-single.xml | 8 +- 5 files changed, 146 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/FuzzyMap.java create mode 100644 src/main/java/com/beust/jcommander/StringKey.java diff --git a/src/main/java/com/beust/jcommander/FuzzyMap.java b/src/main/java/com/beust/jcommander/FuzzyMap.java new file mode 100644 index 0000000..5f3939b --- /dev/null +++ b/src/main/java/com/beust/jcommander/FuzzyMap.java @@ -0,0 +1,61 @@ +package com.beust.jcommander; + +import com.beust.jcommander.internal.Maps; + +import java.util.Map; + +/** + * Helper class to perform fuzzy key look ups: looking up case insensitive or + * abbreviated keys. + */ +public class FuzzyMap { + interface IKey { + String getName(); + } + + public static V findInMap(Map map, IKey name, + boolean caseSensitive, boolean allowAbbreviations) { + if (allowAbbreviations) { + return findAbbreviatedValue(map, name, caseSensitive); + } else { + if (caseSensitive) { + return map.get(name); + } else { + for (IKey c : map.keySet()) { + if (c.getName().equalsIgnoreCase(name.getName())) { + return map.get(c); + } + } + } + } + return null; + } + + private static V findAbbreviatedValue(Map map, IKey name, + boolean caseSensitive) { + String string = name.getName(); + Map results = Maps.newHashMap(); + for (IKey c : map.keySet()) { + String n = c.getName(); + boolean match = (caseSensitive && n.startsWith(string)) + || ((! caseSensitive) && n.toLowerCase().startsWith(string.toLowerCase())); + if (match) { + results.put(n, map.get(c)); + } + } + + V result; + if (results.size() > 1) { + throw new ParameterException("Ambiguous option: " + name + + " matches " + results.keySet()); + } else if (results.size() == 1) { + result = results.values().iterator().next(); + } else { + result = null; + } + + return result; + } + + +} diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index fccbb9e..bfda67f 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -18,6 +18,7 @@ package com.beust.jcommander; +import com.beust.jcommander.FuzzyMap.IKey; import com.beust.jcommander.converters.IParameterSplitter; import com.beust.jcommander.converters.NoConverter; import com.beust.jcommander.converters.StringConverter; @@ -67,7 +68,7 @@ public class JCommander { /** * A map to look up parameter description per option name. */ - private Map m_descriptions; + private Map m_descriptions; /** * The objects that contain fields annotated with @Parameter. @@ -122,7 +123,7 @@ public class JCommander { /** * Alias database for reverse lookup */ - private Map aliasMap = Maps.newLinkedHashMap(); + private Map aliasMap = Maps.newLinkedHashMap(); /** * The name of the command after the parsing has run. @@ -399,8 +400,8 @@ public class JCommander { } private ParameterDescription getPrefixDescriptionFor(String arg) { - for (Map.Entry es : m_descriptions.entrySet()) { - if (arg.startsWith(es.getKey())) return es.getValue(); + for (Map.Entry es : m_descriptions.entrySet()) { + if (arg.startsWith(es.getKey().getName())) return es.getValue(); } return null; @@ -539,14 +540,14 @@ public class JCommander { new ParameterDescription(object, p, parameterized, m_bundle, this); } else { for (String name : p.names()) { - if (m_descriptions.containsKey(name)) { + if (m_descriptions.containsKey(new StringKey(name))) { throw new ParameterException("Found the option " + name + " multiple times"); } p("Adding description for " + name); ParameterDescription pd = new ParameterDescription(object, p, parameterized, m_bundle, this); m_fields.put(parameterized, pd); - m_descriptions.put(name, pd); + m_descriptions.put(new StringKey(name), pd); if (p.required()) m_requiredFields.put(parameterized, pd); } @@ -574,7 +575,7 @@ public class JCommander { ParameterDescription pd = new ParameterDescription(object, dp, parameterized, m_bundle, this); m_fields.put(parameterized, pd); - m_descriptions.put(name, pd); + m_descriptions.put(new StringKey(name), pd); if (dp.required()) m_requiredFields.put(parameterized, pd); } @@ -1356,8 +1357,9 @@ public class JCommander { //Note: Name clash check is intentionally omitted to resemble the // original behaviour of clashing commands. // Aliases are, however, are strictly checked for name clashes. - aliasMap.put(name, progName); - for (String alias : aliases) { + aliasMap.put(new StringKey(name), progName); + for (String a : aliases) { + IKey alias = new StringKey(a); //omit pointless aliases to avoid name clash exception if (!alias.equals(name)) { ProgramName mappedName = aliasMap.get(alias); @@ -1415,68 +1417,29 @@ public class JCommander { return m_objects; } - private V findAbbreviatedOption(Map map, String name, boolean caseSensitive) { - Map results = Maps.newHashMap(); - for (String c : map.keySet()) { - boolean match = (caseSensitive && c.startsWith(name)) - || ((! caseSensitive) && c.toLowerCase().startsWith(name.toLowerCase())); - if (match) { - results.put(c, map.get(c)); - } - } - V result; - if (results.size() > 1) { - throw new ParameterException("Ambiguous option: " + name - + " matches " + results.keySet()); - } else if (results.size() == 1) { - result = results.values().iterator().next(); - } else { - result = null; - } - - return result; - } - - private V findCaseSensitiveMap(Map map, String name) { - if (m_caseSensitiveOptions) { - if (m_allowAbbreviatedOptions) { - return findAbbreviatedOption(map, name, m_caseSensitiveOptions); - } else { - return map.get(name); - } - } else { - if (m_allowAbbreviatedOptions) { - return findAbbreviatedOption(map, name, m_caseSensitiveOptions); - } else { - for (String c : map.keySet()) { - if (c.equalsIgnoreCase(name)) { - return map.get(c); - } - } - } - } - return null; - } - private ParameterDescription findParameterDescription(String arg) { - return findCaseSensitiveMap(m_descriptions, arg); + return FuzzyMap.findInMap(m_descriptions, new StringKey(arg), m_caseSensitiveOptions, + m_allowAbbreviatedOptions); } private JCommander findCommand(ProgramName name) { - if (! m_caseSensitiveOptions) { - return m_commands.get(name); - } else { - for (ProgramName c : m_commands.keySet()) { - if (c.getName().equalsIgnoreCase(name.getName())) { - return m_commands.get(c); - } - } - } - return null; + return FuzzyMap.findInMap(m_commands, name, + m_caseSensitiveOptions, m_allowAbbreviatedOptions); +// if (! m_caseSensitiveOptions) { +// return m_commands.get(name); +// } else { +// for (ProgramName c : m_commands.keySet()) { +// if (c.getName().equalsIgnoreCase(name.getName())) { +// return m_commands.get(c); +// } +// } +// } +// return null; } private ProgramName findProgramName(String name) { - return findCaseSensitiveMap(aliasMap, name); + return FuzzyMap.findInMap(aliasMap, new StringKey(name), + m_caseSensitiveOptions, m_allowAbbreviatedOptions); } /* @@ -1499,7 +1462,7 @@ public class JCommander { /** * Encapsulation of either a main application or an individual command. */ - private static final class ProgramName { + private static final class ProgramName implements IKey { private final String m_name; private final List m_aliases; @@ -1508,6 +1471,7 @@ public class JCommander { m_aliases = aliases; } + @Override public String getName() { return m_name; } diff --git a/src/main/java/com/beust/jcommander/StringKey.java b/src/main/java/com/beust/jcommander/StringKey.java new file mode 100644 index 0000000..09d1149 --- /dev/null +++ b/src/main/java/com/beust/jcommander/StringKey.java @@ -0,0 +1,48 @@ +package com.beust.jcommander; + +import com.beust.jcommander.FuzzyMap.IKey; + +public class StringKey implements IKey { + + private String m_name; + + public StringKey(String name) { + m_name = name; + } + + @Override + public String getName() { + return m_name; + } + + @Override + public String toString() { + return m_name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((m_name == null) ? 0 : m_name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StringKey other = (StringKey) obj; + if (m_name == null) { + if (other.m_name != null) + return false; + } else if (!m_name.equals(other.m_name)) + return false; + return true; + } + +} diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 741f16a..2f2d88d 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -861,7 +861,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { -// new JCommanderTest().ambiguousAbbreviatedOptionsCaseInsensitive(); + new JCommanderTest().multiObjectsWithDuplicatesFail(); // class A { // @Parameter(names = "-short", required = true) // List parameters; diff --git a/src/test/resources/testng-single.xml b/src/test/resources/testng-single.xml index c3cdd46..d981d70 100644 --- a/src/test/resources/testng-single.xml +++ b/src/test/resources/testng-single.xml @@ -4,7 +4,13 @@ - + + + + + -- cgit v1.2.3 From 1f90fd156fce3d83e475208367f389f6f13bd7b5 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 1 Aug 2012 10:58:21 -0700 Subject: Documented abbreviated and case insensitive options. --- doc/index.html | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/index.html b/doc/index.html index e8522e1..bc99bb0 100644 --- a/doc/index.html +++ b/doc/index.html @@ -519,6 +519,21 @@ java Main -d /tmp java Main --outputDirectory /tmp +

            Other option configurations

            + +You can configure how options are looked up in a few different ways: + +
              +
            • JCommander#setCaseSensitiveOptions(boolean): specify whether options are case sensitive. If you call this method with false, then "-param" and + "-PARAM" are considered equal. +
            • +
            • JCommander#setAllowAbbreviatedOptions(boolean): specify whether users can + pass abbreviated options. If you call this method with true then users + can pass "-par" to specify an option called -param. JCommander will + throw a ParameterException if the abbreviated name is ambiguous. +
            • +
            +

            Required and optional parameters

            If some of your parameters are mandatory, you can use the -- cgit v1.2.3 From a62e9f5644875c88737a17308adca7775fdb1450 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 2 Aug 2012 10:22:16 -0700 Subject: Don't wrap a ParameterException in a ParameterException. --- src/main/java/com/beust/jcommander/ParameterDescription.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index d886e30..7fd568c 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -302,6 +302,8 @@ public class ParameterDescription { throw new ParameterException("Can't instantiate validator:" + e); } catch (IllegalAccessException e) { throw new ParameterException("Can't instantiate validator:" + e); + } catch(ParameterException ex) { + throw ex; } catch(Exception ex) { throw new ParameterException(ex); } -- cgit v1.2.3 From f19232f69a08b3fc0242b91ea0095b47f5fad44b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 2 Aug 2012 13:02:56 -0700 Subject: New test. --- src/test/java/com/beust/jcommander/JCommanderTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 2f2d88d..5b41e0b 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -859,9 +859,20 @@ public class JCommanderTest { Assert.assertTrue(sb.toString().contains("Default: ")); } + public void spaces() { + class Arg { + @Parameter(names = "-rule", description = "rule") + private List rules = new ArrayList(); + } + Arg a = new Arg(); + StringBuilder sb = new StringBuilder(); + new JCommander(a, "-rule", "some test"); + Assert.assertEquals(a.rules, Arrays.asList("some test")); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().multiObjectsWithDuplicatesFail(); + new JCommanderTest().spaces(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 3dd7558e2aee86e647b4530f536cbb1fa574b87a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Aug 2012 23:50:48 -0700 Subject: Make getParameter() public. --- src/main/java/com/beust/jcommander/ParameterDescription.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 7fd568c..a49562f 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -192,7 +192,7 @@ public class ParameterDescription { return sb.toString(); } - WrappedParameter getParameter() { + public WrappedParameter getParameter() { return m_wrappedParameter; } -- cgit v1.2.3 From 5377e48b0f7b1b77aa9d546313b11767559068de Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 7 Aug 2012 04:29:57 -0700 Subject: IParameterValidator2. --- .../com/beust/jcommander/IParameterValidator2.java | 34 ++++++++++++++++++++++ src/main/java/com/beust/jcommander/JCommander.java | 3 +- .../com/beust/jcommander/ParameterDescription.java | 9 ++++-- .../java/com/beust/jcommander/JCommanderTest.java | 34 +++++++++++++++++++--- src/test/java/com/beust/jcommander/MyClass.java | 14 +++++++-- 5 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/beust/jcommander/IParameterValidator2.java diff --git a/src/main/java/com/beust/jcommander/IParameterValidator2.java b/src/main/java/com/beust/jcommander/IParameterValidator2.java new file mode 100644 index 0000000..77e7dd3 --- /dev/null +++ b/src/main/java/com/beust/jcommander/IParameterValidator2.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2011 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.beust.jcommander; + +public interface IParameterValidator2 extends IParameterValidator { + + /** + * Validate the parameter. + * + * @param name The name of the parameter (e.g. "-host"). + * @param value The value of the parameter that we need to validate + * @param pd The description of this parameter + * + * @throws ParameterException Thrown if the value of the parameter is invalid. + */ + void validate(String name, String value, ParameterDescription pd) throws ParameterException; + +} diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index bfda67f..30b9b4a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -745,7 +745,8 @@ public class JCommander { } } - ParameterDescription.validateParameter(m_mainParameterAnnotation.validateWith(), + ParameterDescription.validateParameter(m_mainParameterDescription, + m_mainParameterAnnotation.validateWith(), "Default", value); m_mainParameterDescription.setAssigned(true); diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index a49562f..33574a9 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -266,7 +266,7 @@ public class ParameterDescription { private void validateParameter(String name, String value) { Class validator = m_wrappedParameter.validateWith(); if (validator != null) { - validateParameter(validator, name, value); + validateParameter(this, validator, name, value); } } @@ -291,13 +291,18 @@ public class ParameterDescription { } } - public static void validateParameter(Class validator, + public static void validateParameter(ParameterDescription pd, + Class validator, String name, String value) { try { if (validator != NoValidator.class) { p("Validating parameter:" + name + " value:" + value + " validator:" + validator); } validator.newInstance().validate(name, value); + if (IParameterValidator2.class.isAssignableFrom(validator)) { + IParameterValidator2 instance = (IParameterValidator2) validator.newInstance(); + instance.validate(name, value, pd); + } } catch (InstantiationException e) { throw new ParameterException("Can't instantiate validator:" + e); } catch (IllegalAccessException e) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 5b41e0b..22c5082 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -839,11 +839,9 @@ public class JCommanderTest { public void parameterWithOneDoubleQuote() { @Parameters(separators = "=") class Arg { - @Parameter(names = { "-p", "--param" }) private String param; } - JCommander jc = new JCommander(new MyClass()); jc.parse("-p=\""); } @@ -865,14 +863,42 @@ public class JCommanderTest { private List rules = new ArrayList(); } Arg a = new Arg(); - StringBuilder sb = new StringBuilder(); new JCommander(a, "-rule", "some test"); Assert.assertEquals(a.rules, Arrays.asList("some test")); } + static class V2 implements IParameterValidator2 { + final static List names = Lists.newArrayList(); + static boolean validateCalled = false; + + @Override + public void validate(String name, String value) throws ParameterException { + validateCalled = true; + } + + @Override + public void validate(String name, String value, ParameterDescription pd) + throws ParameterException { + names.addAll(Arrays.asList(pd.getParameter().names())); + } + } + + public void validator2() { + class Arg { + @Parameter(names = { "-h", "--host" }, validateWith = V2.class) + String host; + } + Arg a = new Arg(); + V2.names.clear(); + V2.validateCalled = false; + new JCommander(a, "--host", "h"); + Assert.assertEquals(V2.names, Arrays.asList(new String[] { "-h", "--host" })); + Assert.assertTrue(V2.validateCalled); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().spaces(); + new JCommanderTest().parameterWithOneDoubleQuote(); // class A { // @Parameter(names = "-short", required = true) // List parameters; diff --git a/src/test/java/com/beust/jcommander/MyClass.java b/src/test/java/com/beust/jcommander/MyClass.java index 3bf46b5..c2d3371 100644 --- a/src/test/java/com/beust/jcommander/MyClass.java +++ b/src/test/java/com/beust/jcommander/MyClass.java @@ -1,14 +1,24 @@ package com.beust.jcommander; +import org.testng.Assert; + + @Parameters(separators = "=") public class MyClass { - @Parameter(names = { "-p", "--param" }) + @Parameter(names = { "-p", "--param" }, validateWith = MyValidator.class) private String param; public static void main(String[] args) { JCommander jCommander = new JCommander(new MyClass()); - jCommander.parse("-p=\""); + jCommander.parse("--param=value"); + } + + public static class MyValidator implements IParameterValidator { + @Override + public void validate(String name, String value) throws ParameterException { + Assert.assertEquals(value, "\""); + } } } \ No newline at end of file -- cgit v1.2.3 From 80b44a9210ee3fe50e64eb4bdcaad03288ea9f08 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 7 Aug 2012 04:33:43 -0700 Subject: .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 41d1df2..5812af2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target .project .settings test-output +src/test/java/com/beust/jcommander/ignore -- cgit v1.2.3 From 8a4c3d11d8d74628fbe55dce61771810a841723e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 16 Aug 2012 10:33:26 -0700 Subject: Don't throw an exception if running in "no validation" mode. --- src/main/java/com/beust/jcommander/JCommander.java | 25 ++++--- src/test/java/com/beust/jcommander/CmdTest.java | 86 ++++++++++++++++++++++ src/test/resources/testng-single.xml | 5 +- src/test/resources/testng.xml | 1 + 4 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/CmdTest.java diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 30b9b4a..8965f3b 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -273,7 +273,7 @@ public class JCommander { if (m_descriptions == null) createDescriptions(); initializeDefaultValues(); - parseValues(expandArgs(args)); + parseValues(expandArgs(args), validate); if (validate) validateOptions(); } @@ -666,7 +666,7 @@ public class JCommander { /** * Main method that parses the values and initializes the fields accordingly. */ - private void parseValues(String[] args) { + 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) @@ -756,15 +756,18 @@ public class JCommander { // // Command parsing // - if (jc == null) throw new MissingCommandException("Expected a command, got " + arg); - m_parsedCommand = jc.m_programName.m_name; - m_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 - // loop to end. - jc.parse(subArray(args, i + 1)); - commandParsed = true; + if (jc == null && validate) { + throw new MissingCommandException("Expected a command, got " + arg); + } else if (jc != null){ + m_parsedCommand = jc.m_programName.m_name; + m_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 + // loop to end. + jc.parse(subArray(args, i + 1)); + commandParsed = true; + } } } } diff --git a/src/test/java/com/beust/jcommander/CmdTest.java b/src/test/java/com/beust/jcommander/CmdTest.java new file mode 100644 index 0000000..6601193 --- /dev/null +++ b/src/test/java/com/beust/jcommander/CmdTest.java @@ -0,0 +1,86 @@ +package com.beust.jcommander; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public class CmdTest { + + @Parameters(commandNames = "--cmd-one") + public static class CmdOne { + } + + @Parameters(commandNames = "--cmd-two") + class CmdTwo { + @Parameter + List params = new java.util.LinkedList(); + } + + public String parseArgs(boolean withDefault, String[] args) { + JCommander jc = new JCommander(); + jc.addCommand(new CmdOne()); + jc.addCommand(new CmdTwo()); + + if (withDefault) { + // First check if a command was given, when not prepend default + // command (--cmd-two") + // In version up to 1.23 JCommander throws an Exception in this + // line, + // which might be incorrect, at least its not reasonable if the + // method + // is named "WithoutValidation". + jc.parseWithoutValidation(args); + if (jc.getParsedCommand() == null) { + LinkedList newArgs = new LinkedList(); + newArgs.add("--cmd-two"); + newArgs.addAll(Arrays.asList(args)); + jc.parse(newArgs.toArray(new String[0])); + } + } else { + jc.parse(args); + } + return jc.getParsedCommand(); + } + + @DataProvider + public Object[][] testData() { + return new Object[][] { + new Object[] { "--cmd-one", false, new String[] { "--cmd-one" } }, + new Object[] { "--cmd-two", false, new String[] { "--cmd-two" } }, + new Object[] { "--cmd-two", false, + new String[] { "--cmd-two", "param1", "param2" } }, + // This is the relevant test case to test default commands + new Object[] { "--cmd-two", true, + new String[] { "param1", "param2" } } }; + } + + @Test(dataProvider = "testData") + public void testArgsWithoutDefaultCmd(String expected, + boolean requireDefault, String[] args) { + if (!requireDefault) { + Assert.assertEquals(parseArgs(false, args), expected); + } + } + + @Test(dataProvider = "testData", expectedExceptions = MissingCommandException.class) + public void testArgsWithoutDefaultCmdFail(String expected, + boolean requireDefault, String[] args) { + if (requireDefault) { + parseArgs(false, args); + } else { + throw new MissingCommandException("irrelevant test case"); + } + } + + // We do not expect a MissingCommandException! + @Test(dataProvider = "testData") + public void testArgsWithDefaultCmd(String expected, boolean requireDefault, + String[] args) { + Assert.assertEquals(parseArgs(true, args), expected); + } + +} \ No newline at end of file diff --git a/src/test/resources/testng-single.xml b/src/test/resources/testng-single.xml index d981d70..db8497b 100644 --- a/src/test/resources/testng-single.xml +++ b/src/test/resources/testng-single.xml @@ -7,10 +7,7 @@ - - - - + diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index c3592e0..f804418 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -16,6 +16,7 @@ + -- cgit v1.2.3 From c36c84f608a9a0f3877b37e2889bff6d8a1da88d Mon Sep 17 00:00:00 2001 From: Sergey Tyurin Date: Mon, 17 Sep 2012 22:03:11 +0600 Subject: Fix usage() to print missing new-line characters. The change affects the result of usage() when: - there are commands and no main parameters - there are commands without parameters --- src/main/java/com/beust/jcommander/JCommander.java | 4 +- .../java/com/beust/jcommander/JCommanderTest.java | 50 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 8965f3b..16ca88e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1032,10 +1032,10 @@ public class JCommander { String programName = m_programName != null ? m_programName.getDisplayName() : "
            "; out.append(indent).append("Usage: " + programName + " [options]"); if (hasCommands) out.append(indent).append(" [command] [command options]"); -// out.append("\n"); if (m_mainParameterDescription != null) { out.append(" " + m_mainParameterDescription.getDescription()); } + out.append("\n"); // // Align the descriptions at the "longestName" column @@ -1062,7 +1062,7 @@ public class JCommander { // Display all the names and descriptions // int descriptionIndent = 6; - if (sorted.size() > 0) out.append(indent).append("\n").append(indent).append(" Options:\n"); + if (sorted.size() > 0) out.append(indent).append(" Options:\n"); for (ParameterDescription pd : sorted) { WrappedParameter parameter = pd.getParameter(); out.append(indent).append(" " diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 22c5082..b705bfa 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -895,6 +895,56 @@ public class JCommanderTest { Assert.assertEquals(V2.names, Arrays.asList(new String[] { "-h", "--host" })); Assert.assertTrue(V2.validateCalled); } + + public void usageCommandsUnderUsage() { + class Arg { + } + @Parameters(commandDescription = "command a") + class ArgCommandA { + @Parameter(description = "command a parameters") + List parameters; + } + @Parameters(commandDescription = "command b") + class ArgCommandB { + @Parameter(description = "command b parameters") + List parameters; + } + + Arg a = new Arg(); + + JCommander c = new JCommander(a); + c.addCommand("a", new ArgCommandA()); + c.addCommand("b", new ArgCommandB()); + + StringBuilder sb = new StringBuilder(); + c.usage(sb); + Assert.assertTrue(sb.toString().contains("[command options]\n Commands:")); + } + + public void usageWithEmpytLine() { + class Arg { + } + @Parameters(commandDescription = "command a") + class ArgCommandA { + @Parameter(description = "command a parameters") + List parameters; + } + @Parameters(commandDescription = "command b") + class ArgCommandB { + @Parameter(description = "command b parameters") + List parameters; + } + + Arg a = new Arg(); + + JCommander c = new JCommander(a); + c.addCommand("a", new ArgCommandA()); + c.addCommand("b", new ArgCommandB()); + + StringBuilder sb = new StringBuilder(); + c.usage(sb); + Assert.assertTrue(sb.toString().contains("command a parameters\n\n b")); + } @Test(enabled = false) public static void main(String[] args) throws Exception { -- cgit v1.2.3 From c421118d3104c0594dbe207c8443e51022422d32 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 17 Sep 2012 23:01:04 -0700 Subject: Added JCommander#setNoThrow() and JCommander#getUnknownArgs(). --- src/main/java/com/beust/jcommander/JCommander.java | 46 ++++++++++----- .../java/com/beust/jcommander/internal/Lists.java | 5 ++ .../java/com/beust/jcommander/JCommanderTest.java | 65 +++++++++++++--------- src/test/resources/testng-single.xml | 5 +- 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 8965f3b..f1717be 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -18,18 +18,6 @@ package com.beust.jcommander; -import com.beust.jcommander.FuzzyMap.IKey; -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; - import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; @@ -50,6 +38,18 @@ import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; +import com.beust.jcommander.FuzzyMap.IKey; +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 @@ -149,6 +149,9 @@ public class JCommander { private int m_columnSize = 79; private boolean m_helpWasSpecified; + + private List m_unknownArgs = Lists.newArrayList(); + private boolean m_noThrow; private static Console m_console; @@ -721,7 +724,16 @@ public class JCommander { } } } else { - throw new ParameterException("Unknown option: " + arg); + if (m_noThrow) { + m_unknownArgs.add(arg); + i++; + while (i < args.length && ! isOption(args, args[i])) { + m_unknownArgs.add(args[i++]); + } + increment = 0; + } else { + throw new ParameterException("Unknown option: " + arg); + } } } else { @@ -1545,6 +1557,14 @@ public class JCommander { m_allowAbbreviatedOptions = b; } + public void setNoThrow(boolean b) { + m_noThrow = b; + } + + public List getUnknownArgs() { + return m_unknownArgs; + } + // public void setCaseSensitiveCommands(boolean b) { // m_caseSensitiveCommands = b; // } diff --git a/src/main/java/com/beust/jcommander/internal/Lists.java b/src/main/java/com/beust/jcommander/internal/Lists.java index c4017c0..fdbee55 100644 --- a/src/main/java/com/beust/jcommander/internal/Lists.java +++ b/src/main/java/com/beust/jcommander/internal/Lists.java @@ -19,6 +19,7 @@ package com.beust.jcommander.internal; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -33,6 +34,10 @@ public class Lists { return new ArrayList(c); } + public static List newArrayList(K... c) { + return new ArrayList(Arrays.asList(c)); + } + public static List newArrayList(int size) { return new ArrayList(size); } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 22c5082..ff001e3 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -18,6 +18,28 @@ package com.beust.jcommander; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.TreeSet; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + import com.beust.jcommander.args.Args1; import com.beust.jcommander.args.Args1Setter; import com.beust.jcommander.args.Args2; @@ -52,30 +74,8 @@ import com.beust.jcommander.args.VariableArity; import com.beust.jcommander.command.CommandAdd; import com.beust.jcommander.command.CommandCommit; import com.beust.jcommander.command.CommandMain; - -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import org.testng.collections.Lists; -import org.testng.collections.Maps; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigDecimal; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.TreeSet; +import com.beust.jcommander.internal.Lists; +import com.beust.jcommander.internal.Maps; @Test public class JCommanderTest { @@ -891,11 +891,26 @@ public class JCommanderTest { Arg a = new Arg(); V2.names.clear(); V2.validateCalled = false; - new JCommander(a, "--host", "h"); + JCommander jc = new JCommander(a, "--host", "h"); + jc.setNoThrow(true); Assert.assertEquals(V2.names, Arrays.asList(new String[] { "-h", "--host" })); Assert.assertTrue(V2.validateCalled); } + public void partialValidation() { + class Arg { + @Parameter(names = { "-h", "--host" }) + String host; + } + Arg a = new Arg(); + JCommander jc = new JCommander(); + jc.setNoThrow(true); + jc.addObject(a); + jc.parse("-a", "foo", "-h", "host"); + Assert.assertEquals(a.host, "host"); + Assert.assertEquals(jc.getUnknownArgs(), Lists.newArrayList("-a", "foo")); + } + @Test(enabled = false) public static void main(String[] args) throws Exception { new JCommanderTest().parameterWithOneDoubleQuote(); diff --git a/src/test/resources/testng-single.xml b/src/test/resources/testng-single.xml index db8497b..cc0602c 100644 --- a/src/test/resources/testng-single.xml +++ b/src/test/resources/testng-single.xml @@ -7,7 +7,10 @@ - + + + + -- cgit v1.2.3 From c6fb7f8ab1cd68e2765ea018d97138f8ba11ab74 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 17 Sep 2012 23:08:45 -0700 Subject: Change log. --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index fdc3a1c..1b92041 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,9 @@ Current +Added: JCommander#setNoThrow and JCommander#getUnknownArgs Added: JCommander#allowAbbreviatedOptions (default: false) Added: JCommander#setCaseSensitiveOptions (default: true) +Fixed: Missing new lines in usage (styurin) Fixed: The description of commands is now displayed on the next line and indented. Fixed: Empty string defaults now displayed as "" in the usage Fixed: Bugs with the PositiveInteger validator -- cgit v1.2.3 From 406904b81e91c3160646388b26f7c167fa7dd3ea Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 18 Sep 2012 18:44:38 -0700 Subject: Rename: noThrow -> acceptUnknownOption. --- src/main/java/com/beust/jcommander/JCommander.java | 8 ++++---- src/test/java/com/beust/jcommander/JCommanderTest.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 45392f5..3f6853d 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -151,7 +151,7 @@ public class JCommander { private boolean m_helpWasSpecified; private List m_unknownArgs = Lists.newArrayList(); - private boolean m_noThrow; + private boolean m_acceptUnknownOptions = false; private static Console m_console; @@ -724,7 +724,7 @@ public class JCommander { } } } else { - if (m_noThrow) { + if (m_acceptUnknownOptions) { m_unknownArgs.add(arg); i++; while (i < args.length && ! isOption(args, args[i])) { @@ -1557,8 +1557,8 @@ public class JCommander { m_allowAbbreviatedOptions = b; } - public void setNoThrow(boolean b) { - m_noThrow = b; + public void setAcceptUnknownOptions(boolean b) { + m_acceptUnknownOptions = b; } public List getUnknownArgs() { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 9426fd1..cab19be 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -892,7 +892,7 @@ public class JCommanderTest { V2.names.clear(); V2.validateCalled = false; JCommander jc = new JCommander(a, "--host", "h"); - jc.setNoThrow(true); + jc.setAcceptUnknownOptions(true); Assert.assertEquals(V2.names, Arrays.asList(new String[] { "-h", "--host" })); Assert.assertTrue(V2.validateCalled); } @@ -954,7 +954,7 @@ public class JCommanderTest { } Arg a = new Arg(); JCommander jc = new JCommander(); - jc.setNoThrow(true); + jc.setAcceptUnknownOptions(true); jc.addObject(a); jc.parse("-a", "foo", "-h", "host"); Assert.assertEquals(a.host, "host"); -- cgit v1.2.3 From 31f61c5de3753a86d58a5bf2399ea5ea7312d35b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Tue, 18 Sep 2012 22:12:45 -0700 Subject: Renaming. --- src/main/java/com/beust/jcommander/JCommander.java | 2 +- src/test/java/com/beust/jcommander/JCommanderTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 3f6853d..1b49ae7 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1561,7 +1561,7 @@ public class JCommander { m_acceptUnknownOptions = b; } - public List getUnknownArgs() { + public List getUnknownOptions() { return m_unknownArgs; } diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index cab19be..5199cad 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -958,7 +958,7 @@ public class JCommanderTest { jc.addObject(a); jc.parse("-a", "foo", "-h", "host"); Assert.assertEquals(a.host, "host"); - Assert.assertEquals(jc.getUnknownArgs(), Lists.newArrayList("-a", "foo")); + Assert.assertEquals(jc.getUnknownOptions(), Lists.newArrayList("-a", "foo")); } @Test(enabled = false) -- cgit v1.2.3 From 5fc805c44e904eb37f24217676b5da1619268c48 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 23 Sep 2012 06:10:45 -0700 Subject: Added enum support (Scott M. Stark). --- CHANGELOG | 1 + src/main/java/com/beust/jcommander/JCommander.java | 6 +++++- src/test/java/com/beust/jcommander/JCommanderTest.java | 5 ++++- src/test/java/com/beust/jcommander/args/ArgsEnum.java | 11 ++++++++--- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1b92041..514c1f9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Current Added: JCommander#setNoThrow and JCommander#getUnknownArgs Added: JCommander#allowAbbreviatedOptions (default: false) Added: JCommander#setCaseSensitiveOptions (default: true) +Added: Support for enums (Scott M Stark) Fixed: Missing new lines in usage (styurin) Fixed: The description of commands is now displayed on the next line and indented. Fixed: Empty string defaults now displayed as "" in the usage diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 1b49ae7..efde39e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1235,6 +1235,10 @@ public class JCommander { converterClass = elementType != null ? findConverter((Class>) elementType) : StringConverter.class; + // Check for enum type parameter + if (converterClass == null && Enum.class.isAssignableFrom((Class) elementType)) { + converterClass = (Class>) elementType; + } } // @@ -1257,7 +1261,7 @@ public class JCommander { try { String[] names = annotation.names(); String optionName = names.length > 0 ? names[0] : "[Main class]"; - if (converterClass.isEnum()) { + if (converterClass != null && converterClass.isEnum()) { try { result = Enum.valueOf((Class) converterClass, value.toUpperCase()); } catch (Exception e) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 5199cad..a5caca0 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -48,6 +48,7 @@ import com.beust.jcommander.args.ArgsBooleanArity; import com.beust.jcommander.args.ArgsBooleanArity0; import com.beust.jcommander.args.ArgsConverter; import com.beust.jcommander.args.ArgsEnum; +import com.beust.jcommander.args.ArgsEnum.ChoiceType; import com.beust.jcommander.args.ArgsEquals; import com.beust.jcommander.args.ArgsHelp; import com.beust.jcommander.args.ArgsI18N1; @@ -561,11 +562,13 @@ public class JCommanderTest { public void enumArgs() { ArgsEnum args = new ArgsEnum(); - String[] argv = { "-choice", "ONE"}; + String[] argv = { "-choice", "ONE", "-choices", "ONE", "TWO" }; JCommander jc = new JCommander(args, argv); Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE); + List expected = Arrays.asList(ChoiceType.ONE, ChoiceType.TWO); + Assert.assertEquals(expected, args.choices); Assert.assertEquals(jc.getParameters().get(0).getDescription(), "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class)); diff --git a/src/test/java/com/beust/jcommander/args/ArgsEnum.java b/src/test/java/com/beust/jcommander/args/ArgsEnum.java index 16643cd..c6b0c08 100644 --- a/src/test/java/com/beust/jcommander/args/ArgsEnum.java +++ b/src/test/java/com/beust/jcommander/args/ArgsEnum.java @@ -18,12 +18,14 @@ package com.beust.jcommander.args; -import com.beust.jcommander.JCommander; -import com.beust.jcommander.Parameter; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; import org.testng.Assert; -import java.util.EnumSet; +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; /** * Test enums. @@ -36,6 +38,9 @@ public class ArgsEnum { @Parameter(names = "-choice") public ChoiceType choice = ChoiceType.ONE; + @Parameter(names = "-choices", variableArity = true) + public List choices = new ArrayList(); + public static void main(String[] args1) { ArgsEnum args = new ArgsEnum(); String[] argv = { "-choice", "ONE"}; -- cgit v1.2.3 From c55dc01a3d8c54dc5711860e6e649d4cb9ba70e8 Mon Sep 17 00:00:00 2001 From: John Yani Date: Thu, 25 Oct 2012 12:33:30 +0300 Subject: Update README.markdown Add a DynamicParameter. Swap expected and actual in assertion. Make a -groups option more clear. Show where parameters are stored. --- README.markdown | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index bf479db..048bc39 100644 --- a/README.markdown +++ b/README.markdown @@ -18,6 +18,10 @@ public class JCommanderTest { @Parameter(names = "-debug", description = "Debug mode") public boolean debug = false; + + @DynamicParameter(names = "-D", description = "Dynamic parameters go here") + public Map dynamicParams = new HashMap(); + } ``` @@ -25,10 +29,19 @@ and how you use it: ```java CommanderTest jct = new JCommanderTest(); -String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; +String[] argv = { "-log", "2", "-groups", "unit1,unit2,unit3", + "-Doption=value", "a", "b", "c" }; new JCommander(jct, argv); -Assert.assertEquals(jct.verbose.intValue(), 2); +Assert.assertEquals(2, jct.verbose.intValue()); + +Assert.assertEquals("unit1,unit2,unit3", jct.groups); + +Map params = new HashMap(); +params.put("option", "value"); +Assert.assertEquals(params, jct.params); + +Assert.assertEquals(Arrays.asList("a", "b", "c"), jct.parameters); ``` The full doc is available at http://beust.com/jcommander -- cgit v1.2.3 From 459da854b54683fda1c17a0d1250162201dacf45 Mon Sep 17 00:00:00 2001 From: John Yani Date: Thu, 25 Oct 2012 12:43:46 +0300 Subject: Update README.markdown Provide a boolean flag demo. --- README.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 048bc39..18c69e7 100644 --- a/README.markdown +++ b/README.markdown @@ -30,12 +30,12 @@ and how you use it: ```java CommanderTest jct = new JCommanderTest(); String[] argv = { "-log", "2", "-groups", "unit1,unit2,unit3", - "-Doption=value", "a", "b", "c" }; + "-debug", "-Doption=value", "a", "b", "c" }; new JCommander(jct, argv); Assert.assertEquals(2, jct.verbose.intValue()); - Assert.assertEquals("unit1,unit2,unit3", jct.groups); +Assert.assertEquals(true, jct.debug); Map params = new HashMap(); params.put("option", "value"); -- cgit v1.2.3 From f50612c269bd81a78f1b215357075f14f77a5970 Mon Sep 17 00:00:00 2001 From: John Yani Date: Thu, 25 Oct 2012 12:52:08 +0300 Subject: Update README.markdown Simplify --- README.markdown | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.markdown b/README.markdown index 18c69e7..0aecbf5 100644 --- a/README.markdown +++ b/README.markdown @@ -28,19 +28,15 @@ public class JCommanderTest { and how you use it: ```java -CommanderTest jct = new JCommanderTest(); +JCommanderTest jct = new JCommanderTest(); String[] argv = { "-log", "2", "-groups", "unit1,unit2,unit3", - "-debug", "-Doption=value", "a", "b", "c" }; + "-debug", "-Doption=value", "a", "b", "c" }; new JCommander(jct, argv); Assert.assertEquals(2, jct.verbose.intValue()); Assert.assertEquals("unit1,unit2,unit3", jct.groups); Assert.assertEquals(true, jct.debug); - -Map params = new HashMap(); -params.put("option", "value"); -Assert.assertEquals(params, jct.params); - +Assert.assertEquals("value", jct.dynamicParams.get("option")); Assert.assertEquals(Arrays.asList("a", "b", "c"), jct.parameters); ``` -- cgit v1.2.3 From 30931bb8f8b8edfad31160e13230e8bc6f85e72b Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 25 Oct 2012 09:02:30 -0700 Subject: Doc clarification. --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index bc99bb0..e740391 100644 --- a/doc/index.html +++ b/doc/index.html @@ -79,7 +79,7 @@ and then you simply ask JCommander to parse:
             JCommanderExample jct = new JCommanderExample();
            -String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" };
            +String[] argv = { "-log", "2", "-groups", "unit" };
             new JCommander(jct, argv);
             
             Assert.assertEquals(jct.verbose.intValue(), 2);
            -- 
            cgit v1.2.3
            
            
            From 5d2a3459de27c363143f4b89d9bdb5550116b730 Mon Sep 17 00:00:00 2001
            From: John Yani 
            Date: Sat, 27 Oct 2012 15:12:52 +0300
            Subject: Fix the CHANGELOG
            
            ---
             CHANGELOG | 7 +++++--
             1 file changed, 5 insertions(+), 2 deletions(-)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index 514c1f9..308c0b6 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -1,17 +1,20 @@
             Current
             
            -Added: JCommander#setNoThrow and JCommander#getUnknownArgs
            +Added: JCommander#acceptUnknownOption and JCommander#getUnknownArgs
             Added: JCommander#allowAbbreviatedOptions (default: false)
             Added: JCommander#setCaseSensitiveOptions (default: true)
             Added: Support for enums (Scott M Stark)
             Fixed: Missing new lines in usage (styurin)
             Fixed: The description of commands is now displayed on the next line and indented.
            +
            +1.29
            +2012/07/28
             Fixed: Empty string defaults now displayed as "" in the usage
             Fixed: Bugs with the PositiveInteger validator
             Fixed: Parameters with a single double quote were not working properly
             
             1.27
            -1012/08/05
            +2012/07/05
             Added: IValueValidator to validate parameter values (typed) as opposed to IParameterValidator which validates strings
             Added: echoInput, used when password=true to echo the characters (Jason Wheeler)
             Added: @Parameter(help = true)
            -- 
            cgit v1.2.3
            
            
            From f33601791cd2bbd01009b7dd26f45329d23fb6bf Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 27 Oct 2012 08:44:23 -0700
            Subject: [maven-release-plugin] prepare release jcommander-1.30
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 35e5a4d..1e2073e 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.30-SNAPSHOT
            +  1.30
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From bb1537ff23e87535bb0b1cd0024421107967fdcf Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 27 Oct 2012 08:44:30 -0700
            Subject: [maven-release-plugin] prepare for next development iteration
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 1e2073e..b1c3062 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.30
            +  1.31-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 20a8ea0b0da5f7f0e724716943eb0f0f3d7104d4 Mon Sep 17 00:00:00 2001
            From: John Yani 
            Date: Sat, 27 Oct 2012 22:07:22 +0300
            Subject: Update the CHANGELOG due to 1.30 release
            
            ---
             CHANGELOG | 6 ++++++
             1 file changed, 6 insertions(+)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index 308c0b6..05bb809 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -1,5 +1,8 @@
             Current
             
            +1.30
            +2012/10/27
            +
             Added: JCommander#acceptUnknownOption and JCommander#getUnknownArgs
             Added: JCommander#allowAbbreviatedOptions (default: false)
             Added: JCommander#setCaseSensitiveOptions (default: true)
            @@ -9,12 +12,14 @@ Fixed: The description of commands is now displayed on the next line and indente
             
             1.29
             2012/07/28
            +
             Fixed: Empty string defaults now displayed as "" in the usage
             Fixed: Bugs with the PositiveInteger validator
             Fixed: Parameters with a single double quote were not working properly
             
             1.27
             2012/07/05
            +
             Added: IValueValidator to validate parameter values (typed) as opposed to IParameterValidator which validates strings
             Added: echoInput, used when password=true to echo the characters (Jason Wheeler)
             Added: @Parameter(help = true)
            @@ -26,6 +31,7 @@ Fixed: variable arities not working when same parameter appears multiple times.
             
             1.25
             2012/04/26
            +
             Added: Default passwords are no longer displayed in the usage (Paul Mendelson)
             Added: Variable arities now work magically, no need for IVariableArity any more
             Fixed: Commands using @Parameters(resourceBundle) were not i18n'ed properly in the usage()
            -- 
            cgit v1.2.3
            
            
            From d5490aabc6002f9400e5cf3050f098ab967253d2 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 10 Nov 2012 10:29:37 -0800
            Subject: Fixed: GITHUB-107: Allow enum values without converting them to
             uppercase.
            
            ---
             CHANGELOG                                              | 2 ++
             src/main/java/com/beust/jcommander/JCommander.java     | 5 ++++-
             src/test/java/com/beust/jcommander/JCommanderTest.java | 6 +++---
             src/test/java/com/beust/jcommander/args/ArgsEnum.java  | 2 +-
             4 files changed, 10 insertions(+), 5 deletions(-)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index 05bb809..aef125c 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -1,5 +1,7 @@
             Current
             
            +Fixed: GITHUB-107: Allow enum values without converting them to uppercase.
            +
             1.30
             2012/10/27
             
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index efde39e..4f2929e 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -1263,7 +1263,10 @@ public class JCommander {
                   String optionName = names.length > 0 ? names[0] : "[Main class]";
                   if (converterClass != null && converterClass.isEnum()) {
                     try {
            -          result = Enum.valueOf((Class) converterClass, value.toUpperCase());
            +          result = Enum.valueOf((Class) converterClass, value);
            +          if (result == null) {
            +            result = Enum.valueOf((Class) converterClass, value.toUpperCase());
            +          }
                     } catch (Exception e) {
                       throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" +
                                                    EnumSet.allOf((Class) converterClass));
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index a5caca0..4a84496 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -562,12 +562,12 @@ public class JCommanderTest {
             
               public void enumArgs() {
                 ArgsEnum args = new ArgsEnum();
            -    String[] argv = { "-choice", "ONE", "-choices", "ONE", "TWO" };
            +    String[] argv = { "-choice", "ONE", "-choices", "ONE", "Two" };
                 JCommander jc = new JCommander(args, argv);
             
                 Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE);
                 
            -    List expected = Arrays.asList(ChoiceType.ONE, ChoiceType.TWO);
            +    List expected = Arrays.asList(ChoiceType.ONE, ChoiceType.Two);
                 Assert.assertEquals(expected, args.choices);
                 Assert.assertEquals(jc.getParameters().get(0).getDescription(),
                     "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class));
            @@ -966,7 +966,7 @@ public class JCommanderTest {
             
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    new JCommanderTest().parameterWithOneDoubleQuote();
            +    new JCommanderTest().enumArgs();
             //    class A {
             //      @Parameter(names = "-short", required = true)
             //      List parameters;
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsEnum.java b/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            index c6b0c08..bef663b 100644
            --- a/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            +++ b/src/test/java/com/beust/jcommander/args/ArgsEnum.java
            @@ -34,7 +34,7 @@ import com.beust.jcommander.Parameter;
              */
             public class ArgsEnum {
             
            -  public enum ChoiceType { ONE, TWO, THREE };
            +  public enum ChoiceType { ONE, Two, THREE };
               @Parameter(names = "-choice")
               public ChoiceType choice = ChoiceType.ONE;
               
            -- 
            cgit v1.2.3
            
            
            From 07e332d70768d2f49d835ccf65628d73d2d6703f Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 10 Nov 2012 11:30:30 -0800
            Subject: Fixed: GITHUB-137: Main parameters with a default value should be
             overridden if a main parameter is specified
            
            ---
             CHANGELOG                                           |  1 +
             src/main/java/com/beust/jcommander/JCommander.java  | 21 ++++++---------------
             .../java/com/beust/jcommander/JCommanderTest.java   | 15 ++++++++++++++-
             3 files changed, 21 insertions(+), 16 deletions(-)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index aef125c..0893a59 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -1,5 +1,6 @@
             Current
             
            +Fixed: GITHUB-137: Main parameters with a default value should be overridden if a main parameter is specified 
             Fixed: GITHUB-107: Allow enum values without converting them to uppercase.
             
             1.30
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 4f2929e..1bc0084 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -75,6 +75,8 @@ public class JCommander {
                */
               private List m_objects = Lists.newArrayList();
             
            +  private boolean m_firstTimeMainParameter = true;
            +
               /**
                * This field/method will contain whatever command line parameter is not an option.
                * It is expected to be a List.
            @@ -913,6 +915,10 @@ public class JCommander {
                   }
                   m_mainParameter.set(m_mainParameterObject, result);
                 }
            +    if (m_firstTimeMainParameter) {
            +      result.clear();
            +      m_firstTimeMainParameter = false;
            +    }
                 return result;
               }
             
            @@ -1241,21 +1247,6 @@ public class JCommander {
                   }
                 }
             
            -    //
            -//    //
            -//    // Try to find a converter in the factory
            -//    //
            -//    IStringConverter converter = null;
            -//    if (converterClass == null && m_converterFactories != null) {
            -//      // Mmmh, javac requires a cast here
            -//      converter = (IStringConverter) m_converterFactories.getConverter(type);
            -//    }
            -
            -//    if (converterClass == null) {
            -//      throw new ParameterException("Don't know how to convert " + value
            -//          + " to type " + type + " (field: " + field.getName() + ")");
            -//    }
            -
                 IStringConverter converter;
                 Object result = null;
                 try {
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 4a84496..4f67f9a 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -964,9 +964,22 @@ public class JCommanderTest {
                 Assert.assertEquals(jc.getUnknownOptions(), Lists.newArrayList("-a", "foo"));
               }
             
            +  /**
            +   * GITHUB-137.
            +   */
            +  public void listArgShouldBeCleared() {
            +    class Args {
            +      @Parameter(description = "[endpoint]")
            +      public List endpoint = Lists.newArrayList("prod");
            +    }
            +    Args a = new Args();
            +    new JCommander(a, new String[] { "dev" });
            +    Assert.assertEquals(a.endpoint, Lists.newArrayList("dev"));
            +  }
            +
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    new JCommanderTest().enumArgs();
            +    new JCommanderTest().listParameters(); // listArgShouldBeCleared();
             //    class A {
             //      @Parameter(names = "-short", required = true)
             //      List parameters;
            -- 
            cgit v1.2.3
            
            
            From cf62891268452675c56a4b18d5866123398e1cb3 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 10 Nov 2012 11:41:04 -0800
            Subject: New test.
            
            ---
             .../java/com/beust/jcommander/JCommanderTest.java  | 24 +++++++++++++++++++++-
             1 file changed, 23 insertions(+), 1 deletion(-)
            
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 4f67f9a..356d442 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -977,9 +977,31 @@ public class JCommanderTest {
                 Assert.assertEquals(a.endpoint, Lists.newArrayList("dev"));
               }
             
            +  public void a() {
            +    class Arguments {
            +        @Parameter(names = { "-help", "-h" }, arity = 0, description = "Show this help message")
            +        public Boolean help = false;
            +        
            +        @Parameter(names = { "-verbose", "-v" }, arity = 0, description = "Verbose output mode")
            +        public Boolean verbose = false;
            +        
            +        @Parameter(names = { "-target" }, arity = 1, description = "Target directory", required = true)
            +        public File target;
            +        
            +        @Parameter(names = { "-input" }, variableArity = true, description = "Input paths", required = true)
            +        public List paths;
            +    }
            +    Arguments a = new Arguments();
            +    new JCommander(a, new String[] {
            +        "-input", "example_in1", "example_in2", "-target", "example_out" }
            +    );
            +    Assert.assertEquals(a.paths, Lists.newArrayList("example_in1", "example_in2"));
            +    Assert.assertEquals(a.target, new File("example_out"));
            +  }
            +
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    new JCommanderTest().listParameters(); // listArgShouldBeCleared();
            +    new JCommanderTest().a();
             //    class A {
             //      @Parameter(names = "-short", required = true)
             //      List parameters;
            -- 
            cgit v1.2.3
            
            
            From e96931e95b746330b5d6aebe5bfead6d5ba2201a Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sun, 11 Nov 2012 22:18:38 -0800
            Subject: Wrong file.
            
            ---
             CHANGELOG | 3 ---
             1 file changed, 3 deletions(-)
            
            diff --git a/CHANGELOG b/CHANGELOG
            index 0893a59..05bb809 100644
            --- a/CHANGELOG
            +++ b/CHANGELOG
            @@ -1,8 +1,5 @@
             Current
             
            -Fixed: GITHUB-137: Main parameters with a default value should be overridden if a main parameter is specified 
            -Fixed: GITHUB-107: Allow enum values without converting them to uppercase.
            -
             1.30
             2012/10/27
             
            -- 
            cgit v1.2.3
            
            
            From 74678a3a186b681f116c1580d6c3445a03207039 Mon Sep 17 00:00:00 2001
            From: kjpoalses 
            Date: Fri, 21 Dec 2012 08:04:51 +0000
            Subject: New: @Parameters can now be used with cglib proxies
            
            ---
             pom.xml                                            | 2 +-
             src/main/java/com/beust/jcommander/Parameters.java | 6 ++++--
             2 files changed, 5 insertions(+), 3 deletions(-)
            
            diff --git a/pom.xml b/pom.xml
            index b1c3062..d17bda8 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -137,7 +137,7 @@
                       
                         com.beust
                         jcommander
            -            1.13
            +            1.31-SNAPSHOT
             
            diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java
            index be5b5ce..9834ea0 100644
            --- a/src/main/java/com/beust/jcommander/Parameters.java
            +++ b/src/main/java/com/beust/jcommander/Parameters.java
            @@ -18,11 +18,12 @@
             
             package com.beust.jcommander;
             
            -import static java.lang.annotation.ElementType.TYPE;
            -
            +import java.lang.annotation.Inherited;
             import java.lang.annotation.Retention;
             import java.lang.annotation.Target;
             
            +import static java.lang.annotation.ElementType.TYPE;
            +
             /**
              * An annotation used to specify settings for parameter parsing.
              * 
            @@ -30,6 +31,7 @@ import java.lang.annotation.Target;
              */
             @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
             @Target({ TYPE })
            +@Inherited
             public @interface Parameters {
             
               public static final String DEFAULT_OPTION_PREFIXES = "-";
            -- 
            cgit v1.2.3
            
            
            From e014aa0143809847d06e6923ce4a5949b3c0e401 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sun, 3 Feb 2013 06:58:26 -0800
            Subject: Doc update.
            
            ---
             doc/index.html | 4 ++--
             1 file changed, 2 insertions(+), 2 deletions(-)
            
            diff --git a/doc/index.html b/doc/index.html
            index e740391..ad3d051 100644
            --- a/doc/index.html
            +++ b/doc/index.html
            @@ -39,7 +39,7 @@
               
               
                 
            -      Last updated: July 31st, 2012
            +      Last updated: October 25th, 2012
                 
               
               Cédric Beust
            @@ -825,7 +825,7 @@ You can download JCommander from the following locations:
             
               <groupId>com.beust</groupId>
               <artifactId>jcommander</artifactId>
            -  <version>1.27</version>
            +  <version>1.30</version>
             
               
             
            -- 
            cgit v1.2.3
            
            
            From 25fbea80c0d4e8b84143b19fb729c1b8c27989a5 Mon Sep 17 00:00:00 2001
            From: Mike Drob 
            Date: Fri, 7 Jun 2013 02:00:32 -0400
            Subject: added test for quotes
            
            ---
             .../java/com/mdrob/jcommander/QuotedMainTest.java  | 30 ++++++++++++++++++++++
             1 file changed, 30 insertions(+)
             create mode 100644 src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            
            diff --git a/src/test/java/com/mdrob/jcommander/QuotedMainTest.java b/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            new file mode 100644
            index 0000000..fcd2e2e
            --- /dev/null
            +++ b/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            @@ -0,0 +1,30 @@
            +package com.mdrob.jcommander;
            +
            +import java.util.ArrayList;
            +import java.util.Collections;
            +import java.util.List;
            +
            +import org.testng.Assert;
            +import org.testng.annotations.Test;
            +
            +import com.beust.jcommander.JCommander;
            +import com.beust.jcommander.Parameter;
            +
            +
            +public class QuotedMainTest {
            +  public static class Options {
            +    @Parameter
            +    List args = new ArrayList();
            +    
            +    @Parameter(names={"-f", "--foo"})
            +    String other;
            +  }
            +  
            +  @Test
            +  public void testMain() {    
            +    String quoted = "\"quoted\"";
            +    Options options = new Options();
            +    new JCommander(options).parse(quoted);
            +    Assert.assertEquals(options.args, Collections.singletonList(quoted));
            +  }
            +}
            -- 
            cgit v1.2.3
            
            
            From fa793cd8418739fba071ab481b322bdcad18389f Mon Sep 17 00:00:00 2001
            From: Mike Drob 
            Date: Fri, 7 Jun 2013 02:33:58 -0400
            Subject: test to reproduce bug with quoted main parameters
            
            ---
             pom.xml                                            |  2 +-
             .../java/com/mdrob/jcommander/QuotedMainTest.java  | 26 ++++++++++------------
             2 files changed, 13 insertions(+), 15 deletions(-)
            
            diff --git a/pom.xml b/pom.xml
            index d17bda8..ece970e 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -131,7 +131,7 @@
                     maven-surefire-plugin
                     2.10
                     
            -          true
            +          false
                     
                     
                       
            diff --git a/src/test/java/com/mdrob/jcommander/QuotedMainTest.java b/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            index fcd2e2e..9b0cbb3 100644
            --- a/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            +++ b/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            @@ -1,7 +1,6 @@
             package com.mdrob.jcommander;
             
             import java.util.ArrayList;
            -import java.util.Collections;
             import java.util.List;
             
             import org.testng.Assert;
            @@ -10,21 +9,20 @@ import org.testng.annotations.Test;
             import com.beust.jcommander.JCommander;
             import com.beust.jcommander.Parameter;
             
            -
             public class QuotedMainTest {
            -  public static class Options {
            -    @Parameter
            -    List args = new ArrayList();
            -    
            -    @Parameter(names={"-f", "--foo"})
            -    String other;
            -  }
            +  @Parameter
            +  List args = new ArrayList();
               
            +  String quoted = "\" \"";
            +
               @Test
            -  public void testMain() {    
            -    String quoted = "\"quoted\"";
            -    Options options = new Options();
            -    new JCommander(options).parse(quoted);
            -    Assert.assertEquals(options.args, Collections.singletonList(quoted));
            +  public void testMain() {
            +    JCommander jc = new JCommander(this);
            +    jc.parse(quoted);
            +    Assert.assertEquals(args.size(), 1);
            +  }
            +  
            +  public static void main(String[] args) {
            +    new QuotedMainTest().testMain();
               }
             }
            -- 
            cgit v1.2.3
            
            
            From b2435441a8c891f9577fdab4421a580f5f807758 Mon Sep 17 00:00:00 2001
            From: Mike Drob 
            Date: Fri, 7 Jun 2013 03:04:36 -0400
            Subject: bugfix to address quoted main params
            
            ---
             pom.xml                                            |  2 +-
             src/main/java/com/beust/jcommander/JCommander.java |  3 ++-
             .../java/com/mdrob/jcommander/QuotedMainTest.java  | 28 ---------------------
             src/test/java/test/QuotedMainTest.java             | 29 ++++++++++++++++++++++
             4 files changed, 32 insertions(+), 30 deletions(-)
             delete mode 100644 src/test/java/com/mdrob/jcommander/QuotedMainTest.java
             create mode 100644 src/test/java/test/QuotedMainTest.java
            
            diff --git a/pom.xml b/pom.xml
            index ece970e..d17bda8 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -131,7 +131,7 @@
                     maven-surefire-plugin
                     2.10
                     
            -          false
            +          true
                     
                     
                       
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 1bc0084..b78d890 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -680,6 +680,7 @@ public class JCommander {
                 while (i < args.length && ! commandParsed) {
                   String arg = args[i];
                   String a = trim(arg);
            +      args[i] = a;
                   p("Parsing arg: " + a);
             
                   JCommander jc = findCommandByAlias(arg);
            @@ -748,7 +749,7 @@ public class JCommander {
                         // Regular (non-command) parsing
                         //
                         List mp = getMainParameter(arg);
            -            String value = arg;
            +            String value = a; // If there's a non-quoted version, prefer that one
                         Object convertedValue = value;
             
                         if (m_mainParameter.getGenericType() instanceof ParameterizedType) {
            diff --git a/src/test/java/com/mdrob/jcommander/QuotedMainTest.java b/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            deleted file mode 100644
            index 9b0cbb3..0000000
            --- a/src/test/java/com/mdrob/jcommander/QuotedMainTest.java
            +++ /dev/null
            @@ -1,28 +0,0 @@
            -package com.mdrob.jcommander;
            -
            -import java.util.ArrayList;
            -import java.util.List;
            -
            -import org.testng.Assert;
            -import org.testng.annotations.Test;
            -
            -import com.beust.jcommander.JCommander;
            -import com.beust.jcommander.Parameter;
            -
            -public class QuotedMainTest {
            -  @Parameter
            -  List args = new ArrayList();
            -  
            -  String quoted = "\" \"";
            -
            -  @Test
            -  public void testMain() {
            -    JCommander jc = new JCommander(this);
            -    jc.parse(quoted);
            -    Assert.assertEquals(args.size(), 1);
            -  }
            -  
            -  public static void main(String[] args) {
            -    new QuotedMainTest().testMain();
            -  }
            -}
            diff --git a/src/test/java/test/QuotedMainTest.java b/src/test/java/test/QuotedMainTest.java
            new file mode 100644
            index 0000000..abb97c0
            --- /dev/null
            +++ b/src/test/java/test/QuotedMainTest.java
            @@ -0,0 +1,29 @@
            +package test;
            +
            +import java.util.ArrayList;
            +import java.util.List;
            +
            +import org.testng.Assert;
            +import org.testng.annotations.Test;
            +
            +import com.beust.jcommander.JCommander;
            +import com.beust.jcommander.Parameter;
            +
            +public class QuotedMainTest {
            +  @Parameter
            +  List args = new ArrayList();
            +  
            +  String quoted = "\" \"";
            +
            +  @Test
            +  public void testMain() {
            +    JCommander jc = new JCommander(this);
            +    jc.parse(quoted);
            +    Assert.assertEquals(args.size(), 1);
            +    Assert.assertEquals(args.get(0), " ");
            +  }
            +  
            +  public static void main(String[] args) {
            +    new QuotedMainTest().testMain();
            +  }
            +}
            -- 
            cgit v1.2.3
            
            
            From d627b357c2a63b003869de40221c02b04d0eb663 Mon Sep 17 00:00:00 2001
            From: Julien Massenet 
            Date: Mon, 5 Aug 2013 14:41:43 +0200
            Subject: Do not close System.in when using DefaultConsole
            
            ---
             .../beust/jcommander/internal/DefaultConsole.java  |  3 +-
             .../jcommander/internal/DefaultConsoleTest.java    | 64 ++++++++++++++++++++++
             2 files changed, 65 insertions(+), 2 deletions(-)
             create mode 100644 src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java
            
            diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java
            index 65e87ba..8fd7d6d 100644
            --- a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java
            +++ b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java
            @@ -18,11 +18,10 @@ public class DefaultConsole implements Console {
             
               public char[] readPassword(boolean echoInput) {
                 try {
            +      // Do not close the readers since System.in should not be closed
                   InputStreamReader isr = new InputStreamReader(System.in);
                   BufferedReader in = new BufferedReader(isr);
                   String result = in.readLine();
            -      in.close();
            -      isr.close();
                   return result.toCharArray();
                 }
                 catch (IOException e) {
            diff --git a/src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java b/src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java
            new file mode 100644
            index 0000000..e101439
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java
            @@ -0,0 +1,64 @@
            +package com.beust.jcommander.internal;
            +
            +import java.io.IOException;
            +import java.io.InputStream;
            +
            +import org.testng.Assert;
            +import org.testng.annotations.Test;
            +
            +@Test
            +public class DefaultConsoleTest {
            +  public void readPasswordCanBeCalledMultipleTimes() {
            +    final InputStream inBackup = System.in;
            +    try {
            +      final StringInputStream in = new StringInputStream();
            +      System.setIn(in);
            +      final Console console = new DefaultConsole();
            +
            +      in.setData("password1\n");
            +      char[] password = console.readPassword(false);
            +      Assert.assertEquals(password, "password1".toCharArray());
            +      Assert.assertFalse(in.isClosedCalled(), "System.in stream shouldn't be closed");
            +
            +      in.setData("password2\n");
            +      password = console.readPassword(false);
            +      Assert.assertEquals(password, "password2".toCharArray());
            +      Assert.assertFalse(in.isClosedCalled(), "System.in stream shouldn't be closed");
            +    } finally {
            +      System.setIn(inBackup);
            +    }
            +  }
            +
            +  private static class StringInputStream extends InputStream {
            +    private byte[] data = new byte[0];
            +    private int offset = 0;
            +    private boolean closedCalled;
            +
            +    StringInputStream() {
            +      super();
            +    }
            +
            +    void setData(final String strData) {
            +      data = strData.getBytes();
            +      offset = 0;
            +    }
            +
            +    boolean isClosedCalled() {
            +      return closedCalled;
            +    }
            +
            +    @Override
            +    public int read() throws IOException {
            +      if (offset >= data.length) {
            +        return -1;
            +      }
            +      return 0xFFFF & data[offset++];
            +    }
            +
            +    @Override
            +    public void close() throws IOException {
            +      closedCalled = true;
            +      super.close();
            +    }
            +  }
            +}
            -- 
            cgit v1.2.3
            
            
            From caa49a6cc4587c128b9a05204d56b8ae2ab155c5 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 9 Sep 2013 22:56:55 -0700
            Subject: Build update
            
            ---
             build-with-maven | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/build-with-maven b/build-with-maven
            index 988f7d9..41aef5a 100755
            --- a/build-with-maven
            +++ b/build-with-maven
            @@ -2,7 +2,7 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign
             
             
             #v=6.5.2beta
            -export TESTNG=`echo ../testng/target/testng*jar`
            +export TESTNG=`echo ../testng/target/testng-6.8.7.jar`
             
             run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml"
             echo "Launching tests: ${run}"
            -- 
            cgit v1.2.3
            
            
            From c3299661480c68139f64ae9018fee1aef85a7c7a Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 9 Sep 2013 22:59:27 -0700
            Subject: pom
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index d17bda8..faf3ac1 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.31-SNAPSHOT
            +  1.32-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 43d5ef7d1d4d8691bbc15122d9c98f95eeb235ad Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 9 Sep 2013 23:02:25 -0700
            Subject: pom.xml
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index faf3ac1..4d6b858 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -137,7 +137,7 @@
                       
                         com.beust
                         jcommander
            -            1.31-SNAPSHOT
            +            1.30
             
            -- 
            cgit v1.2.3
            
            
            From 58d47ed1cda61db4d1843cec2ced45578858d534 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 9 Sep 2013 23:03:49 -0700
            Subject: [maven-release-plugin] prepare release jcommander-1.32
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 4d6b858..516caf5 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.32-SNAPSHOT
            +  1.32
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From f3be8161a574aaea44a9d45888ed824937644424 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 9 Sep 2013 23:03:54 -0700
            Subject: [maven-release-plugin] prepare for next development iteration
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 516caf5..e5aff27 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.32
            +  1.33-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 89820cc701ca41c85e3b000939f649df0636e35b Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Thu, 28 Nov 2013 20:05:54 -0800
            Subject: Donations
            
            ---
             doc/index.html | 1 +
             1 file changed, 1 insertion(+)
            
            diff --git a/doc/index.html b/doc/index.html
            index ad3d051..6ed16c4 100644
            --- a/doc/index.html
            +++ b/doc/index.html
            @@ -30,6 +30,7 @@
                 
             

            JCommander

            Because life is too short to parse command line parameters

            +

            Donations welcome at 1BhLmUZnDtjtqNetjqjHW1onqdykJW7Bd2 -- cgit v1.2.3 From 3cadec1fcd0de5fcd095d97053d4638f8955ec58 Mon Sep 17 00:00:00 2001 From: David BRASSELY Date: Fri, 17 Jan 2014 09:31:14 +0100 Subject: Typo error in documentation --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index ad3d051..a92a969 100644 --- a/doc/index.html +++ b/doc/index.html @@ -200,7 +200,7 @@ For example, here is a converter that turns a string into a File:
             public class FileConverter implements IStringConverter<File> {
               @Override
            -  private File convert(String value) {
            +  public File convert(String value) {
                 return new File(value);
               }
             }
            -- 
            cgit v1.2.3
            
            
            From 04e646fe260cced3e41c20c7807a7af7207ea32f Mon Sep 17 00:00:00 2001
            From: Andy Law 
            Date: Mon, 17 Feb 2014 11:40:19 +0000
            Subject: Fixed problem whereby Parameters returning Lists and with alternate
             names were being reset on the first use of an alternate name. Added test to
             ensure correct behaviour.
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java |  4 +--
             .../java/com/beust/jcommander/JCommanderTest.java  | 30 ++++++++++++++++++++++
             .../jcommander/args/AlternateNamesForListArgs.java | 30 ++++++++++++++++++++++
             3 files changed, 62 insertions(+), 2 deletions(-)
             create mode 100644 src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index b78d890..a763bc1 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -544,13 +544,13 @@ public class JCommander {
                       m_mainParameterDescription =
                           new ParameterDescription(object, p, parameterized, m_bundle, this);
                     } else {
            +          ParameterDescription pd =
            +              new ParameterDescription(object, p, parameterized, m_bundle, this);
                       for (String name : p.names()) {
                         if (m_descriptions.containsKey(new StringKey(name))) {
                           throw new ParameterException("Found the option " + name + " multiple times");
                         }
                         p("Adding description for " + name);
            -            ParameterDescription pd =
            -                new ParameterDescription(object, p, parameterized, m_bundle, this);
                         m_fields.put(parameterized, pd);
                         m_descriptions.put(new StringKey(name), pd);
             
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 356d442..be9a7ea 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -18,6 +18,7 @@
             
             package com.beust.jcommander;
             
            +import com.beust.jcommander.args.AlternateNamesForListArgs;
             import java.io.ByteArrayInputStream;
             import java.io.File;
             import java.io.FileWriter;
            @@ -96,6 +97,35 @@ public class JCommanderTest {
                 Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26"));
               }
             
            +  @DataProvider
            +  public Object[][] alternateNamesListArgs() {
            +    return new Object[][] {
            +        new String[][] {new String[] {"--servers", "1", "-s", "2", "--servers", "3"}},
            +        new String[][] {new String[] {"-s", "1", "-s", "2", "--servers", "3"}},
            +        new String[][] {new String[] {"--servers", "1", "--servers", "2", "-s", "3"}},
            +        new String[][] {new String[] {"-s", "1", "--servers", "2", "-s", "3"}},
            +        new String[][] {new String[] {"-s", "1", "-s", "2", "--servers", "3"}},
            +    };
            +  }
            +  
            +  /**
            +   *  Confirm that List parameters with alternate names return the correct
            +   * List regardless of how the arguments are specified
            +   */
            +  
            +  @Test(dataProvider = "alternateNamesListArgs")
            +  public void testAlternateNamesForListArguments(String[] argv) {
            +      AlternateNamesForListArgs args = new AlternateNamesForListArgs();
            +      
            +      new JCommander(args, argv);
            +      
            +      Assert.assertEquals(args.serverNames.size(), 3);
            +      Assert.assertEquals(args.serverNames.get(0), argv[1]);
            +      Assert.assertEquals(args.serverNames.get(1), argv[3]);
            +      Assert.assertEquals(args.serverNames.get(2), argv[5]);
            +  }
            +  
            +  
               /**
                * Make sure that if there are args with multiple names (e.g. "-log" and "-verbose"),
                * the usage will only display it once.
            diff --git a/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java b/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java
            new file mode 100644
            index 0000000..cf05bd3
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java
            @@ -0,0 +1,30 @@
            +/*
            + * Copyright 2014 alaw3.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *      http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +package com.beust.jcommander.args;
            +
            +import com.beust.jcommander.Parameter;
            +import com.beust.jcommander.internal.Lists;
            +import java.util.List;
            +
            +/**
            + *
            + * @author alaw3
            + */
            +public class AlternateNamesForListArgs {
            +
            +    @Parameter(names = {"-s", "--servers"}, description = "blah")
            +    public List serverNames = Lists.newLinkedList();
            +}
            -- 
            cgit v1.2.3
            
            
            From 2a4eef24e7c309e8fc69ccb7d7e3fd08681635d8 Mon Sep 17 00:00:00 2001
            From: Andy Law 
            Date: Mon, 17 Feb 2014 11:46:16 +0000
            Subject: Fixed the copyright notice in the test class file
            
            ---
             .../java/com/beust/jcommander/args/AlternateNamesForListArgs.java   | 6 ++++--
             1 file changed, 4 insertions(+), 2 deletions(-)
            
            diff --git a/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java b/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java
            index cf05bd3..18a1655 100644
            --- a/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java
            +++ b/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java
            @@ -1,5 +1,7 @@
             /*
            - * Copyright 2014 alaw3.
            + * Copyright (C) 2014 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
              *
              * Licensed under the Apache License, Version 2.0 (the "License");
              * you may not use this file except in compliance with the License.
            @@ -21,7 +23,7 @@ import java.util.List;
             
             /**
              *
            - * @author alaw3
            + * @author Andy Law 
              */
             public class AlternateNamesForListArgs {
             
            -- 
            cgit v1.2.3
            
            
            From acdb150baf44fc8c697da731f6b78fd7955b6d70 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 22 Feb 2014 09:10:14 -0800
            Subject: Preparing next release.
            
            ---
             build-with-maven | 2 +-
             pom.xml          | 2 +-
             2 files changed, 2 insertions(+), 2 deletions(-)
            
            diff --git a/build-with-maven b/build-with-maven
            index 41aef5a..176ca1a 100755
            --- a/build-with-maven
            +++ b/build-with-maven
            @@ -2,7 +2,7 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign
             
             
             #v=6.5.2beta
            -export TESTNG=`echo ../testng/target/testng-6.8.7.jar`
            +export TESTNG=`echo ../testng/target/testng-6.9beta.jar`
             
             run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml"
             echo "Launching tests: ${run}"
            diff --git a/pom.xml b/pom.xml
            index e5aff27..39b8a64 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.33-SNAPSHOT
            +  1.34-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 0b9a5702c9add87c720f4d7ae91fe44da47daaf7 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 22 Feb 2014 09:24:05 -0800
            Subject: [maven-release-plugin] prepare release jcommander-1.34
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 39b8a64..8dc53e6 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.34-SNAPSHOT
            +  1.34
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 996047c26782cb9660190550685b31b98e47e135 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 22 Feb 2014 09:24:10 -0800
            Subject: [maven-release-plugin] prepare for next development iteration
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 8dc53e6..420c117 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.34
            +  1.35-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 480c8c2f75dcdae83685bcb146c947868ca660bf Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 22 Feb 2014 09:29:41 -0800
            Subject: [maven-release-plugin] prepare release jcommander-1.35
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index 420c117..a7863fd 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.35-SNAPSHOT
            +  1.35
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From ecd7bf5ed8717a2b04240e7eb44d887f485d0bf2 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Sat, 22 Feb 2014 09:29:46 -0800
            Subject: [maven-release-plugin] prepare for next development iteration
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index a7863fd..2d5ff92 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.35
            +  1.36-SNAPSHOT
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From aa87f5891a77dffdf24bc4fb1f766ec976b064c1 Mon Sep 17 00:00:00 2001
            From: Yannick Menager 
            Date: Thu, 27 Feb 2014 14:22:28 +0000
            Subject: Fixes #184 Bug in enum parsing
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java     |  5 ++---
             src/test/java/com/beust/jcommander/JCommanderTest.java | 12 ++++++++++--
             2 files changed, 12 insertions(+), 5 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index a763bc1..08efd8b 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -1256,9 +1256,8 @@ public class JCommander {
                   if (converterClass != null && converterClass.isEnum()) {
                     try {
                       result = Enum.valueOf((Class) converterClass, value);
            -          if (result == null) {
            -            result = Enum.valueOf((Class) converterClass, value.toUpperCase());
            -          }
            +        } catch ( IllegalArgumentException e ) {
            +          result = Enum.valueOf((Class) converterClass, value.toUpperCase());
                     } catch (Exception e) {
                       throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" +
                                                    EnumSet.allOf((Class) converterClass));
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index be9a7ea..63964ae 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -596,12 +596,20 @@ public class JCommanderTest {
                 JCommander jc = new JCommander(args, argv);
             
                 Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE);
            -    
            +
                 List expected = Arrays.asList(ChoiceType.ONE, ChoiceType.Two);
                 Assert.assertEquals(expected, args.choices);
                 Assert.assertEquals(jc.getParameters().get(0).getDescription(),
                     "Options: " + EnumSet.allOf((Class) ArgsEnum.ChoiceType.class));
            -    
            +
            +  }
            +
            +  public void enumArgsCaseInsensitive() {
            +      ArgsEnum args = new ArgsEnum();
            +      String[] argv = { "-choice", "one"};
            +      JCommander jc = new JCommander(args, argv);
            +
            +      Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE);
               }
             
               @Test(expectedExceptions = ParameterException.class)
            -- 
            cgit v1.2.3
            
            
            From 7c5bf86fc5d5e85d471e3722a39b7a21101b0484 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 7 Apr 2014 22:24:08 -0700
            Subject: Support for "--".
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java |  5 +++-
             .../java/com/beust/jcommander/JCommanderTest.java  | 30 ++++++++++------------
             2 files changed, 17 insertions(+), 18 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 08efd8b..3884976 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -685,7 +685,7 @@ public class JCommander {
             
                   JCommander jc = findCommandByAlias(arg);
                   int increment = 1;
            -      if (isOption(args, a) && jc == null) {
            +      if (! "--".equals(a) && isOption(args, a) && jc == null) {
                     //
                     // Option
                     //
            @@ -744,6 +744,9 @@ public class JCommander {
                     // Main parameter
                     //
                     if (! Strings.isStringEmpty(arg)) {
            +          if ("--".equals(arg)) {
            +              a = trim(args[++i]);
            +          }
                       if (m_commands.isEmpty()) {
                         //
                         // Regular (non-command) parsing
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 63964ae..978f0d6 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -18,7 +18,6 @@
             
             package com.beust.jcommander;
             
            -import com.beust.jcommander.args.AlternateNamesForListArgs;
             import java.io.ByteArrayInputStream;
             import java.io.File;
             import java.io.FileWriter;
            @@ -41,6 +40,7 @@ import org.testng.Assert;
             import org.testng.annotations.DataProvider;
             import org.testng.annotations.Test;
             
            +import com.beust.jcommander.args.AlternateNamesForListArgs;
             import com.beust.jcommander.args.Args1;
             import com.beust.jcommander.args.Args1Setter;
             import com.beust.jcommander.args.Args2;
            @@ -1015,31 +1015,27 @@ public class JCommanderTest {
                 Assert.assertEquals(a.endpoint, Lists.newArrayList("dev"));
               }
             
            -  public void a() {
            +  public void dashDashParameter() {
                 class Arguments {
            -        @Parameter(names = { "-help", "-h" }, arity = 0, description = "Show this help message")
            -        public Boolean help = false;
            -        
            -        @Parameter(names = { "-verbose", "-v" }, arity = 0, description = "Verbose output mode")
            -        public Boolean verbose = false;
            -        
            -        @Parameter(names = { "-target" }, arity = 1, description = "Target directory", required = true)
            -        public File target;
            -        
            -        @Parameter(names = { "-input" }, variableArity = true, description = "Input paths", required = true)
            -        public List paths;
            +        @Parameter(names = { "-name" })
            +        public String name;
            +        @Parameter
            +        public List mainParameters;
                 }
            +
                 Arguments a = new Arguments();
                 new JCommander(a, new String[] {
            -        "-input", "example_in1", "example_in2", "-target", "example_out" }
            +        "-name", "theName", "--", "param1", "param2"}
                 );
            -    Assert.assertEquals(a.paths, Lists.newArrayList("example_in1", "example_in2"));
            -    Assert.assertEquals(a.target, new File("example_out"));
            +    Assert.assertEquals(a.name, "theName");
            +    Assert.assertEquals(a.mainParameters.size(), 2);
            +    Assert.assertEquals(a.mainParameters.get(0), "param1");
            +    Assert.assertEquals(a.mainParameters.get(1), "param2");
               }
             
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
            -    new JCommanderTest().a();
            +//    new JCommanderTest().a();
             //    class A {
             //      @Parameter(names = "-short", required = true)
             //      List parameters;
            -- 
            cgit v1.2.3
            
            
            From df883e8495e143f92d363225e48b45a81cf449fd Mon Sep 17 00:00:00 2001
            From: Mike Drob 
            Date: Thu, 10 Apr 2014 14:38:57 -0400
            Subject: Added another test for using '--'
            
            ---
             .../java/com/beust/jcommander/JCommanderTest.java    | 20 ++++++++++++++++++++
             1 file changed, 20 insertions(+)
            
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index 978f0d6..c61980a 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -1033,6 +1033,26 @@ public class JCommanderTest {
                 Assert.assertEquals(a.mainParameters.get(1), "param2");
               }
             
            +  public void dashDashParameter2() {
            +    class Arguments {
            +        @Parameter(names = { "-name" })
            +        public String name;
            +        @Parameter
            +        public List mainParameters;
            +    }
            +
            +    Arguments a = new Arguments();
            +    new JCommander(a, new String[] {
            +        "param1", "param2", "--", "-name", "theName"}
            +    );
            +    Assert.assertNull(a.name);
            +    Assert.assertEquals(a.mainParameters.size(), 4);
            +    Assert.assertEquals(a.mainParameters.get(0), "param1");
            +    Assert.assertEquals(a.mainParameters.get(1), "param2");
            +    Assert.assertEquals(a.mainParameters.get(2), "-name");
            +    Assert.assertEquals(a.mainParameters.get(3), "theName");
            +  }
            +
               @Test(enabled = false)
               public static void main(String[] args) throws Exception {
             //    new JCommanderTest().a();
            -- 
            cgit v1.2.3
            
            
            From a944e2290d2ced9e3615892695754424197d93b7 Mon Sep 17 00:00:00 2001
            From: Mike Drob 
            Date: Thu, 10 Apr 2014 14:52:14 -0400
            Subject: Broke parsing of --
            
            ---
             src/test/java/com/beust/jcommander/JCommanderTest.java | 9 +++++----
             1 file changed, 5 insertions(+), 4 deletions(-)
            
            diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
            index c61980a..342b858 100644
            --- a/src/test/java/com/beust/jcommander/JCommanderTest.java
            +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
            @@ -1043,14 +1043,15 @@ public class JCommanderTest {
             
                 Arguments a = new Arguments();
                 new JCommander(a, new String[] {
            -        "param1", "param2", "--", "-name", "theName"}
            +        "param1", "param2", "--", "param3", "-name", "theName"}
                 );
                 Assert.assertNull(a.name);
            -    Assert.assertEquals(a.mainParameters.size(), 4);
            +    Assert.assertEquals(a.mainParameters.size(), 5);
                 Assert.assertEquals(a.mainParameters.get(0), "param1");
                 Assert.assertEquals(a.mainParameters.get(1), "param2");
            -    Assert.assertEquals(a.mainParameters.get(2), "-name");
            -    Assert.assertEquals(a.mainParameters.get(3), "theName");
            +    Assert.assertEquals(a.mainParameters.get(2), "param3");
            +    Assert.assertEquals(a.mainParameters.get(3), "-name");
            +    Assert.assertEquals(a.mainParameters.get(4), "theName");
               }
             
               @Test(enabled = false)
            -- 
            cgit v1.2.3
            
            
            From d9bec530f2d1c83289e8f325b33940cafce6b6c2 Mon Sep 17 00:00:00 2001
            From: Sam Vervaeck 
            Date: Sat, 17 May 2014 22:53:59 +0200
            Subject: Added support for URL parameters
            
            ---
             .../beust/jcommander/converters/URLConverter.java  | 46 ++++++++++++++++++++++
             .../com/beust/jcommander/args/ArgsConverter.java   |  7 +++-
             2 files changed, 52 insertions(+), 1 deletion(-)
             create mode 100644 src/main/java/com/beust/jcommander/converters/URLConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/converters/URLConverter.java b/src/main/java/com/beust/jcommander/converters/URLConverter.java
            new file mode 100644
            index 0000000..1f3734b
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/URLConverter.java
            @@ -0,0 +1,46 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +
            +import java.net.MalformedURLException;
            +import java.net.URL;
            +
            +/**
            + * Convert a string into a URI.
            + * 
            + * @author samvv
            + */
            +public class URLConverter extends BaseConverter {
            +
            +	public URLConverter(String optionName) {
            +		super(optionName);
            +	}
            +
            +	public URL convert(String value) {
            +		try {
            +			return new URL(value);
            +		} catch (MalformedURLException e) {
            +			throw new ParameterException(
            +					getErrorString(value, "a RFC 2396 and RFC 2732 compliant URL"));
            +			
            +		}
            +	}
            +}
            \ No newline at end of file
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            index 159ed78..c33475c 100644
            --- a/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            @@ -23,13 +23,17 @@ import com.beust.jcommander.converters.FileConverter;
             
             import java.io.File;
             import java.math.BigDecimal;
            +import java.net.URI;
             import java.util.List;
             
             public class ArgsConverter {
             
               @Parameter(names = "-file", converter = FileConverter.class)
               public File file;
            -
            +  
            +//  @Parameter(names = "-uri")
            +//  public URI uri;
            +  
               @Parameter(names = "-listStrings")
               public List listStrings;
             
            @@ -38,4 +42,5 @@ public class ArgsConverter {
             
               @Parameter(names = "-listBigDecimals")
               public List listBigDecimals;
            +  
             }
            -- 
            cgit v1.2.3
            
            
            From 495398d07b80ba24b6a1eaff0f0c973d4a295dcc Mon Sep 17 00:00:00 2001
            From: Sam Vervaeck 
            Date: Sat, 17 May 2014 22:57:11 +0200
            Subject: Added support for URI parameters
            
            ---
             .../beust/jcommander/converters/URIConverter.java  | 46 ++++++++++++++++++++++
             .../com/beust/jcommander/args/ArgsConverter.java   | 10 ++++-
             2 files changed, 54 insertions(+), 2 deletions(-)
             create mode 100644 src/main/java/com/beust/jcommander/converters/URIConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/converters/URIConverter.java b/src/main/java/com/beust/jcommander/converters/URIConverter.java
            new file mode 100644
            index 0000000..82f6ace
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/URIConverter.java
            @@ -0,0 +1,46 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.ParameterException;
            +
            +import java.net.URI;
            +import java.net.URISyntaxException;
            +
            +/**
            + * Convert a string into a URI.
            + * 
            + * @author samvv
            + */
            +public class URIConverter extends BaseConverter {
            +
            +	public URIConverter(String optionName) {
            +		super(optionName);
            +	}
            +
            +	public URI convert(String value) {
            +		try {
            +			return new URI(value);
            +		} catch (URISyntaxException e) {
            +			throw new ParameterException(
            +					getErrorString(value, "a RFC 2396 and RFC 2732 compliant URI"));
            +		}
            +	}
            +
            +}
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            index c33475c..315abdc 100644
            --- a/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            @@ -20,10 +20,13 @@ package com.beust.jcommander.args;
             
             import com.beust.jcommander.Parameter;
             import com.beust.jcommander.converters.FileConverter;
            +import com.beust.jcommander.converters.URIConverter;
            +import com.beust.jcommander.converters.URLConverter;
             
             import java.io.File;
             import java.math.BigDecimal;
             import java.net.URI;
            +import java.net.URL;
             import java.util.List;
             
             public class ArgsConverter {
            @@ -31,8 +34,11 @@ public class ArgsConverter {
               @Parameter(names = "-file", converter = FileConverter.class)
               public File file;
               
            -//  @Parameter(names = "-uri")
            -//  public URI uri;
            +  @Parameter(names = "-url", converter = URLConverter.class)
            +  public URL url;
            +  
            +  @Parameter(names = "-uri", converter = URIConverter.class)
            +  public URI uri;
               
               @Parameter(names = "-listStrings")
               public List listStrings;
            -- 
            cgit v1.2.3
            
            
            From 3899d473faed68a3d308336d213626dffaa030e7 Mon Sep 17 00:00:00 2001
            From: Sam Vervaeck 
            Date: Sat, 17 May 2014 22:58:37 +0200
            Subject: Added support for Java NIO Paths
            
            ---
             .../beust/jcommander/converters/PathConverter.java | 37 ++++++++++++++++++++++
             .../com/beust/jcommander/args/ArgsConverter.java   |  5 +++
             2 files changed, 42 insertions(+)
             create mode 100644 src/main/java/com/beust/jcommander/converters/PathConverter.java
            
            diff --git a/src/main/java/com/beust/jcommander/converters/PathConverter.java b/src/main/java/com/beust/jcommander/converters/PathConverter.java
            new file mode 100644
            index 0000000..dcd5b43
            --- /dev/null
            +++ b/src/main/java/com/beust/jcommander/converters/PathConverter.java
            @@ -0,0 +1,37 @@
            +/**
            + * Copyright (C) 2010 the original author or authors.
            + * See the notice.md file distributed with this work for additional
            + * information regarding copyright ownership.
            + *
            + * Licensed under the Apache License, Version 2.0 (the "License");
            + * you may not use this file except in compliance with the License.
            + * You may obtain a copy of the License at
            + *
            + *     http://www.apache.org/licenses/LICENSE-2.0
            + *
            + * Unless required by applicable law or agreed to in writing, software
            + * distributed under the License is distributed on an "AS IS" BASIS,
            + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            + * See the License for the specific language governing permissions and
            + * limitations under the License.
            + */
            +
            +package com.beust.jcommander.converters;
            +
            +import com.beust.jcommander.IStringConverter;
            +
            +import java.nio.file.Path;
            +import java.nio.file.Paths;
            +
            +/**
            + * Convert a string into a path.
            + * 
            + * @author samvv
            + */
            +public class PathConverter implements IStringConverter {
            +
            +  public Path convert(String value) {
            +    return Paths.get(value);
            +  }
            +
            +}
            diff --git a/src/test/java/com/beust/jcommander/args/ArgsConverter.java b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            index 315abdc..677cf9b 100644
            --- a/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            +++ b/src/test/java/com/beust/jcommander/args/ArgsConverter.java
            @@ -20,6 +20,7 @@ package com.beust.jcommander.args;
             
             import com.beust.jcommander.Parameter;
             import com.beust.jcommander.converters.FileConverter;
            +import com.beust.jcommander.converters.PathConverter;
             import com.beust.jcommander.converters.URIConverter;
             import com.beust.jcommander.converters.URLConverter;
             
            @@ -27,6 +28,7 @@ import java.io.File;
             import java.math.BigDecimal;
             import java.net.URI;
             import java.net.URL;
            +import java.nio.file.Path;
             import java.util.List;
             
             public class ArgsConverter {
            @@ -40,6 +42,9 @@ public class ArgsConverter {
               @Parameter(names = "-uri", converter = URIConverter.class)
               public URI uri;
               
            +  @Parameter(names = "-path", converter = PathConverter.class)
            +  public Path path;
            +  
               @Parameter(names = "-listStrings")
               public List listStrings;
             
            -- 
            cgit v1.2.3
            
            
            From b55abbbe352028c09c37f0c37a9f4dfa099838b5 Mon Sep 17 00:00:00 2001
            From: Sam Vervaeck 
            Date: Sat, 17 May 2014 23:13:55 +0200
            Subject: Aligned indentation with rest of the code
            
            ---
             .../beust/jcommander/converters/PathConverter.java |  4 ++--
             .../beust/jcommander/converters/URIConverter.java  | 27 +++++++++++-----------
             2 files changed, 15 insertions(+), 16 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/converters/PathConverter.java b/src/main/java/com/beust/jcommander/converters/PathConverter.java
            index dcd5b43..b7fdafd 100644
            --- a/src/main/java/com/beust/jcommander/converters/PathConverter.java
            +++ b/src/main/java/com/beust/jcommander/converters/PathConverter.java
            @@ -29,9 +29,9 @@ import java.nio.file.Paths;
              * @author samvv
              */
             public class PathConverter implements IStringConverter {
            -
            +  
               public Path convert(String value) {
                 return Paths.get(value);
               }
            -
            +  
             }
            diff --git a/src/main/java/com/beust/jcommander/converters/URIConverter.java b/src/main/java/com/beust/jcommander/converters/URIConverter.java
            index 82f6ace..3473bf0 100644
            --- a/src/main/java/com/beust/jcommander/converters/URIConverter.java
            +++ b/src/main/java/com/beust/jcommander/converters/URIConverter.java
            @@ -29,18 +29,17 @@ import java.net.URISyntaxException;
              * @author samvv
              */
             public class URIConverter extends BaseConverter {
            -
            -	public URIConverter(String optionName) {
            -		super(optionName);
            -	}
            -
            -	public URI convert(String value) {
            -		try {
            -			return new URI(value);
            -		} catch (URISyntaxException e) {
            -			throw new ParameterException(
            -					getErrorString(value, "a RFC 2396 and RFC 2732 compliant URI"));
            -		}
            -	}
            -
            +  
            +  public URIConverter(String optionName) {
            +    super(optionName);
            +  }
            +  
            +  public URI convert(String value) {
            +    try {
            +      return new URI(value);
            +    } catch (URISyntaxException e) {
            +      throw new ParameterException(getErrorString(value, "a RFC 2396 and RFC 2732 compliant URI"));
            +    }
            +  }
            +  
             }
            -- 
            cgit v1.2.3
            
            
            From 44ef916dcf74e46adbf7c2ae99643bd0e97c16e6 Mon Sep 17 00:00:00 2001
            From: John Conwell 
            Date: Fri, 6 Jun 2014 19:00:27 -0700
            Subject: Adding functionality that allows commands to be hidden from usage
             output
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java | 18 +++++++++++-------
             src/main/java/com/beust/jcommander/Parameters.java |  5 +++++
             .../beust/jcommander/command/CommandHidden.java    | 17 +++++++++++++++++
             .../com/beust/jcommander/command/CommandTest.java  | 22 ++++++++++++++++++++++
             4 files changed, 55 insertions(+), 7 deletions(-)
             create mode 100644 src/test/java/com/beust/jcommander/command/CommandHidden.java
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 3884976..5538661 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -1119,13 +1119,17 @@ public class JCommander {
                   // The magic value 3 is the number of spaces between the name of the option
                   // and its description
                   for (Map.Entry commands : m_commands.entrySet()) {
            -        ProgramName progName = commands.getKey();
            -        String dispName = progName.getDisplayName();
            -        out.append(indent).append("    " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n");
            -
            -        // Options for this command
            -        usage(progName.getName(), out, "      ");
            -        out.append("\n");
            +        Object arg = commands.getValue().getObjects().get(0);
            +        Parameters p = arg.getClass().getAnnotation(Parameters.class);
            +        if (!p.hidden()) {
            +          ProgramName progName = commands.getKey();
            +          String dispName = progName.getDisplayName();
            +          out.append(indent).append("    " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n");
            +
            +          // Options for this command
            +          usage(progName.getName(), out, "      ");
            +          out.append("\n");
            +        }
                   }
                 }
               }
            diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java
            index 9834ea0..f2e8c76 100644
            --- a/src/main/java/com/beust/jcommander/Parameters.java
            +++ b/src/main/java/com/beust/jcommander/Parameters.java
            @@ -67,4 +67,9 @@ public @interface Parameters {
                * An array of allowed command names.
                */
               String[] commandNames() default {};
            +
            +  /**
            +   * If true, this command won't appear in the usage().
            +   */
            +  boolean hidden() default false;
             }
            diff --git a/src/test/java/com/beust/jcommander/command/CommandHidden.java b/src/test/java/com/beust/jcommander/command/CommandHidden.java
            new file mode 100644
            index 0000000..a3fc4fa
            --- /dev/null
            +++ b/src/test/java/com/beust/jcommander/command/CommandHidden.java
            @@ -0,0 +1,17 @@
            +package com.beust.jcommander.command;
            +
            +import com.beust.jcommander.Parameter;
            +import com.beust.jcommander.Parameters;
            +
            +import java.util.List;
            +
            +@Parameters(commandNames = "add", commandDescription = "Hidden command to add file contents to the index", hidden = true)
            +public class CommandHidden {
            +
            +    @Parameter(description = "Patterns of files to be added")
            +    public List patterns;
            +
            +    @Parameter(names = "-i")
            +    public Boolean interactive = false;
            +
            +}
            diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java
            index 97e0007..cf921bd 100644
            --- a/src/test/java/com/beust/jcommander/command/CommandTest.java
            +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java
            @@ -87,6 +87,28 @@ public class CommandTest {
                 Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java"));
               }
             
            +    @Test
            +    public void hiddenCommandTest() {
            +        CommandMain cm = new CommandMain();
            +        JCommander jc = new JCommander(cm);
            +        CommandAdd add = new CommandAdd();
            +        jc.addCommand("add", add);
            +        CommandHidden hidden = new CommandHidden();
            +        jc.addCommand("hidden", hidden);
            +        jc.parse("hidden", "-i", "A.java");
            +
            +        Assert.assertEquals(jc.getParsedCommand(), "hidden");
            +        Assert.assertEquals(hidden.interactive.booleanValue(), true);
            +        Assert.assertEquals(hidden.patterns, Arrays.asList("A.java"));
            +
            +        jc.setProgramName("TestCommander");
            +        StringBuilder out = new StringBuilder();
            +        jc.usage(out);
            +
            +        Assert.assertTrue(out.toString().contains("add      Add file contents to the index"));
            +        Assert.assertFalse(out.toString().contains("hidden      Hidden command to add file contents to the index"));
            +    }
            +
               public static void main(String[] args) {
                 new CommandTest().shouldComplainIfNoAnnotations();
               }
            -- 
            cgit v1.2.3
            
            
            From 55e9949641d8906e622ea92f40ac1138ae74a30c Mon Sep 17 00:00:00 2001
            From: helllth 
            Date: Tue, 22 Jul 2014 13:41:46 +0200
            Subject: add the possibility to have # comments in a @file
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java | 6 ++++--
             1 file changed, 4 insertions(+), 2 deletions(-)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 3884976..f4a29e5 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -485,8 +485,10 @@ public class JCommander {
             
                   // Read through file one line at time. Print line # and line
                   while ((line = bufRead.readLine()) != null) {
            -        // Allow empty lines in these at files
            -        if (line.length() > 0) result.add(line);
            +        // Allow empty lines and # comments in these at files
            +        if (line.length() > 0 && ! line.trim().startsWith("#")) {
            +            result.add(line);
            +        }
                   }
             
                   bufRead.close();
            -- 
            cgit v1.2.3
            
            
            From 9d7035d4d9145090a0d20869963e23014b835577 Mon Sep 17 00:00:00 2001
            From: helllth 
            Date: Tue, 22 Jul 2014 16:13:01 +0200
            Subject: add possibility to allow parameter overwriting (and even disallowing
             it for certain parameters)
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java           | 7 +++++++
             src/main/java/com/beust/jcommander/Parameter.java            | 8 ++++++++
             src/main/java/com/beust/jcommander/ParameterDescription.java | 6 +++++-
             src/main/java/com/beust/jcommander/WrappedParameter.java     | 3 +++
             4 files changed, 23 insertions(+), 1 deletion(-)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index f4a29e5..04f98ba 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -154,6 +154,7 @@ public class JCommander {
             
               private List m_unknownArgs = Lists.newArrayList();
               private boolean m_acceptUnknownOptions = false;
            +  private boolean m_allowParameterOverwriting = false;
               
               private static Console m_console;
             
            @@ -1567,7 +1568,13 @@ public class JCommander {
               public List getUnknownOptions() {
                 return m_unknownArgs;
               }
            +  public void setAllowParameterOverwriting(boolean b) {
            +    m_allowParameterOverwriting = b;
            +  }
             
            +  public boolean isParameterOverwritingAllowed() {
            +    return m_allowParameterOverwriting;
            +  }
             //  public void setCaseSensitiveCommands(boolean b) {
             //    m_caseSensitiveCommands = b;
             //  }
            diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java
            index 974eeaa..d8cf87d 100644
            --- a/src/main/java/com/beust/jcommander/Parameter.java
            +++ b/src/main/java/com/beust/jcommander/Parameter.java
            @@ -119,4 +119,12 @@ public @interface Parameter {
                * required parameters are no longer checked for their presence.
                */
               boolean help() default false;
            +  
            +  /**
            +   * If true, this parameter can be overwritten through a file or another appearance of the parameter
            +   * @return 
            +   */
            +  boolean forceNonOverwritable() default false;
            +
            +  
             }
            diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
            index 33574a9..e41c782 100644
            --- a/src/main/java/com/beust/jcommander/ParameterDescription.java
            +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
            @@ -231,7 +231,7 @@ public class ParameterDescription {
                 p("Adding " + (isDefault ? "default " : "") + "value:" + value
                     + " to parameter:" + m_parameterized.getName());
                 String name = m_wrappedParameter.names()[0];
            -    if (m_assigned && ! isMultiOption()) {
            +    if (m_assigned && ! isMultiOption() && !m_jCommander.isParameterOverwritingAllowed() || isNonOverwritableForced()) {
                   throw new ParameterException("Can only specify option " + name + " once.");
                 }
             
            @@ -358,4 +358,8 @@ public class ParameterDescription {
               public boolean isHelp() {
                 return m_wrappedParameter.isHelp();
               }
            +  
            +  public boolean isNonOverwritableForced() {
            +    return m_wrappedParameter.isNonOverwritableForced();
            +  }
             }
            diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java
            index 52cafc4..f4e7d56 100644
            --- a/src/main/java/com/beust/jcommander/WrappedParameter.java
            +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java
            @@ -109,4 +109,7 @@ public class WrappedParameter {
                 return m_parameter != null && m_parameter.help();
               }
             
            +  public boolean isNonOverwritableForced() {
            +      return m_parameter != null && m_parameter.forceNonOverwritable();
            +  }
             }
            -- 
            cgit v1.2.3
            
            
            From 2a1c82bf728a011697991e990c761914446a1517 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Mon, 4 Aug 2014 10:19:21 -0400
            Subject: Doc update
            
            ---
             doc/index.html | 15 ++++++++++++++-
             1 file changed, 14 insertions(+), 1 deletion(-)
            
            diff --git a/doc/index.html b/doc/index.html
            index a92a969..8ee8880 100644
            --- a/doc/index.html
            +++ b/doc/index.html
            @@ -30,6 +30,19 @@
                 
             

            JCommander

            Because life is too short to parse command line parameters

            +

            +
            + + + + + + + + + +
            +

            @@ -39,7 +52,7 @@ - Last updated: October 25th, 2012 + Last updated: August 2nd, 2014 Cédric Beust -- cgit v1.2.3 From 84d37323ff2416cf9a98dd96fab25f52eed1b516 Mon Sep 17 00:00:00 2001 From: chilinglam Date: Fri, 12 Sep 2014 13:58:23 -0400 Subject: propagate m_acceptUnknownOptions to addCommand --- src/main/java/com/beust/jcommander/JCommander.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index ecbb1cd..7f6638a 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1371,6 +1371,7 @@ public class JCommander { JCommander jc = new JCommander(object); jc.setProgramName(name, aliases); jc.setDefaultProvider(m_defaultProvider); + jc.setAcceptUnknownOptions(m_acceptUnknownOptions); ProgramName progName = jc.m_programName; m_commands.put(progName, jc); -- cgit v1.2.3 From e217da3bb340b5a319b79025fbb09f6207e5c3a2 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 14 Sep 2014 09:55:37 -0700 Subject: Fix --. --- src/main/java/com/beust/jcommander/JCommander.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 7f6638a..53246b3 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -680,6 +680,7 @@ public class JCommander { // object) boolean commandParsed = false; int i = 0; + boolean isDashDash = false; // once we encounter --, everything goes into the main parameter while (i < args.length && ! commandParsed) { String arg = args[i]; String a = trim(arg); @@ -688,7 +689,7 @@ public class JCommander { JCommander jc = findCommandByAlias(arg); int increment = 1; - if (! "--".equals(a) && isOption(args, a) && jc == null) { + if (! isDashDash && ! "--".equals(a) && isOption(args, a) && jc == null) { // // Option // @@ -748,6 +749,7 @@ public class JCommander { // if (! Strings.isStringEmpty(arg)) { if ("--".equals(arg)) { + isDashDash = true; a = trim(args[++i]); } if (m_commands.isEmpty()) { -- cgit v1.2.3 From 460b51f6319bb8b8c621fce06346eaab7902c9b8 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 14 Sep 2014 10:01:36 -0700 Subject: Fix enumArgsFail. --- src/main/java/com/beust/jcommander/JCommander.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 53246b3..98f112e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1268,11 +1268,16 @@ public class JCommander { if (converterClass != null && converterClass.isEnum()) { try { result = Enum.valueOf((Class) converterClass, value); - } catch ( IllegalArgumentException e ) { - result = Enum.valueOf((Class) converterClass, value.toUpperCase()); + } catch (IllegalArgumentException e) { + try { + result = Enum.valueOf((Class) converterClass, value.toUpperCase()); + } catch (IllegalArgumentException ex) { + throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" + + EnumSet.allOf((Class) converterClass)); + } } catch (Exception e) { throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" + - EnumSet.allOf((Class) converterClass)); + EnumSet.allOf((Class) converterClass)); } } else { converter = instantiateConverter(optionName, converterClass); -- cgit v1.2.3 From f5bc65089dc0a58c3855868c985f291b6e9e1afe Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:53:37 -0700 Subject: Preparing release. --- build-with-maven | 7 +++-- pom.xml | 35 +++++++++++++++++++++- .../java/com/beust/jcommander/JCommanderTest.java | 2 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/build-with-maven b/build-with-maven index 176ca1a..8323640 100755 --- a/build-with-maven +++ b/build-with-maven @@ -2,11 +2,12 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign #v=6.5.2beta -export TESTNG=`echo ../testng/target/testng-6.9beta.jar` +export TESTNG=`echo ../testng/target/testng-6.8.8.jar` -run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml" +run="java -classpath \"target/classes;target/test-classes;${TESTNG};$CLASSPATH\" org.testng.TestNG src/test/resources/testng.xml" echo "Launching tests: ${run}" -java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml +$run +#java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml echo "To deploy to the snapshot repository: mvn deploy" echo "To deploy to the release directory: mvn -DskipTests=true release:clean release:prepare release:perform" diff --git a/pom.xml b/pom.xml index 2d5ff92..5507f7b 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.36-SNAPSHOT + 1.37-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander @@ -155,6 +155,39 @@ + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.felix + + maven-bundle-plugin + + + [2.1.0,) + + + manifest + + + + + + + + + + + + diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 342b858..ad2c5e8 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -1056,7 +1056,7 @@ public class JCommanderTest { @Test(enabled = false) public static void main(String[] args) throws Exception { -// new JCommanderTest().a(); + new JCommanderTest().enumArgsFail(); // class A { // @Parameter(names = "-short", required = true) // List parameters; -- cgit v1.2.3 From 006e02166d976203b246f19cabbb2f918c20f726 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:54:15 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.37 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5507f7b..a9cc102 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.37-SNAPSHOT + 1.37 A Java framework to parse command line options with annotations. http://beust.com/jcommander @@ -179,7 +179,7 @@ - + -- cgit v1.2.3 From b2fd6c250e7ecc980fa3b9cfe8361df1e24f2b18 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:54:20 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a9cc102..2737641 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.37 + 1.38-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 780c8608bf7e0217881de793ebe6277de07517bf Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:57:47 -0700 Subject: Release. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2737641..7dd1def 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.38-SNAPSHOT + 1.39-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 9d79877f6794f9c4560523a87c8ef34f364b8747 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:58:53 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.39 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7dd1def..1106606 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.39-SNAPSHOT + 1.39 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 3aeccc940e59fc6be352c9d099bbb3cdeb6aad77 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:58:57 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1106606..f28dcf0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.39 + 1.40-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 85b0cd1344a5a89d44358bea3ade6bbc98ec49df Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 08:58:57 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1106606..6f2aa14 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.39 + 1.41-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From e37d58090d5132a803054776d28c7870cc75136c Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:04:28 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.41 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6f2aa14..48912e8 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.41-SNAPSHOT + 1.41 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 0c5c5e95cfd9b79a4c25a28387035675f4e6c347 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:05:34 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.42 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e6386cd..ed16c7f 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.42-SNAPSHOT + 1.42 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From b786cb2a331ba16013f8ee434b6e1e303f280cc0 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:05:38 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed16c7f..c376dfe 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.42 + 1.43-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From f4bb9297d94fa73000a7dd23cd8b63cf9b500430 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:12:45 -0700 Subject: Repo. --- pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pom.xml b/pom.xml index c376dfe..215c5f2 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,14 @@ git@github.com:cbeust/jcommander.git + + + nexus-site + Nexus Staging Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + Cedric Beust -- cgit v1.2.3 From db2b19345ec59075970bea733176dd4bf683efbb Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:12:45 -0700 Subject: Repo. --- pom.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c376dfe..dd22f35 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.43-SNAPSHOT + 1.43 A Java framework to parse command line options with annotations. http://beust.com/jcommander @@ -40,6 +40,14 @@ git@github.com:cbeust/jcommander.git + + + nexus-site + Nexus Staging Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + Cedric Beust -- cgit v1.2.3 From 9f224876ea601f99e57733f89502702e3cb05f91 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:16:06 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.44 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5a59454..f4e0069 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.44-SNAPSHOT + 1.44 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 9d95b9d5cc6cf6eaa33b4170779e2191f2baefd9 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Sun, 5 Oct 2014 09:16:11 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f4e0069..e7d15de 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.44 + 1.45-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 878419eb82d03e32325d0993f95a906244f7a507 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Oct 2014 09:08:43 -0700 Subject: [maven-release-plugin] prepare release jcommander-1.45 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e7d15de..88f7acf 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.45-SNAPSHOT + 1.45 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 6870ba8112fd649409bd92a5f3e01dc9bf82cc37 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Mon, 6 Oct 2014 09:08:47 -0700 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 88f7acf..5e7a470 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.45 + 1.46-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From fb7a1a73d02a75e62b85e86e8b592af57733a36e Mon Sep 17 00:00:00 2001 From: Manuel Boillod Date: Sun, 16 Nov 2014 16:24:27 +0100 Subject: fix for issue200 Incorrect usage() formatting with single long options --- src/main/java/com/beust/jcommander/ParameterDescription.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index e41c782..2ef2d5f 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -186,7 +186,6 @@ public class ParameterDescription { String[] names = m_wrappedParameter.names(); for (int i = 0; i < names.length; i++) { if (i > 0) sb.append(", "); - if (names.length == 1 && names[i].startsWith("--")) sb.append(" "); sb.append(names[i]); } return sb.toString(); -- cgit v1.2.3 From 34760d6eb0a7cdc73a4f57dc9dae30de4fe89199 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Dec 2014 11:35:42 -0800 Subject: Build script --- build-with-maven | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-with-maven b/build-with-maven index 8323640..0e2de5a 100755 --- a/build-with-maven +++ b/build-with-maven @@ -2,7 +2,7 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign #v=6.5.2beta -export TESTNG=`echo ../testng/target/testng-6.8.8.jar` +export TESTNG=`echo ../testng/target/testng-6.8.13.jar` run="java -classpath \"target/classes;target/test-classes;${TESTNG};$CLASSPATH\" org.testng.TestNG src/test/resources/testng.xml" echo "Launching tests: ${run}" -- cgit v1.2.3 From fe30bab3e38f9f7e10c24bcedddf201e4ff0598d Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Dec 2014 11:36:00 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.46 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e7a470..e6c8af6 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.46-SNAPSHOT + 1.46 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 1a568c9848848d6ae1292cfe1b55f96279d40db1 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Dec 2014 11:36:05 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e6c8af6..5b921c0 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.46 + 1.47-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 99236c731f5d35988700ae65787607283383ff6a Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Dec 2014 11:37:52 -0800 Subject: Updated Nexus site name --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5b921c0..9f80195 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ - nexus-site + sonatype-nexus-staging Nexus Staging Repository https://oss.sonatype.org/service/local/staging/deploy/maven2/ -- cgit v1.2.3 From 7e7bb2f4739057be398ff7f7eb64c456b834b508 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Dec 2014 11:38:05 -0800 Subject: [maven-release-plugin] prepare release jcommander-1.47 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9f80195..c1cec26 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.47-SNAPSHOT + 1.47 A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From 616b96d9b4aa42c74df70607b9ab388c469dc892 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 18 Dec 2014 11:38:08 -0800 Subject: [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c1cec26..cc70277 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ jcommander jar JCommander - 1.47 + 1.48-SNAPSHOT A Java framework to parse command line options with annotations. http://beust.com/jcommander -- cgit v1.2.3 From bb73fda634685379a8e99565f42b0ad47ac9bace Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jan 2015 15:45:07 -0800 Subject: Doc update. --- doc/index.html | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 8ee8880..6d67768 100644 --- a/doc/index.html +++ b/doc/index.html @@ -52,7 +52,7 @@ - Last updated: August 2nd, 2014 + Last updated: January 14th, 2015 Cédric Beust @@ -808,9 +808,25 @@ object Main { }
            +

            JCommander in Groovy

            + +
            +import com.beust.jcommander.*
            +
            +class Args {
            +  @Parameter(names = ["-f", "--file"], description = "File to load. Can be specified multiple times.")
            +  List<String> file
            +}
            +
            +new Args().with {
            +  new JCommander(it, args)
            +  file.each { println "file: ${new File(it).name}" }
            +}
            +
            +

            More examples

            -TestNG uses JCommander to parse its command line, here is its definition file. +TestNG uses JCommander to parse its own command line, here is its definition file.

            Mailing list

            -- cgit v1.2.3 From 6c86beb7fdc16a6b02ea5591e0fbc9d35a3a646e Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Wed, 14 Jan 2015 15:46:35 -0800 Subject: Doc. --- doc/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/index.html b/doc/index.html index 6d67768..da0368b 100644 --- a/doc/index.html +++ b/doc/index.html @@ -810,6 +810,9 @@ object Main {

            JCommander in Groovy

            +Here is a quick example of how to use JCommander in Groovy (courtesy of Paul King): + +
             import com.beust.jcommander.*
             
            -- 
            cgit v1.2.3
            
            
            From 495a006cacb2a62449b74474fc57ca2e1b37d85d Mon Sep 17 00:00:00 2001
            From: TKlerx 
            Date: Fri, 13 Mar 2015 10:01:51 +0100
            Subject: Added default converters for Path, URI and URL
            
            ---
             .../com/beust/jcommander/internal/DefaultConverterFactory.java   | 9 +++++++++
             1 file changed, 9 insertions(+)
            
            diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            index f98a111..2b8a10c 100644
            --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            @@ -29,10 +29,16 @@ import com.beust.jcommander.converters.ISO8601DateConverter;
             import com.beust.jcommander.converters.IntegerConverter;
             import com.beust.jcommander.converters.LongConverter;
             import com.beust.jcommander.converters.StringConverter;
            +import com.beust.jcommander.converters.PathConverter;
            +import com.beust.jcommander.converters.URIConverter;
            +import com.beust.jcommander.converters.URLConverter;
             
             import java.io.File;
             import java.math.BigDecimal;
             import java.util.Date;
            +import java.net.URI;
            +import java.net.URL;
            +import java.nio.file.Path;
             import java.util.Map;
             
             public class DefaultConverterFactory implements IStringConverterFactory {
            @@ -57,6 +63,9 @@ public class DefaultConverterFactory implements IStringConverterFactory {
                 m_classConverters.put(File.class, FileConverter.class);
                 m_classConverters.put(BigDecimal.class, BigDecimalConverter.class);
                 m_classConverters.put(Date.class, ISO8601DateConverter.class);
            +    m_classConverters.put(Path.class, PathConverter.class);
            +    m_classConverters.put(URI.class, URIConverter.class);
            +    m_classConverters.put(URL.class, URLConverter.class);
               }
             
               public Class> getConverter(Class forType) {
            -- 
            cgit v1.2.3
            
            
            From cea0c1642b084285d232968a701086267b4b3ec3 Mon Sep 17 00:00:00 2001
            From: TKlerx 
            Date: Fri, 13 Mar 2015 10:08:50 +0100
            Subject: Added enum constants to usage output
            
            ---
             src/main/java/com/beust/jcommander/JCommander.java | 5 +++++
             1 file changed, 5 insertions(+)
            
            diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
            index 98f112e..2e049a1 100644
            --- a/src/main/java/com/beust/jcommander/JCommander.java
            +++ b/src/main/java/com/beust/jcommander/JCommander.java
            @@ -1113,6 +1113,11 @@ public class JCommander {
                     out.append("\n" + s(indentCount + 1))
                         .append("Default: " + (parameter.password()?"********" : displayedDef));
                   }
            +      Class type =  pd.getParameterized().getType();
            +      if(type.isEnum()){
            +          out.append("\n" + s(indentCount + 1))
            +          .append("Possible Values: " + EnumSet.allOf((Class) type));
            +      }
                   out.append("\n");
                 }
             
            -- 
            cgit v1.2.3
            
            
            From e47fce5f08c9fc1214253d2bc4679da059d649b9 Mon Sep 17 00:00:00 2001
            From: Nikolay Martynov 
            Date: Thu, 9 Apr 2015 17:03:48 -0400
            Subject: Allow users to create ParameterException with description and cause
            
            This is useful in custom validators: it may want to provide both description
            and exception caused it. E.g. in case of file operations
            ---
             src/main/java/com/beust/jcommander/ParameterException.java | 4 ++++
             1 file changed, 4 insertions(+)
            
            diff --git a/src/main/java/com/beust/jcommander/ParameterException.java b/src/main/java/com/beust/jcommander/ParameterException.java
            index 3c0f588..2bba7d1 100644
            --- a/src/main/java/com/beust/jcommander/ParameterException.java
            +++ b/src/main/java/com/beust/jcommander/ParameterException.java
            @@ -34,5 +34,9 @@ public class ParameterException extends RuntimeException {
               public ParameterException(String string) {
                 super(string);
               }
            +  
            +  public ParameterException(String string, Throwable t) {
            +      super(string, t);
            +  }   
             
             }
            -- 
            cgit v1.2.3
            
            
            From 14fbe2bc5a2c402b456ed68578a5d5dc2c343fa2 Mon Sep 17 00:00:00 2001
            From: Cedric Beust 
            Date: Fri, 10 Apr 2015 19:45:40 -0700
            Subject: [maven-release-plugin] prepare release jcommander-1.48
            
            ---
             pom.xml | 2 +-
             1 file changed, 1 insertion(+), 1 deletion(-)
            
            diff --git a/pom.xml b/pom.xml
            index cc70277..1cedb33 100644
            --- a/pom.xml
            +++ b/pom.xml
            @@ -24,7 +24,7 @@
               jcommander
               jar
               JCommander
            -  1.48-SNAPSHOT
            +  1.48
               A Java framework to parse command line options with annotations.
               http://beust.com/jcommander
               
            -- 
            cgit v1.2.3
            
            
            From 62ca94818e9ed1bbd1fbac77eaa7376b054abe8c Mon Sep 17 00:00:00 2001
            From: Igor Murashkin 
            Date: Wed, 16 Mar 2016 13:42:23 -0700
            Subject: android: Add project metadata
            
            Bug: 27552463
            Change-Id: I71cff480c9b5fb813f3209cd6186e96b124f94ca
            ---
             MODULE_LICENSE_APACHE2 |   0
             NOTICE                 | 203 +++++++++++++++++++++++++++++++++++++++++++++++++
             README.version         |   4 +
             3 files changed, 207 insertions(+)
             create mode 100644 MODULE_LICENSE_APACHE2
             create mode 100755 NOTICE
             create mode 100644 README.version
            
            diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
            new file mode 100644
            index 0000000..e69de29
            diff --git a/NOTICE b/NOTICE
            new file mode 100755
            index 0000000..d0c18cf
            --- /dev/null
            +++ b/NOTICE
            @@ -0,0 +1,203 @@
            +
            +                                 Apache License
            +                           Version 2.0, January 2004
            +                        http://www.apache.org/licenses/
            +
            +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
            +
            +   1. Definitions.
            +
            +      "License" shall mean the terms and conditions for use, reproduction,
            +      and distribution as defined by Sections 1 through 9 of this document.
            +
            +      "Licensor" shall mean the copyright owner or entity authorized by
            +      the copyright owner that is granting the License.
            +
            +      "Legal Entity" shall mean the union of the acting entity and all
            +      other entities that control, are controlled by, or are under common
            +      control with that entity. For the purposes of this definition,
            +      "control" means (i) the power, direct or indirect, to cause the
            +      direction or management of such entity, whether by contract or
            +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
            +      outstanding shares, or (iii) beneficial ownership of such entity.
            +
            +      "You" (or "Your") shall mean an individual or Legal Entity
            +      exercising permissions granted by this License.
            +
            +      "Source" form shall mean the preferred form for making modifications,
            +      including but not limited to software source code, documentation
            +      source, and configuration files.
            +
            +      "Object" form shall mean any form resulting from mechanical
            +      transformation or translation of a Source form, including but
            +      not limited to compiled object code, generated documentation,
            +      and conversions to other media types.
            +
            +      "Work" shall mean the work of authorship, whether in Source or
            +      Object form, made available under the License, as indicated by a
            +      copyright notice that is included in or attached to the work
            +      (an example is provided in the Appendix below).
            +
            +      "Derivative Works" shall mean any work, whether in Source or Object
            +      form, that is based on (or derived from) the Work and for which the
            +      editorial revisions, annotations, elaborations, or other modifications
            +      represent, as a whole, an original work of authorship. For the purposes
            +      of this License, Derivative Works shall not include works that remain
            +      separable from, or merely link (or bind by name) to the interfaces of,
            +      the Work and Derivative Works thereof.
            +
            +      "Contribution" shall mean any work of authorship, including
            +      the original version of the Work and any modifications or additions
            +      to that Work or Derivative Works thereof, that is intentionally
            +      submitted to Licensor for inclusion in the Work by the copyright owner
            +      or by an individual or Legal Entity authorized to submit on behalf of
            +      the copyright owner. For the purposes of this definition, "submitted"
            +      means any form of electronic, verbal, or written communication sent
            +      to the Licensor or its representatives, including but not limited to
            +      communication on electronic mailing lists, source code control systems,
            +      and issue tracking systems that are managed by, or on behalf of, the
            +      Licensor for the purpose of discussing and improving the Work, but
            +      excluding communication that is conspicuously marked or otherwise
            +      designated in writing by the copyright owner as "Not a Contribution."
            +
            +      "Contributor" shall mean Licensor and any individual or Legal Entity
            +      on behalf of whom a Contribution has been received by Licensor and
            +      subsequently incorporated within the Work.
            +
            +   2. Grant of Copyright License. Subject to the terms and conditions of
            +      this License, each Contributor hereby grants to You a perpetual,
            +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
            +      copyright license to reproduce, prepare Derivative Works of,
            +      publicly display, publicly perform, sublicense, and distribute the
            +      Work and such Derivative Works in Source or Object form.
            +
            +   3. Grant of Patent License. Subject to the terms and conditions of
            +      this License, each Contributor hereby grants to You a perpetual,
            +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
            +      (except as stated in this section) patent license to make, have made,
            +      use, offer to sell, sell, import, and otherwise transfer the Work,
            +      where such license applies only to those patent claims licensable
            +      by such Contributor that are necessarily infringed by their
            +      Contribution(s) alone or by combination of their Contribution(s)
            +      with the Work to which such Contribution(s) was submitted. If You
            +      institute patent litigation against any entity (including a
            +      cross-claim or counterclaim in a lawsuit) alleging that the Work
            +      or a Contribution incorporated within the Work constitutes direct
            +      or contributory patent infringement, then any patent licenses
            +      granted to You under this License for that Work shall terminate
            +      as of the date such litigation is filed.
            +
            +   4. Redistribution. You may reproduce and distribute copies of the
            +      Work or Derivative Works thereof in any medium, with or without
            +      modifications, and in Source or Object form, provided that You
            +      meet the following conditions:
            +
            +      (a) You must give any other recipients of the Work or
            +          Derivative Works a copy of this License; and
            +
            +      (b) You must cause any modified files to carry prominent notices
            +          stating that You changed the files; and
            +
            +      (c) You must retain, in the Source form of any Derivative Works
            +          that You distribute, all copyright, patent, trademark, and
            +          attribution notices from the Source form of the Work,
            +          excluding those notices that do not pertain to any part of
            +          the Derivative Works; and
            +
            +      (d) If the Work includes a "NOTICE" text file as part of its
            +          distribution, then any Derivative Works that You distribute must
            +          include a readable copy of the attribution notices contained
            +          within such NOTICE file, excluding those notices that do not
            +          pertain to any part of the Derivative Works, in at least one
            +          of the following places: within a NOTICE text file distributed
            +          as part of the Derivative Works; within the Source form or
            +          documentation, if provided along with the Derivative Works; or,
            +          within a display generated by the Derivative Works, if and
            +          wherever such third-party notices normally appear. The contents
            +          of the NOTICE file are for informational purposes only and
            +          do not modify the License. You may add Your own attribution
            +          notices within Derivative Works that You distribute, alongside
            +          or as an addendum to the NOTICE text from the Work, provided
            +          that such additional attribution notices cannot be construed
            +          as modifying the License.
            +
            +      You may add Your own copyright statement to Your modifications and
            +      may provide additional or different license terms and conditions
            +      for use, reproduction, or distribution of Your modifications, or
            +      for any such Derivative Works as a whole, provided Your use,
            +      reproduction, and distribution of the Work otherwise complies with
            +      the conditions stated in this License.
            +
            +   5. Submission of Contributions. Unless You explicitly state otherwise,
            +      any Contribution intentionally submitted for inclusion in the Work
            +      by You to the Licensor shall be under the terms and conditions of
            +      this License, without any additional terms or conditions.
            +      Notwithstanding the above, nothing herein shall supersede or modify
            +      the terms of any separate license agreement you may have executed
            +      with Licensor regarding such Contributions.
            +
            +   6. Trademarks. This License does not grant permission to use the trade
            +      names, trademarks, service marks, or product names of the Licensor,
            +      except as required for reasonable and customary use in describing the
            +      origin of the Work and reproducing the content of the NOTICE file.
            +
            +   7. Disclaimer of Warranty. Unless required by applicable law or
            +      agreed to in writing, Licensor provides the Work (and each
            +      Contributor provides its Contributions) on an "AS IS" BASIS,
            +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
            +      implied, including, without limitation, any warranties or conditions
            +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
            +      PARTICULAR PURPOSE. You are solely responsible for determining the
            +      appropriateness of using or redistributing the Work and assume any
            +      risks associated with Your exercise of permissions under this License.
            +
            +   8. Limitation of Liability. In no event and under no legal theory,
            +      whether in tort (including negligence), contract, or otherwise,
            +      unless required by applicable law (such as deliberate and grossly
            +      negligent acts) or agreed to in writing, shall any Contributor be
            +      liable to You for damages, including any direct, indirect, special,
            +      incidental, or consequential damages of any character arising as a
            +      result of this License or out of the use or inability to use the
            +      Work (including but not limited to damages for loss of goodwill,
            +      work stoppage, computer failure or malfunction, or any and all
            +      other commercial damages or losses), even if such Contributor
            +      has been advised of the possibility of such damages.
            +
            +   9. Accepting Warranty or Additional Liability. While redistributing
            +      the Work or Derivative Works thereof, You may choose to offer,
            +      and charge a fee for, acceptance of support, warranty, indemnity,
            +      or other liability obligations and/or rights consistent with this
            +      License. However, in accepting such obligations, You may act only
            +      on Your own behalf and on Your sole responsibility, not on behalf
            +      of any other Contributor, and only if You agree to indemnify,
            +      defend, and hold each Contributor harmless for any liability
            +      incurred by, or claims asserted against, such Contributor by reason
            +      of your accepting any such warranty or additional liability.
            +
            +   END OF TERMS AND CONDITIONS
            +
            +   APPENDIX: How to apply the Apache License to your work.
            +
            +      To apply the Apache License to your work, attach the following
            +      boilerplate notice, with the fields enclosed by brackets "[]"
            +      replaced with your own identifying information. (Don't include
            +      the brackets!)  The text should be enclosed in the appropriate
            +      comment syntax for the file format. We also recommend that a
            +      file or class name and description of purpose be included on the
            +      same "printed page" as the copyright notice for easier
            +      identification within third-party archives.
            +
            +   Copyright 2012, Cedric Beust
            +
            +   Licensed under the Apache License, Version 2.0 (the "License");
            +   you may not use this file except in compliance with the License.
            +   You may obtain a copy of the License at
            +
            +       http://www.apache.org/licenses/LICENSE-2.0
            +
            +   Unless required by applicable law or agreed to in writing, software
            +   distributed under the License is distributed on an "AS IS" BASIS,
            +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            +   See the License for the specific language governing permissions and
            +   limitations under the License.
            +
            diff --git a/README.version b/README.version
            new file mode 100644
            index 0000000..9de0411
            --- /dev/null
            +++ b/README.version
            @@ -0,0 +1,4 @@
            +URL: https://github.com/cbeust/jcommander
            +Version: 1.48 (14fbe2bc5a2c402b456ed68578a5d5dc2c343fa2)
            +BugComponent: 99142
            +Owners: iam
            -- 
            cgit v1.2.3
            
            
            From 5321f6ff3251784760f79982b1a720e3607c5003 Mon Sep 17 00:00:00 2001
            From: Igor Murashkin 
            Date: Wed, 16 Mar 2016 13:49:37 -0700
            Subject: build: Add support for building jcommander within the AOSP (host
             only).
            
            Bug: 27552463
            Change-Id: I71b4f3b26b9307b36444cecc75d67de03be9cb23
            ---
             Android.mk                                         | 42 ++++++++++++++++++++++
             .../internal/DefaultConverterFactory.java          | 10 ++++--
             2 files changed, 49 insertions(+), 3 deletions(-)
             create mode 100644 Android.mk
            
            diff --git a/Android.mk b/Android.mk
            new file mode 100644
            index 0000000..76f2f8b
            --- /dev/null
            +++ b/Android.mk
            @@ -0,0 +1,42 @@
            +# Copyright (C) 2016 The Android Open Source Project
            +#
            +# Licensed under the Apache License, Version 2.0 (the "License");
            +# you may not use this file except in compliance with the License.
            +# You may obtain a copy of the License at
            +#
            +#      http://www.apache.org/licenses/LICENSE-2.0
            +#
            +# Unless required by applicable law or agreed to in writing, software
            +# distributed under the License is distributed on an "AS IS" BASIS,
            +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
            +# See the License for the specific language governing permissions and
            +# limitations under the License.
            +#
            +
            +#
            +# Build support for jcommander within the Android Open Source Project
            +# See https://source.android.com/source/building.html for more information
            +#
            +
            +LOCAL_PATH := $(call my-dir)
            +
            +include $(CLEAR_VARS)
            +
            +# Host JAR builds have every single file because all the standard APIs are available.
            +jcommander_all_src_files := $(call all-java-files-under, src/main)
            +# Filter out PathConverter since android is missing java.nio.file APIs.
            +jcommander_android_src_files := $(filter-out %/PathConverter.java,$(jcommander_all_src_files))
            +
            +include $(CLEAR_VARS)
            +LOCAL_SRC_FILES := $(jcommander_all_src_files)
            +LOCAL_MODULE := jcommander-host
            +LOCAL_MODULE_TAGS := optional
            +include $(BUILD_HOST_JAVA_LIBRARY)
            +
            +include $(CLEAR_VARS)
            +LOCAL_SRC_FILES := $(jcommander_android_src_files)
            +LOCAL_MODULE := jcommander-hostdex
            +LOCAL_MODULE_TAGS := optional
            +include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
            +
            +# TODO: also add the tests once we have testng working.
            diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            index 2b8a10c..7eb5ae5 100644
            --- a/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            +++ b/src/main/java/com/beust/jcommander/internal/DefaultConverterFactory.java
            @@ -29,7 +29,6 @@ import com.beust.jcommander.converters.ISO8601DateConverter;
             import com.beust.jcommander.converters.IntegerConverter;
             import com.beust.jcommander.converters.LongConverter;
             import com.beust.jcommander.converters.StringConverter;
            -import com.beust.jcommander.converters.PathConverter;
             import com.beust.jcommander.converters.URIConverter;
             import com.beust.jcommander.converters.URLConverter;
             
            @@ -38,7 +37,6 @@ import java.math.BigDecimal;
             import java.util.Date;
             import java.net.URI;
             import java.net.URL;
            -import java.nio.file.Path;
             import java.util.Map;
             
             public class DefaultConverterFactory implements IStringConverterFactory {
            @@ -63,7 +61,13 @@ public class DefaultConverterFactory implements IStringConverterFactory {
                 m_classConverters.put(File.class, FileConverter.class);
                 m_classConverters.put(BigDecimal.class, BigDecimalConverter.class);
                 m_classConverters.put(Date.class, ISO8601DateConverter.class);
            -    m_classConverters.put(Path.class, PathConverter.class);
            +    try {
            +      Class pathClass = Class.forName("java.nio.file.Path");
            +      Class pathConverterClass = Class.forName("com.beust.jcommander.converters.PathConverter");
            +      m_classConverters.put(pathClass, (Class>)pathConverterClass);
            +    } catch (ClassNotFoundException e) {
            +      // Do nothing: Android does not have java.nio.file.Path
            +    }
                 m_classConverters.put(URI.class, URIConverter.class);
                 m_classConverters.put(URL.class, URLConverter.class);
               }
            -- 
            cgit v1.2.3