Uploaded image for project: 'Commons CLI'
  1. Commons CLI
  2. CLI-196

Annotation based option specification

    XMLWordPrintableJSON

    Details

    • Type: New Feature
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: CLI-1.x
    • Labels:
      None

      Description

      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 arguments:

      -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 object.
      }
      

      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?

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              kevin-au Kevin Holloway
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: