Class Options

java.lang.Object
org.plumelib.options.Options

public class Options extends Object
The Options class:
  • parses command-line options and sets fields in your program accordingly,
  • creates usage messages (such as printed by a --help option), and
  • creates documentation suitable for a manual or manpage.

Thus, the programmer is freed from writing duplicative, boilerplate code. The user documentation is automatically generated and never gets out of sync with the rest of the program.

The programmer does not have to write any code, only declare and document variables. For each field that you want to set from a command-line argument, you write Javadoc and an @Option annotation. Then, at run time, the field is automatically set from a command-line option of the same name. Also, at build time, usage messages and printed documentation are generated automatically.

Suppose your program should support the command-line arguments --outfile, -o (shorthand for --outfile), --ignore-case, -i, (shorthand for --ignore-case), and --temperature. This code does so:

 import org.plumelib.options.*;

 public class MyProgram {

   @Option("-o <filename> the output file ")
   public static File outfile = new File("/tmp/foobar");

   @Option("-i ignore case")
   public static boolean ignoreCase; // or, name the variable ignore_case

   @Option("set the initial temperature")
   public static double temperature = 75.0;

   public static void main(String[] args) {
     MyProgram myInstance = new MyProgram();
     Options options = new Options("MyProgram [options] infile outfile",
                                   myInstance, MyUtilityClass.class);
     String[] remainingArgs = options.parse(true, args);
     ...
   }
 }
 

In the code above, the call to parse(boolean, String[]) sets fields in object myInstance and sets static fields in class MyUtilityClass. It returns the original command line, with all options removed. If a command-line argument is incorrect, it prints a usage message and terminates the program. The program can also explicitly create or print a usage message; see usage(String...) and printUsage().

For examples of generated HTML documentation, see the documentation for Lookup, Randoop, and Javarifier.

@Option indicates a command-line option

The @Option annotation on a field specifies brief user documentation and, optionally, a one-character short name that a user may supply on the command line. The long name is taken from the name of the variable. When the name contains a capital letter, the user must use a hyphen or underscore to separate words. When the name contains an underscore, the user may substitute a hyphen on the command line instead.

For example, both the --multi-word-variable and --multi_word_variable command-line options would set a variable named multiWordVariable or multi_word_variable. (It is an error to define two variables multiWordVariable and multi_word_variable, and to annotate both of them with @Option.)

A user of your program supplies command-line options in the form "--name=value" or "-name value". The value (after the "=" or " ") is mandatory for all options except booleans. Booleans are set to true if no value is specified. Booleans support "--no-optionname" which is equivalent to "--optionname=false".

A user may provide an option multiple times on the command line. If the field is a list, each entry is added to the list. If the field is not a list, then only the last occurrence is used (subsequent occurrences override the previous value).

All arguments that start with "-" are processed as options. By default, the entire command line is scanned for options. To terminate option processing at the first non-option argument, see setParseAfterArg(boolean). Also, the special option "--" always terminates option processing; "--" is discarded, but no subsequent parts of the command line are scanned for options.

Unpublicized options

The @Unpublicized annotation causes an option not to be displayed in the usage message. This can be useful for options that are preliminary, experimental, or for internal purposes only. The @Unpublicized annotation must be specified in addition to the @Option annotation.

The usage message can optionally include unpublicized options; see usage(boolean,String...).

Option groups

In a usage message or manual, it is useful to group related options and give the group a name. For examples of this, see the documentation for Lookup, Randoop, and Javarifier.

If you wish to use option groups, then every option must be in some group. Declare related fields adjacent to one another in your .java file. Write @OptionGroup on the first field in each group.

The group name (the first argument of an @OptionGroup annotation) must be unique among all classes and objects passed to the Options(String, Object...) constructor.

If an option group itself is unpublicized:

  • The default usage message omits the group and all options belonging to it.
  • An unpublicized option group (that has any publicized options) is included in documentation for a manual.

If an option group is not unpublicized but contains only unpublicized options, it will not be included in the default usage message.

Option aliases

The @Option annotation has an optional parameter aliases, which accepts an array of strings. Each string in the array is an alias for the option being defined and can be used in place of an option's long name or short name.

One example is that a program might support "--optimize" and "--optimise" which are interchangeable. Another example is that a program might support "--help" and "-help" with the same meaning:

 // The user may supply --help, -h, or -help, which all mean the same thing and set this variable.
 @Option(value="-h Print a help message", aliases={"-help"})
 public static boolean help;

Aliases should start with a single dash or double dash. If there is only a single, one-character alias, it can be put at the beginning of the value field or in the aliases field. It is the programmer's responsibility to ensure that no alias is the same as other options or aliases.

Generating documentation for a manual or manpage

It is helpful to include a summary of all command-line options in amanual, manpage, or the class Javadoc for a class that has a main method. The OptionsDoclet class generates HTML documentation.

Supported field types

A field with an @Option annotation may be of the following types:

  • Primitive types: boolean, byte, char, short, int, long, float, double.
  • Primitive type wrappers: Boolean, Byte, Char, Short, Integer, Long, Float, Double. Use of a wrapper type allows the argument to have no default value.
  • Reference types that have a constructor with a single string parameter.
  • java.util.regex.Pattern.
  • enums.
  • Lists of any of the above reference types.

Customization

Option processing can be customized in a number of ways.

  • If setUseSingleDash(boolean) is true, then the long names take the form "-longname" instead of "--longname". It defaults to false.
  • If setParseAfterArg(boolean) is true, then options are searched for throughout a command line, to its end. If it is false, then processing stops at the first non-option argument. It defaults to true.
  • If spaceSeparatedLists is true, then when an argument contains spaces, it is treated as multiple elements to be added to a list. It defaults to false.
  • The programmer may set usageSynopsis to masquerade as another program.
  • If useDashes is false, then usage messages advertise long options with underscores (as in --my_option_name) instead of dashes (as in --my-option-name). The user can always specify either one on the command line; useDashes just affects usage messages. It defaults to false.

Limitations

  • Short options are only supported as separate entries (e.g., "-a -b") and not as a single group (e.g., "-ab").
  • If you have a boolean option named exactly "long", you must use "--long=false" to turn it off; "--no-long" is not supported.
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Indicates an exception encountered during argument processing.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static boolean
    Whether to treat arguments to lists as space-separated.
    @Nullable String
    Synopsis of usage.
    boolean
    In usage messages, use dashes (hyphens) to split words in option names.
    boolean
    When true, long options take the form -longOption with a single dash, rather than the default --longOption with two dashes.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Options(@UnknownInitialization Object... args)
    Prepare for option processing.
    Options(String usageSynopsis, @UnknownInitialization Object... args)
    Prepare for option processing.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    enableDebugLogging(boolean enabled)
    Enable or disable debug logging.
    Returns a string containing all of the options that were set and their arguments.
    parse(boolean showUsageOnError, String[] args)
    Sets option variables from the given command line; if any command-line argument is illegal, prints the usage message and terminates the program.
    parse(String[] args)
    Sets option variables from the given command line.
    parse(String message, String[] args)
    Sets option variables from the given command line; if any command-line argument is illegal, prints the given message and terminates the program.
    void
    Prints, to standard output, usage information.
    void
    Prints usage information to the given PrintStream.
    void
    setParseAfterArg(boolean val)
    If true, Options will parse arguments even after a non-option command-line argument.
    Returns a string containing the current setting for each option, in command-line format that can be parsed by Options.
    settings(boolean showUnpublicized)
    Returns a string containing the current setting for each option, in command-line format that can be parsed by Options.
    void
    setUseSingleDash(boolean val)
    If true, long options (those derived from field names) are expected with a single dash prefix as in -long-option rather than --long-option.
    static String[]
    Splits the argument string into an array of tokens (command-line flags and arguments), respecting single and double quotes.
    Return a description of all of the known options.
    usage(boolean showUnpublicized, String... groupNames)
    Returns a usage message for command-line options.
    usage(String... groupNames)
    Returns a usage message for command-line options.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • useSingleDash

      public boolean useSingleDash
      When true, long options take the form -longOption with a single dash, rather than the default --longOption with two dashes.
    • spaceSeparatedLists

      public static boolean spaceSeparatedLists
      Whether to treat arguments to lists as space-separated. Defaults to false.

      When true, an argument to an option of list type is split, on whitespace, into multiple arguments each of which is added to the list. When false, each argument to an option of list type is treated as a single element, no matter what characters it contains.

      For example, when this is true, a command line containing --my-option="foo bar" is equivalent to --my-option="foo" --my-option="bar". Both of them have the effect of adding two elements, "foo" and "bar", to the list myOption (or my_option).

    • usageSynopsis

      public @Nullable String usageSynopsis
      Synopsis of usage. Example: "prog [options] arg1 arg2 ..."

      This field is public so that clients can reset it. Setting it enables one program to masquerade as another program, based on parsed options.

    • useDashes

      public boolean useDashes
      In usage messages, use dashes (hyphens) to split words in option names. This only applies to fields whose name contains an underscore. On the command line, a user may use either the underscores or dashes in the option name; this only controls which one is advertised in usage messages.
  • Constructor Details

    • Options

      public Options(@UnknownInitialization Object... args)
      Prepare for option processing. Creates an object that will set fields in all the given arguments. An argument to this method may be a Class, in which case its static fields are set. The names of all the options (that is, the fields annotated with @Option) must be unique across all the arguments.
      Parameters:
      args - the classes whose options to process
    • Options

      public Options(String usageSynopsis, @UnknownInitialization Object... args)
      Prepare for option processing. Creates an object that will set fields in all the given arguments. An argument to this method may be a Class, in which case it must be fully initalized and its static fields are set. The names of all the options (that is, the fields annotated with @Option) must be unique across all the arguments.
      Parameters:
      usageSynopsis - a synopsis of how to call your program
      args - the classes whose options to process
  • Method Details

    • enableDebugLogging

      public void enableDebugLogging(boolean enabled)
      Enable or disable debug logging.
      Parameters:
      enabled - whether to enable or disable logging
    • setParseAfterArg

      public void setParseAfterArg(boolean val)
      If true, Options will parse arguments even after a non-option command-line argument. Setting this to true is useful to permit users to write options at the end of a command line. Setting this to false is useful to avoid processing arguments that are actually options/arguments for another program that this one will invoke. The default is true.
      Parameters:
      val - whether to parse arguments after a non-option command-line argument
    • setUseSingleDash

      public void setUseSingleDash(boolean val)
      If true, long options (those derived from field names) are expected with a single dash prefix as in -long-option rather than --long-option. The default is false and long options will be parsed with a double dash prefix as in --longOption.
      Parameters:
      val - whether to parse long options with a single dash, as in -longOption
    • tokenize

      public static String[] tokenize(String args)
      Splits the argument string into an array of tokens (command-line flags and arguments), respecting single and double quotes.

      This method is only appropriate when the String[] version of the arguments is not available — for example, for the premain method of a Java agent.

      Parameters:
      args - the command line to be tokenized
      Returns:
      a string array analogous to the argument to main
    • parse

      public String[] parse(String[] args) throws Options.ArgException
      Sets option variables from the given command line.
      Parameters:
      args - the commandline to be parsed
      Returns:
      all non-option arguments
      Throws:
      Options.ArgException - if the command line contains unknown option or misused options
    • parse

      public String[] parse(String message, String[] args)
      Sets option variables from the given command line; if any command-line argument is illegal, prints the given message and terminates the program.

      If an error occurs, prints the exception's message, prints the given message, and then terminates the program. The program is terminated rather than throwing an error to create cleaner output.

      Parameters:
      message - a message to print, such as "Pass --help for a list of all command-line arguments."
      args - the command line to parse
      Returns:
      all non-option arguments
      See Also:
    • parse

      public String[] parse(boolean showUsageOnError, String[] args)
      Sets option variables from the given command line; if any command-line argument is illegal, prints the usage message and terminates the program.

      If an error occurs and showUsageOnError is true, prints the exception's message, prints usage inoframtion, and then terminates the program. The program is terminated rather than throwing an error to create cleaner output.

      Parameters:
      showUsageOnError - if a command-line argument is incorrect, print a usage message
      args - the command line to parse
      Returns:
      all non-option arguments
      See Also:
    • printUsage

      public void printUsage(PrintStream ps)
      Prints usage information to the given PrintStream. Uses the usage synopsis passed into the constructor, if any.
      Parameters:
      ps - where to print usage information
    • printUsage

      public void printUsage()
      Prints, to standard output, usage information.
    • usage

      public String usage(String... groupNames)
      Returns a usage message for command-line options.
      Parameters:
      groupNames - the list of option groups to include in the usage message. If empty and option groups are being used, will return usage for all option groups that are not unpublicized. If empty and option groups are not being used, will return usage for all options that are not unpublicized.
      Returns:
      the command-line usage message
    • usage

      public String usage(boolean showUnpublicized, String... groupNames)
      Returns a usage message for command-line options.
      Parameters:
      showUnpublicized - if true, treat all unpublicized options and option groups as publicized
      groupNames - the list of option groups to include in the usage message. If empty and option groups are being used, will return usage for all option groups that are not unpublicized. If empty and option groups are not being used, will return usage for all options that are not unpublicized.
      Returns:
      the command-line usage message
    • getOptionsString

      public String getOptionsString()
      Returns a string containing all of the options that were set and their arguments. This is essentially the contents of args[] with all non-options removed. It can be used for calling a subprocess or for debugging.
      Returns:
      options, similarly to supplied on the command line
      See Also:
    • settings

      public String settings()
      Returns a string containing the current setting for each option, in command-line format that can be parsed by Options. Contains every known option even if the option was not specified on the command line. Never contains duplicates.
      Returns:
      a command line that can be tokenized with tokenize(java.lang.String), containing the current setting for each option
    • settings

      public String settings(boolean showUnpublicized)
      Returns a string containing the current setting for each option, in command-line format that can be parsed by Options. Contains every known option even if the option was not specified on the command line. Never contains duplicates.
      Parameters:
      showUnpublicized - if true, treat all unpublicized options and option groups as publicized
      Returns:
      a command line that can be tokenized with tokenize(java.lang.String), containing the current setting for each option
    • toString

      @SideEffectFree public String toString(@GuardSatisfied Options this)
      Return a description of all of the known options. Each option is described on its own line in the output.
      Overrides:
      toString in class Object
      Returns:
      a description of all of the known options