CLC format is a simple properties-based configuration allowing defining of:
The addProperties(InputStream) call can be called multiple times in order to
load properties from several different sources; in addition there's also the
addProperties(File) API call to load properties directly from a file rather
than an input stream. Both calls can be intermixed and called in any order for
any number of properties files or streams. Properties will be added in the order
that they are added by the addProperties calls.
The structure of the command line configuration is strictly ordered: global definitions must be defined first, followed by option definitions, followed by argument definitions (if present).
Commands, if defined, must come after the either the last defined top-level option (if no argument definitions exist), or after the last argument for the application.
If commands are defined they follow the same rules as top-level options and arguments - options are defined first, followed by arguments for the command (if present), and a new command after the first follows the same rules, and so on.
Since the configuration is properties-based, all definitions follow the form
<key> = <value>
It's worth noting that all global properties benefit from using manifest entry
text substitutions - that is, properties can be extracted from the
META/MANIFEST.MF file (when present) to substitute entries of the form
${manifest:<manifest-entry>}
For example if the manifest file contains an Implementation-Version entry for
the application version, this can be substituted into the version text rather
than hard-coding the version of the application directly into the properties.
Let's look at each of these in turn.
All global definitions and option configuration descriptions benefit from being able to make text substitutions of two different forms:
${manifest:<manifest-entry-name>}; and${resoure:<resource-name>}.Substitutions of this form enable manifest entry values to be substituted into text. This can be useful in any number of situations.
For example when defining the command usage of the global definition (oulined
below), rather than hard-coding the application name, we can reference the name
of the application as it is defined in the MANIFEST.MF file. Say, for example,
that the manifest file has an entry as follows:
Application-Name: foobar
… Then defining the command usage with the following entry:
${manifest:Application-Name}
… Will cause foobar to be substituted into the text of the command usage
when the CLC file is parsed.
Likewise, if the manifest file contains an Implementation-Version entry, then
applying
${manifest:Implementation-Version}
… Can be inserted into the global definition for the application version, again enabling the version to be defined dynamically rather than hard coded.
Using resource file substitutions (where a resource is a file embedded into the application at compile time) can substitute the entirety of the text from the file into CLC definitions. Furthermore resource files can themselves contain manifest entry susbstitutions.
When formatting resource files for inclusion into CLC files, a few rules need to
be applied since the commons-cli help formatter strips newlines out of the
text being added.
Therefore when defining paragraphs, always add a newline to the start (or end)
of repeated blocks of text; likewise, for newlines, add \n to the empty line
(because the API will strip the actual newline out) which means the \n will
remain in place.
Consider the following example command header resource file:
All properties will be treated as top-level (non-command based) options;
however, the API provides the ability to create commands that will have
properties associated with them. To take advantage of this, file names of
properties files can be prefixed by the colon character, with the name of the
command defined before the colon. All properties files defined after such a
definition will be associated with the previously defined command.\n
For example, to create a command named 'export-files' from a file named
'cmd1.props', the following definition would be applied:\n
export-files:cmd1.props\n
Although this is how we'd like to present the text in the help output, it will render the following output when help is invoked:
All properties will be treated as top-level (non-command based)
options;however, the API provides the ability to create commands that will
haveproperties associated with them. To take advantage of this, file names
ofproperties files can be prefixed by the colon character, with the name
of thecommand defined before the colon. All properties files defined after
such adefinition will be associated with the previously defined command.
For example, to create a command named 'export-files' from a file named
'cmd1.props', the following definition would be applied:
export-files:cmd1.props
Notice how lines have been joined together and the newlines from the resource file have been stripped out.
Instead, applying the above rules of adding whitespace and \n to newlines, as
follows:
All properties will be treated as top-level (non-command based) options;
however, the API provides the ability to create commands that will have
properties associated with them. To take advantage of this, file names of
properties files can be prefixed by the colon character, with the name of the
command defined before the colon. All properties files defined after such a
definition will be associated with the previously defined command.\n
\n
For example, to create a command named 'export-files' from a file named
'cmd1.props', the following definition would be applied:\n
\n
export-files:cmd1.props\n
\n
Notice how all lines for the paragraphs have been prefixed with a single space -
this ensures that as lines are built the end line of the previous section is
separated by a space before appending the next line. Likewise, the ‘natural’
newlines of the file have now been appended to with ‘\n’ so that the
commons-cli API adds the newlines in correctly. The following output is
generated when invoking help as a result:
All properties will be treated as top-level (non-command based) options;
however, the API provides the ability to create commands that will have
properties associated with them. To take advantage of this, file names of
properties files can be prefixed by the colon character, with the name of
the command defined before the colon. All properties files defined after
such a definition will be associated with the previously defined command.
For example, to create a command named 'export-files' from a file named
'cmd1.props', the following definition would be applied:
export-files:cmd1.props