commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kevin Holloway (JIRA)" <>
Subject [jira] Created: (CLI-196) Annotation based option specification
Date Mon, 15 Mar 2010 21:13:27 GMT
Annotation based option specification

                 Key: CLI-196
             Project: Commons CLI
          Issue Type: New Feature
          Components: CLI-1.x
            Reporter: Kevin Holloway
            Priority: Minor

This is a proposal for an alternative way of specifying command line options, using annotations.
 It's implementation wraps Commons CLI code and uses reflection.

>From a user perspective, the following is a example of a mythical program that takes three

-utc, reports the date in terms of UTC.
-offset <integer>, adds an offset to the reference date.
-reference <amount>, the reference amount (whatever that is).

The Java code for the options is as follows:

public class XyzOptions {

  private boolean utc;
  private int offset;
  private BigDecimal reference;

  @Option (name="utc", description="Reports the date in terms of UTC")
  void setUTC (boolean utc) {
    this.utc = utc;

  @Option (name="offset", description="Adds an offset to the reference date")
  void setOffset (int offset) {
    this.offset = offset;

  @Option (name="reference", required=true, description="The reference amount")
  void setReferenceAmount (BigDecimal amount) {
    this.reference = amount;

  // get methods omitted

@Option is an annotation that provides CLI option details.  The @Option annotates set methods
of the options class.

The Java code that uses these options is as follows:

public static void main (String[] args) {
  XyzOptions options = CommandLine.parse(args, XyzOptions.class, "dateCommand");
  // the program options can then be accessed using get methods or field access on the options

The "CommandLine" class is the class that builds the CLI Options instance using the @Option
annotations and reflection.  

The @Option annotation allows the following to be specified:
* name.  The short name of the option.
* longForm.  The long form of the option.
* description.  The description of the option.  This is the description that appears in the
help text.
* required.  true if this option is required.  This defaults to false, meaning the option
is optional.
* argOptional.  true if the option argument is optional.  This defaults to false, meaning
the option argument is mandatory.

The remaining information is obtained by reflection on the set method parameter.
* If the set method parameter is boolean or Boolean, the option is assumed to take no argument.
 It is a simple switch.
* If the set method parameter takes any other type, the option is assumed to take an argument
of that type.
** If the parameter type is String, the option argument is used as-is.
** If the parameter type is a primitive type (or the class equivalent), the option argument
is converted to that type and passed to the set method.
** If the parameter type is something else (such as BigDecimal), the command line parser looks
for a class constructor that takes a String argument.  If this is found, and instance of the
object is created an passed to the set method.  Any class that has a constructor that takes
a single String argument can be used.

Option arguments can be validated in the set methods.  For example, if a File needs to be
a directory, the set method could be as follows:

  @Option (name="dir", description="The output directory")
  void setOutputDir (File file) {
    if (!file.isDirectory()) {
      throw new IllegalArgumentException ("'dir' option must specify a directory");
    this.file = file;

The code for what is described here is available if anyone wants it.

This is the idea.  There are some issues to resolve, but the first question is: does anyone
think it worth pursuing this?

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message