blob: 8be3bf5c5867b4ed6ed92cd689c8dd555e81c6d3 [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>Examples - ant</title>
</properties>
<body>
<section name="ant">
<p>
This example works through modelling Apache Ant using CLI2, the
example is based on Apache Ant version 1.6.1 compiled on February 12
2004.
</p>
<p>
"Apache Ant is a Java-based build tool. In theory, it is kind of like
Make, but without Make's wrinkles." - For more information please
visit <a href="http://ant.apache.org/">http://ant.apache.org/</a>
</p>
<subsection name="Modelling">
<p>
To model the ant options we first need to create some Builders so that
each of the option instances can be created:
</p>
<source>final DefaultOptionBuilder obuilder = new DefaultOptionBuilder();
final ArgumentBuilder abuilder = new ArgumentBuilder();
final GroupBuilder gbuilder = new GroupBuilder();</source>
<p>
For each option we create an Option instance that will model it, built
using the Builder instances above:
</p>
<source>Option help =
obuilder
.withShortName("help")
.withShortName("h")
.withDescription("print this message")
.create();
Option projecthelp =
obuilder
.withShortName("projecthelp")
.withShortName("p")
.withDescription("print project help information")
.create();
Option version =
obuilder
.withShortName("version")
.withDescription("print the version information and exit")
.create();
Option diagnostics =
obuilder
.withShortName("diagnostics")
.withDescription("print information that might be helpful to diagnose or report problems.")
.create();
Option quiet =
obuilder
.withShortName("quiet")
.withShortName("q")
.withDescription("be extra quiet")
.create();
Option verbose =
obuilder
.withShortName("verbose")
.withShortName("v")
.withDescription("be extra verbose")
.create();
Option debug =
obuilder
.withShortName("debug")
.withShortName("d")
.withDescription("print debugging information")
.create();
Option emacs =
obuilder
.withShortName("emacs")
.withShortName("e")
.withDescription("produce logging information without adornments")
.create();
Option lib =
obuilder
.withShortName("lib")
.withDescription("specifies a path to search for jars and classes")
.withArgument(
abuilder
.withName("path")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option logfile =
obuilder
.withShortName("logfile")
.withShortName("l")
.withDescription("use given file for log")
.withArgument(
abuilder
.withName("file")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option logger =
obuilder
.withShortName("logger")
.withDescription("the class which is to perform logging")
.withArgument(
abuilder
.withName("classname")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option listener =
obuilder
.withShortName("listener")
.withDescription("add an instance of class as a project listener")
.withArgument(
abuilder
.withName("classname")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option noinput =
obuilder
.withShortName("noinput")
.withDescription("do not allow interactive input")
.create();
Option buildfile =
obuilder
.withShortName("buildfile")
.withShortName("file")
.withShortName("f")
.withDescription("use given buildfile")
.withArgument(
abuilder
.withName("file")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option property = new PropertyOption();
Option propertyfile =
obuilder
.withShortName("propertyfile")
.withDescription("load all properties from file with -D properties taking precedence")
.withArgument(
abuilder
.withName("name")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option inputhandler =
obuilder
.withShortName("inputhandler")
.withDescription("the class which will handle input requests")
.withArgument(
abuilder
.withName("class")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option find =
obuilder
.withShortName("find")
.withShortName("s")
.withDescription("search for buildfile towards the root of the filesystem and use it")
.withArgument(
abuilder
.withName("file")
.withMinimum(1)
.withMaximum(1)
.create())
.create();
Option targets = abuilder.withName("target").create();</source>
<p>
We now create a Group instance consisting of all the above options:
</p>
<source>Group options =
gbuilder
.withName("options")
.withOption(help)
.withOption(projecthelp)
.withOption(version)
.withOption(diagnostics)
.withOption(quiet)
.withOption(verbose)
.withOption(debug)
.withOption(emacs)
.withOption(lib)
.withOption(logfile)
.withOption(logger)
.withOption(listener)
.withOption(noinput)
.withOption(buildfile)
.withOption(property)
.withOption(propertyfile)
.withOption(inputhandler)
.withOption(find)
.withOption(targets)
.create();</source>
</subsection>
<subsection name="Querying">
<p>
Once the model is built, a CommandLine needs to be parsed:
</p>
<source>Parser parser = new Parser();
parser.setGroup(options);
CommandLine cl = parser.parse(args);</source>
<p>
The CommandLine can be tested for the presence of options using the
hasOption() methods which take either an option instance or a trigger
value to lookup against:
</p>
<source>if(cl.hasOption(help)) {
//displayHelp();
return;
}
if(cl.hasOption("-version")) {
//displayVersion();
return;
}</source>
<p>
For those options that have an argument, the argument needs to be
extracted and processed:
</p>
<source>if(cl.hasOption(logfile)) {
String file = (String)cl.getValue(logfile);
//setLogFile(file);
}</source>
<p>
Each target for ant to process could then be processed in order as
specified:
</p>
<source>List targetList = cl.getValues(targets);
for (Iterator i = targetList.iterator(); i.hasNext();) {
String target = (String) i.next();
//doTarget(target);
}</source>
</subsection>
<subsection name="Helping">
<p>
To generate a help page for ant we first need to create a
HelpFormatter and set some basic properties. The shell command is
the command that the user would have typed to invoke the application,
and the group is the group of options that compose the model.
</p>
<source>HelpFormatter hf = new HelpFormatter();
hf.setShellCommand("ant");
hf.setGroup(options);</source>
<p>
The first section of help will display the full usage string for the
application, the appearence of this line can be adjusted using the
HelpFormatter's fullUsageSettings property:
</p>
<source>hf.getFullUsageSettings().add(DisplaySetting.DISPLAY_GROUP_NAME);
hf.getFullUsageSettings().add(DisplaySetting.DISPLAY_GROUP_ARGUMENT);
hf.getFullUsageSettings().remove(DisplaySetting.DISPLAY_GROUP_EXPANDED);</source>
<p>
The main body of the help is based on a line or more of information
about each option in the model. DisplaySettings can be used again to
adjust which items are included in this display and which aren't. In
this case, we don't want to display any groups as the top one is the
only one present and can be inferred:
</p>
<source>hf.getDisplaySettings().remove(DisplaySetting.DISPLAY_GROUP_ARGUMENT);</source>
<p>
Each of the options identified by the displaySettings above has some
usage information displayed, usually this will be a minimal set of
DisplaySettings but these can be adjusted to get the desired effect:
</p>
<source>hf.getLineUsageSettings().add(DisplaySetting.DISPLAY_PROPERTY_OPTION);
hf.getLineUsageSettings().add(DisplaySetting.DISPLAY_PARENT_ARGUMENT);
hf.getLineUsageSettings().add(DisplaySetting.DISPLAY_ARGUMENT_BRACKETED);</source>
<p>
Finally, the help can be printed to System.out with a simple call to
<code>print()</code>:
</p>
<source>hf.print();</source>
</subsection>
</section>
</body>
</document>