[jira] Created: (CLI-196) Annotation based option specification

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[jira] Created: (CLI-196) Annotation based option specification

ASF GitHub Bot (Jira)
Annotation based option specification
-------------------------------------

                 Key: CLI-196
                 URL: https://issues.apache.org/jira/browse/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 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:

{code}
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
}
{code}

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

{code}
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.
}
{code}

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:

{code}
  @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;
}
{code}

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.

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (CLI-196) Annotation based option specification

ASF GitHub Bot (Jira)

    [ https://issues.apache.org/jira/browse/CLI-196?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12877862#action_12877862 ]

Emmanuel Bourg commented on CLI-196:
------------------------------------

That's an interesting usage of the annotations, however I'm not sure I would tie the description of the options to the class, that would make the internationalization impossible.

> Annotation based option specification
> -------------------------------------
>
>                 Key: CLI-196
>                 URL: https://issues.apache.org/jira/browse/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 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:
> {code}
> 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
> }
> {code}
> @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:
> {code}
> 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.
> }
> {code}
> 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:
> {code}
>   @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;
> }
> {code}
> 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.

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (CLI-196) Annotation based option specification

ASF GitHub Bot (Jira)
In reply to this post by ASF GitHub Bot (Jira)

    [ https://issues.apache.org/jira/browse/CLI-196?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12888035#action_12888035 ]

Emmanuel Bourg commented on CLI-196:
------------------------------------

I18n could probably be implemented by adding a descriptionKey attribute as an alternative to the description attribute. The resource bundle would be specified by an annotation at the class level.

For the reference, the annotation based declaration has been implemented by Cedric Beust in JCommander :

http://beust.com/weblog/2010/07/13/announcing-jcommander-1-0

> Annotation based option specification
> -------------------------------------
>
>                 Key: CLI-196
>                 URL: https://issues.apache.org/jira/browse/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 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:
> {code}
> 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
> }
> {code}
> @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:
> {code}
> 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.
> }
> {code}
> 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:
> {code}
>   @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;
> }
> {code}
> 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.

Reply | Threaded
Open this post in threaded view
|

[jira] Updated: (CLI-196) Annotation based option specification

ASF GitHub Bot (Jira)
In reply to this post by ASF GitHub Bot (Jira)

     [ https://issues.apache.org/jira/browse/CLI-196?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Emmanuel Bourg updated CLI-196:
-------------------------------

    Fix Version/s: 1.4
         Priority: Major  (was: Minor)

> Annotation based option specification
> -------------------------------------
>
>                 Key: CLI-196
>                 URL: https://issues.apache.org/jira/browse/CLI-196
>             Project: Commons CLI
>          Issue Type: New Feature
>          Components: CLI-1.x
>            Reporter: Kevin Holloway
>             Fix For: 1.4
>
>
> 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:
> {code}
> 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
> }
> {code}
> @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:
> {code}
> 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.
> }
> {code}
> 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:
> {code}
>   @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;
> }
> {code}
> 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.