blob: b9c83f3909539e30c5350748a27d747d5517a6f7 [file] [log] [blame]
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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="dev@commons.apache.org">commons-dev</author>
<title>CLI2 - Overview</title>
</properties>
<body>
<section name="Overview">
<p>
CLI Breaks down command line processing into three distinct phases, the
first of which is to create a model of the command line you wish to process. The
second phase is arguably the most important as it involves processing the
command line arguments of the application according to the model created.
Finally the parsed command line is available to be queried by the
application proper. The phases are discussed in more detail below.
</p>
<subsection name="Modelling the interface">
<p>
In CLI2 a command line is modelled as a Group composed of many Options.
There are a number different Option implementations available to be
used including DefaultOption, Switch and Command which may all have an
Argument and/or a Group of child options associated with them. An
example of where this parental relationship could be used is where you
need to allow for the following scenario where one option
only makes sense within the context of another:
</p>
<p><code>myapp --output path/to/file --xml</code></p>
<p>
Typically this command line would be modelled as a DefaultOption
(<code>--output</code>) with an Argument (to capture
<code>path/to/file</code>) and a Group of children consisting of a
DefaultOption (<code>--xml</code>) since the format only applies if the
output is specified
</p>
<p>
The various Option implementations provided need careful configuration
and constructors take a complex set of arguments. To ease the construction
of these options *Builder classes (e.g. DefaultOptionBuilder, GroupBuilder
and ArgumentBuilder) have been supplied following the
<a href="http://c2.com/cgi/wiki?BuilderPattern">Builder Pattern</a>
which essentially involves using the DefaultOptionBuilder class to create
instances of DefaultOption using descriptive method calls instead of
anonymous arguments to a constructor. The following example demonstrates how
the command line shown above could be modelled in code:
</p>
<source>
DefaultOptionBuilder oBuilder = new DefaultOptionBuilder();
ArgumentBuilder aBuilder = new ArgumentBuilder();
GroupBuilder gBuilder = new GroupBuilder();
DefaultOption xmlOption =
oBuilder
.withLongName("xml")
.withDescription("Output using xml format")
.create();
Argument pathArgument =
aBuilder
.withName("path")
.withMinimum(1)
.withMaximum(1)
.create();
Group outputChildren =
gBuilder
.withOption(xmlOption)
.create();
Option outputOption =
oBuilder
.withLongName("output")
.withDescription("Outputs to a file")
.withArgument(pathArgument)
.withChildren(outputChildren)
.create();
</source>
<p>
The <a href="options.html">Options</a> and
<a href="builders.html">Builders</a> sections of the manual discuss these
features in greater detail.
</p>
<p>
Once all the options have been composed into a Group modelling the complete
option model then we are ready to parse a command line.
</p>
</subsection>
<subsection name="Parsing the command line">
<p>
The Parser class can be used to parse an array of arguments against the
option model into a CommandLine. The parsing is driven by the
<code>parse(String[])</code> method which delegates to the option model to do
the actual parsing, with each Option implementation providing its own parsing
logic. The <code>parseAndHelp(String[])</code> method attempts to simplify
the use of the former method by automatically handling any <code>--help</code>
options and displaying error messages where appropriate.
</p>
<p>
The HelpFormatter class is designed to allow the option model to be described
to the user in a manner typical of command line applications. The
HelpFormatter is designed with flexibility in mind so it should be possible to
control exactly which structures are described to the user and what level of
detail to use.
</p>
<p>
Any errors that occur while parsing result in an OptionException being thrown
which attempt to provide a meaningful message describing the problem to the
user. Parser's <code>parseAndHelp(String[])</code> method catches any
OptionException and uses the HelpFormatter to display to the user:
</p>
<source>
// configure the options
Group options = ...;
// configure a HelpFormatter
HelpFormatter hf = new HelpFormatter();
// configure a parser
Parser p = new Parser();
p.setGroup(options);
p.setHelpFormatter(hf);
p.setHelpTrigger("--help");
CommandLine cl = p.parseAndHelp(new String[]{});
// abort application if no CommandLine was parsed
if(cl==null) {
System.exit(-1);
}
</source>
<p>
Assuming that OptionExceptions have been averted then the next step is to have
the application query the resulting CommandLine instance.
</p>
</subsection>
<subsection name="Querying the result">
<p>
The CommandLine interface provides lots of ways to look up information either
by Option instance or by a String representing any of the forms valid on the
command line. For example if an option is configured with multiple names
(e.g. <code>-?</code>, <code>-h</code>, <code>--help</code>) then any of the
those strings can be used to look up the value irrespective of which form
appeared on the command line.
</p>
<p>
The <code>hasOption()</code> family of methods can be used to simply test for
the presence of options, while the <code>getValues()</code> family of methods
can be used to retrieve the values associated with Arguments. The status of
any Switch options can be detected through the use of <code>getSwitch()</code>
methods which will return a Boolean if set or null otherwise:
</p>
<source>
// if we have --output option
if(cl.hasOption("--output")) {
// grab the path
String path = (String)cl.getValue("--output");
// grab the format
boolean xml = cl.hasOption("--xml");
// configure the application's output
configureOutput(path,xml);
}
</source>
<p>
To enable complex CommandLine configurations alternative implementations are
provided that can wrap a Properties or Preferences instance as a CommandLine.
These can then be combined with the DefaultingCommandLine and the parsed
CommandLine to provide a variety of different defaulting and overriding
scenarios.
</p>
</subsection>
</section>
</body>
</document>