<?xml version="1.0"?>
<!--
 Copyright 2002,2004 The Apache Software Foundation

 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.
-->
<document>

  <properties>
    <author email="commons-dev@jakarta.apache.org">commons-dev</author>
    <title>Usage Scenarios</title>
  </properties>

  <body>
    <section name="Usage Scenarios">
      <p>
        The following sections describe some example scenarios on how to 
        use CLI in applications.
      </p>

      <subsection name="Using a boolean option">
        <p>
          A boolean option is represented on a command line by the presence
          of the option, i.e. if the option is found then the option value
          is <code>true</code>, otherwise the value is <code>false</code>.
        </p>
        <p>
          The <code>DateApp</code> utility prints the current date to standard
          output.  If the <code>-t</code> option is present the current time is 
          also printed.
        </p>
      </subsection>
      <subsection name="Create the Options">
        <p>
          An <a href="apidocs/org/apache/commons/cli/Options.html">
          Options</a> object must be created and the <code>Option</code> must be 
          added to it.
        </p>
        <source>
// create Options object
Options options = new Options();

// add t option
options.addOption("t", false, "display current time");</source>
          <p>
            The <code>addOption</code> method has three parameters.  The first
            parameter is a <code>java.lang.String</code> that represents the option. 
            The second parameter is a <code>boolean</code> that specifies whether the
            option requires an argument or not.  In the case of a boolean option
            (sometimes referred to as a flag) an argument value is not present so
            <code>false</code> is passed.  The third parameter is the description
            of the option.  This description will be used in the usage text of the
            application.
          </p>
      </subsection>
      <subsection name="Parsing the command line arguments">
        <p>
          The <code>parse</code> methods of <code>CommandLineParser</code> are used 
          to parse the command line arguments.  The <code>PosixPaser</code> is
          great when you need to handle options that are one character long,
          like the <code>t</code> option in this example.
        </p>
        <source>CommandLineParser parser = new PosixParser();
CommandLine cmd = parser.parse( options, args);</source>
        <p>
          Now we need to check if the <code>t</code> option is present.  To do
          this we will interrogate the 
          <a href="apidocs/org/apache/commons/cli/CommandLine.html">CommandLine
          </a> object.  The <code>hasOption</code> method takes a 
          <code>java.lang.String</code> parameter and returns <code>true</code> if the option 
          represented by the <code>java.lang.String</code> is present, otherwise 
          it returns <code>false</code>.
        </p>
        <source>if(cmd.hasOption("t")) {
    // print the date and time
}
else {
    // print the date
}</source>
      </subsection>
      <subsection name="International Time">
        <p>
          The <code>InternationalDateApp</code> utility extends the 
          <code>DateApp</code> utility by providing the ability to print the
          date and time in any country in the world.  To facilitate this a new
          command line option, <code>c</code>, has been introduced.
        </p>
        <source>// add c option
options.addOption("c", true, "country code");</source>
        <p>
          The second parameter is <code>true</code> this time.  This specifies that the
          <code>c</code> option requires an argument value.  If the required option
          argument value is specified on the command line it is returned,
          otherwise <code>null</code> is returned.
        </p>
      </subsection>
      <subsection name="Retrieving the argument value">
        <p>
          The <code>getOptionValue</code> methods of <code>CommandLine</code> are
          used to retrieve the argument values of options.
        </p>
        <source>// get c option value
String countryCode = cmd.getOptionValue("c");

if(countryCode == null) {
    // print default date
}
else {
    // print date for country specified by countryCode
}</source>
      </subsection>
    </section>

    <section name="Ant Example">
      <p>
        One of the most ubiquitous Java applications 
        <a href="http://ant.apache.org/">Ant</a> will be used
        here to illustrate how to create the <code>Options</code> required.  The following
        is the help output for Ant.
      </p>
      <source>ant [options] [target [target2 [target3] ...]]
  Options: 
  -help                  print this message
  -projecthelp           print project help information
  -version               print the version information and exit
  -quiet                 be extra quiet
  -verbose               be extra verbose
  -debug                 print debugging information
  -emacs                 produce logging information without adornments
  -logfile &lt;file&gt;        use given file for log
  -logger &lt;classname&gt;    the class which is to perform logging
  -listener &lt;classname&gt;  add an instance of class as a project listener
  -buildfile &lt;file&gt;      use given buildfile
  -D&lt;property>=&lt;value&gt;   use value for given property
  -find &lt;file&gt;           search for buildfile towards the root of the
                         filesystem and use it</source>
      <subsection name="Boolean Options">
        <p>
          Lets create the boolean options for the application as they
          are the easiest to create.  For clarity the constructors for
          <code>Option</code> are used here.
        </p>
        <source>Option help = new Option( "help", "print this message" );
Option projecthelp = new Option( "projecthelp", "print project help information" );
Option version = new Option( "version", "print the version information and exit" );
Option quiet = new Option( "quiet", "be extra quiet" );
Option verbose = new Option( "verbose", "be extra verbose" );
Option debug = new Option( "debug", "print debugging information" );
Option emacs = new Option( "emacs",
                           "produce logging information without adornments" );</source>
      </subsection>
      <subsection name="Argument Options">
        <p> 
          The argument options are created using the <code>OptionBuilder</code>.
        </p>
        <source>Option logfile   = OptionBuilder.withArgName( "file" )
                                .hasArg()
                                .withDescription(  "use given file for log" )
                                .create( "logfile" );

Option logger    = OptionBuilder.withArgName( "classname" )
                                .hasArg()
                                .withDescription( "the class which it to perform "
                                                  + "logging" )
                                .create( "logger" );

Option listener  = OptionBuilder.withArgName( "classname" )
                                .hasArg()
                                .withDescription( "add an instance of class as "
                                                  + "a project listener" )
                                .create( "listener"); 

Option buildfile = OptionBuilder.withArgName( "file" )
                                .hasArg()
                                .withDescription(  "use given buildfile" )
                                .create( "buildfile");

Option find      = OptionBuilder.withArgName( "file" )
                                .hasArg()
                                .withDescription( "search for buildfile towards the "
                                                  + "root of the filesystem and use it" )
                                .create( "find" );</source>
      </subsection>
      <subsection name="Java Property Option">
        <p>
          The last option to create is the Java property and it is also created
          using the OptionBuilder.
        </p>
        <source>Option property  = OptionBuilder.withArgName( "property=value" )
                                .hasArg()
                                .withValueSeparator()
                                .withDescription( "use value for given property" )
                                .create( "D" );</source>
      </subsection>
      <subsection name="Create the Options">
        <p>
          Now that we have created each 
          <a href="apidocs/org/apache/commons/cli/Option.html">Option</a> we need 
          to create the 
          <a href="apidocs/org/apache/commons/cli/Options.html">Options</a> 
          instance.  This is achieved using the 
          <a href="apidocs/org/apache/commons/cli/CommandLine.html#addOption(org.apache.commons.cli.Option)">addOption</a> 
          method of <code>Options</code>.
        </p>
        <source>Options options = new Options();

options.addOption( help );
options.addOption( projecthelp );
options.addOption( version );
options.addOption( quiet );
options.addOption( verbose );
options.addOption( debug );
options.addOption( emacs );
options.addOption( logfile );
options.addOption( logger );
options.addOption( listener );
options.addOption( buildfile );
options.addOption( find );
options.addOption( property );</source>
        <p>
          All the preperation is now complete and we are now ready to
          parse the command line arguments.
        </p>
      </subsection>
      <subsection name="Create the Parser">
        <p>
          We now need to create a <code>Parser</code>.  This will parse the command
          line arguments, using the rules specified by the <code>Options</code> and
          return an instance of <a href="apidocs/org/apache/commons/cli/CommandLine.html">CommandLine</a>.
          This time we will use a <a href="apidocs/org/apache/commons/cli/GnuParser.html">GnuParser</a>
          which is able to handle options that are more than one character long.
        </p>
        <source>public static void main( String[] args ) {
    // create the parser
    CommandLineParser parser = new GnuParser();
    try {
        // parse the command line arguments
        CommandLine line = parser.parse( options, args );
    }
    catch( ParseException exp ) {
        // oops, something went wrong
        System.err.println( "Parsing failed.  Reason: " + exp.getMessage() );
    }
}</source>
      </subsection>
      <subsection name="Querying the commandline">
        <p>
          To see if an option has been passed the <code>hasOption</code>
          method is used.  The argument value can be retrieved using
          the <code>getValue</code> method.
        </p>
        <source>// has the buildfile argument been passed?
if( line.hasOption( "buildfile" ) ) {
    // initialise the member variable
    this.buildfile = line.getValue( "buildfile" );
}</source>
      </subsection>
      <subsection name="Usage/Help">
        <p>
          CLI also provides the means to automatically generate usage
          and help information.  This is achieved with the
          <a href="apidocs/org/apache/commons/cli/HelpFormatter.html">HelpFormatter</a>
          class.
        </p>
        <source>// automatically generate the help statement
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( "ant", options );</source>
        <p>
          When executed the following output is produced:
        </p>
        <source>usage: ant
-D &lt;property=value&gt;     use value for given property
-buildfile &lt;file&gt;       use given buildfile
-debug                  print debugging information
-emacs                  produce logging information without adornments
-file &lt;file&gt;            search for buildfile towards the root of the
                        filesystem and use it
-help                   print this message
-listener &lt;classname&gt;   add an instance of class as a project listener
-logger &lt;classname&gt;     the class which it to perform logging
-projecthelp            print project help information
-quiet                  be extra quiet
-verbose                be extra verbose
-version                print the version information and exit</source>
        <p>
          If you also require to have a usage statement printed 
          then calling <code>formatter.printHelp( "ant", options, true )</code>
          will generate a usage statment as well as the help information.
        </p>
      </subsection>
    </section>

    <section name="ls Example">
      <p>
        One of the most widely used command line applications in the *nix world
        is <code>ls</code>.  To parse a command line for an application like this
        we will use the <a href="apidocs/org/apache/commons/cli/PosixParser.html">PosixParser</a>.
        Due to the large number of options required for <code>ls</code> this
        example will only cover a small proportion of the options.  The following
        is a section of the help output.
      </p>
      <source>Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuSUX nor --sort.

-a, --all                  do not hide entries starting with .
-A, --almost-all           do not list implied . and ..
-b, --escape               print octal escapes for nongraphic characters
    --block-size=SIZE      use SIZE-byte blocks
-B, --ignore-backups       do not list implied entries ending with ~
-c                         with -lt: sort by, and show, ctime (time of last
                           modification of file status information)
                           with -l: show ctime and sort by name
                           otherwise: sort by ctime
-C                         list entries by columns</source>
      <p>
        The following is the code that is used to create the 
        <a href="apidocs/org/apache/commons/cli/Options.html">Options</a> for this example.
      </p>
      <source>// create the command line parser
CommandLineParser parser = new PosixParser();

// create the Options
Options options = new Options();
options.addOption( "a", "all", false, "do not hide entries starting with ." );
options.addOption( "A", "almost-all", false, "do not list implied . and .." );
options.addOption( "b", "escape", false, "print octal escapes for nongraphic "
                                         + "characters" );
options.addOption( OptionBuilder.withLongOpt( "block-size" )
                                .withDescription( "use SIZE-byte blocks" )
                                .withValueSeparator( '=' )
                                .hasArg()
                                .create() );
options.addOption( "B", "ignore-backups", false, "do not list implied entried "
                                                 + "ending with ~");
options.addOption( "c", false, "with -lt: sort by, and show, ctime (time of last " 
                               + "modification of file status information) with "
                               + "-l:show ctime and sort by name otherwise: sort "
                               + "by ctime" );
options.addOption( "C", false, "list entries by columns" );

String[] args = new String[]{ "--block-size=10" };

try {
    // parse the command line arguments
    CommandLine line = parser.parse( options, args );

    // validate that block-size has been set
    if( line.hasOption( "block-size" ) ) {
        // print the value of block-size
        System.out.println( line.getOptionValue( "block-size" ) );
    }
}
catch( ParseException exp ) {
    System.out.println( "Unexpected exception:" + exp.getMessage() );
}</source>
    </section>
  </body>
</document>
