Skip to content

ArgumentParser

Raven Computing edited this page Mar 4, 2020 · 3 revisions

ArgumentParser

Often you want a caller to be able to pass some arguments to your application at startup. The ArgumentParser class can help you with that so you don't have to write code for parsing the arguments over and over again. It supports different types of arguments.

Building an ArgumentParser

You cannot instantiate an ArgumentParser directly. Use an ArgumentParser.Builder to build your parser and to adjust what kind of arguments should be accepted.

Let's say that you want the caller to be able to pass an integer, a string and a boolean to your application at startup. You would have to do something like this:

ArgumentParser ap = new ArgumentParser.Builder()
	.integerArg("intArg")
	.optionalStringArg("stringArg")
	.optionalBooleanArg("booleanArg")
	.build();

The above code tells the parser to accept all three arguments with the specified key. An optional-prefix in the builder method name tells the parser that the specified argument is an optional argument, i.e. the caller can omit it. In the above example the caller has to provide at least the integer argument. Since "intArg" was built as an integer argument and "booleanArg" as a boolean argument, the caller must provide the values of those arguments as the appropriate type. For example, passing "-intArg=abcd" as an argument to the application will not work.

Parsing Arguments

After you've built your parser just call the parse() method on it and pass it the string array of your main() method holding the arguments. You must also catch an ArgumentParseException like this:

try{
    ap.parse(args);
}catch(ArgumentParseException ex){
    //handle
}

That's all you need to do. If all arguments are valid then you can simply get the values through the get*Arg() methods. For the above example you could do something like this:

Integer intArg = ap.getIntegerArg("intArg");
String stringArg = ap.getStringArg("stringArg", "myDefaultValue");
Boolean booleanArg = ap.getBooleanArg("booleanArg");

Since in the above example the string and boolean arguments are optional, the caller doesn't have to provide them, so they might be null. The getter for the string argument shows that you can directly specify a default value when querying arguments. If an argument was optional and the caller did not provide it, then the default value as given to the getter will be returned by the same.

Handling Invalid Arguments

If any argument is invalid then the parse() method will throw an exception. You can query the ArgumentParseException to see what argument caused it to be thrown and to get a human readable usage message you could print on std-out (or std-err for that matter). For example:

try{
    ap.parse(args);
}catch(ArgumentParseException ex){
    System.out.println(ex.getMessage());
    System.out.println(ex.hint());
}

You might also want to exit your application if any argument is invalid. Add appropriate code to the catch clause.

Helper Arguments

The argument parser treats so called helper arguments in a special way. Currently supported helper arguments are:

  • -help
  • -?
  • -version

They are all case insensitive and must be the first argument in the array. Because these kinds of arguments usually require a special action by the application, they will not throw an exception but you can find out if one of them got passed as an argument like this:

try{
    ap.parse(args);
}catch(ArgumentParseException ex){
    //handle invalid arg
}
if(ap.helpTriggered()){
    //handle -help or -? arg
}
if(ap.versionTriggered()){
    //handle -version arg
}

Restricting Arguments

Sometimes certain arguments are restricted in their accepted range. The ArgumentParser.Builder provides additional methods to declare that specific arguments are restricted. For example:

ArgumentParser ap = new ArgumentParser.Builder()
        .integerArg("intArg", 1, 10)
        .build();

The above code builds an ArgumentParser that does only accept the "intArg" argument if it is between 1 and 10 (both inclusive). You can also restrict string arguments. For example:

Set<String> set = new HashSet<String>(Arrays.asList(new String[]{"red", "green", "blue"}));
ArgumentParser ap = new ArgumentParser.Builder()
        .stringArg("color", set)
        .build();

This will only accept the "color" argument if it is in the specified set.

Clone this wiki locally