It appears that you want to build numerous CLI commands based simply on their "help descriptors"; a DSL of sorts. Instead of doing this string parsing, consider building the commands programmatically, for which there are numerous libraries (CLI being but one) and advantages.
Your example is already significantly complex enough that a second look at CLI (or one of the others) is warranted. You show required and optional args, each having either no-value or a default (though no means of indicating 'required' arg-values without a default, command descriptions, etc), and you still need to build a parser for the command line itself, verification, means of invoking handlers, etc...
Below is a list of command parsers I've found. None will parse your specific DSL, but they will allow you to build your commands programmatically, parse it, often verify and provide meaningful warnings, help handling, etc. Some even use annotations on objects to define commands, theoretically making maintenance easier.
Most are designed (and show examples) for parsing the arguments to your program, rather than numerous commands (natural-cli being an exception) but all should be able to do this - a simple class could wrap the parsing and options together:
static class CommandLine {
HashMap<String,Options> options = new HashMap<String,Options>();
public void register(String cmd, Options opts) {
options.put(cmd, opts);
}
public void parse(String line) {
// a better parser here would handle quoted strings
String[] split = line.split("\\s");
String cmd = split[0];
String[] args = new String[split.length-1];
if (args.length > 0)
System.arraycopy(split, 1, args, 0, args.length);
Options opts = options.get(cmd);
if (opts == null)
; // handle unknown command
else {
opts.parse(args);
// handle results...
opts.reset(); // required?
}
}
}
public static void main(String[] args) throws Exception {
CommandLine cl = new CommandLine();
cl.register("size", new Options()); // This will vary based on library Some
cl.register("create-char", new Options()); // require subclasses, others use builder
//... pattern, or other means.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
cl.parse(in.readLine());
}
}
Other Libraries
- CLI
- JewelCli: also uses annotations, and allows lists and enums for values. examples look promising
- natural-cli: allows cli with "human readable sentances". Seems geared towards your goal of multiple commands and their options, albiet with a different DSL and syntax.
- GNU Java Getopt: Used same way as above, though you initialize the Getopt object with the name of the command.
- JOpt Simple: Claims "simplicity over all others"
- JArgs
- args4j: uses annotations on separate classes created for each command
- JSAP
- CLAJR: uses reflection
- CmdLn
- ArgParser
- JCommando: uses XML config files.
- parse-cmd: uses Builder-pattern and method chaining to build parameters
- cli-parser: annotation based