| <?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> |