Command option listeners are similar and defined by implementing
org.statefive.clic.CommandOptionListener, and must implement the following
method:
void option(String command, String option, Object value)
Let's look at implementing this for a top-level command named export, with the
same short and long option defined previously; this time we'll just assume that
the value type is file/java.io.File:
private String command;
private File filename;
// getters omitted
public void option(String command, String option, Object value) {
this.command = command;
switch(command) {
case "export":
switch(option) {
case "f":
case "file":
filename = (File) value;
break;
// other options omitted
}
break;
// other commands omitted
}
}
Assigning the value to the member command isn't detailed here but can be used
by API callers to determine which command was passed in via the command line.
For example, outside of the listener in our main application, we can do
something like:
String command = listener.getCommand();
if ("export".equals(command) {
File fileToExport = listener.getFilename();
// omitted: Do some export-based things...
}
Like OptionListener, if global.help was defined, each command also need to
cater for this for our CommandOptionListener - this will need to be done for
each defined command block:
public void option(String command, String option, Object value) {
this.command = command;
switch(command) {
case "export":
switch(option) {
case "h":
case "help":
System.exit(0);
break;
// other options omitted
}
break;
// other commands omitted
}
}
Command option listeners utilising unary switches should use the same method as
defined for OptionListeners, above, i.e. use a boolean value to determine if
the switch was defined.
For nested commands, the command parameter will be the path of the command.
Let's continue the example by adding a nested command to the export command,
named with-meta-data. Since the command is a sub-command of export, then the
command path will be export/with-meta-data:
public void option(String command, String option, Object value) {
this.command = command;
switch(command) {
case "export":
// export-based checks omitted
break
case "export/with-meta-data":
// with-meta-data checks omitted
break;
}
}
To listen for argument updates for commands, implementations must implement the
org.statefive.clic.CommandArgsListener interface with the following method:
void argument(String command, String name, int index, Object value);
As per the previous example, if no argument configurations are defined, the
name and value will have the same value of the command line argument, and
the index will be indexed from 0.
Likewise, if argument configurations are defined, the name will be the
argument configuration name.
The rules are the same as command option configurations regarding the command name - i.e., the command name will be the full path to the command being run without leading or trailing forward slashes.
Consider the following argument configuration for an export command:
command.name = export
command.usage = Export all files to the given directory: export <dir> <files...>
args.export-dir.length = 1
args.export-dir.type = dir
args.export-dir.properties = dirType = exists
args.files-to-export.type = file
args.files-to-export.properties = fileType = exists
… And the following argument implementation:
File exportDir;
public void argument(String name, int index, Object value) {
switch(name) {
case "export-dir":
exportDir = (File) value;
break;
case "files-to-export":
File fileToMove = (File) value;
File moveTo = new File(exportDir, fileToMove.getName());
if (moveTo.exists()) {
System.err.println("Cannot move " + fileToMove.getAbsolutePath() + "; " + moveTo.getAbsolutePath() + "already exists");
} else {
fileToMove.renameTo(moveTo);
}
break;
}
}