public final class CommandLineOptions extends Object
main()
method and configures a Java bean
accordingly.parse(String[], Object)
Modifier and Type | Method and Description |
---|---|
static int |
applyCommandLineOption(String optionName,
Method option,
String[] args,
int optionArgumentIndex,
Object target)
Parses the command line option's arguments from the args and invokes the method.
|
static Method |
getMethodForOption(String optionName,
Class<?> targetClass)
Determines the method of
target.getClass() that is applicable for the given optionName. |
static String[] |
parse(String[] args,
Object target)
Invokes methods of the target object based on the args.
|
static void |
printResource(Class<?> baseClass,
String relativeResourceName,
Charset resourceCharset,
OutputStream outputStream)
Reads (and decodes) the contents of a resource, replaces all occurrences of
"
${ system-property-name} " with the value of the designated system property,
and writes the result to the outputStream (typically System.out ). |
static void |
printResource(ClassLoader classLoader,
String resourceName,
Charset resourceCharset,
OutputStream outputStream)
Reads (and decodes) the contents of a resource, replaces all occurrences of
"
${ system-property-name} " with the value of the designated system property,
and writes the result to the outputStream (typically System.out ). |
public static String[] parse(String[] args, Object target) throws CommandLineOptionException
All public methods of the target (including those declared by superclasses) are regarded candidates iff
they are annotated with the CommandLineOption
annotation.
The possible "names" of the command line option are derived from the name
element of the CommandLineOption
annotation, or, if that is missing, from the method name
(see examples below).
When an element of args equals such a name, then the following elements in args are converted to match the parameter types of the method (see example code below). After that, the method is invoked with the arguments.
Parsing terminates iff either
"--"
is reached (which is consumed)"-"
is reached (which is notconsumed)Example:
public class MyMain { // ... // This one maps to "-font-size <x>" and "--font-size <x>". @CommandLineOption public static void setFontSize(double size) { System.out.println("fontSize=" + size); } // This one maps to "-help" and "--help". @CommandLineOption public static void help() {} // This one maps to "-alpha" and "--alpha". @CommandLineOption(name = "alpha") public static void method1() {} // This one maps to "-beta" and "--gamma". @CommandLineOption(name = { "-beta", "--gamma" }) public static void method2() {} // This one maps to "-foo <a> <b> <c>". (A single dashes may be used instead of the double dash.) @CommandLineOption public static void foo(int one, String two, java.util.Pattern three) {} // This one maps to "--person [ --name <>name> ] [ --age <age> ]". (Single dashes may be used // instead of the double dashes.) @CommandLineOption public static void addPerson(Person p) {} public static class Person { public void setName(String name) {} public void setAge(int age) {} } } ... final MyMain main = new MyMain(); String[] args = { "--font-size", "17.5", "a", "b" }; System.out.println(Arrays.toString(args)); // Prints "[--font-size, 17.5, a, b]". args = MainBean.parseCommandLineOptions(args, main); // Prints "fontSize=17.5". System.out.println(Arrays.toString(args); // Prints "[a, b]".
To enforce that a particular command line option must be given a specific number of times, use the
cardinality()
element of the @CommandLineOption
annotation:
@CommandLineOption(cardinality = CommandLineOption.Cardinality.MANDATORY) setColor(String color) { this.color = color; }
For this example, it is now guaranteed that parse(String[], Object)
will invoke the "setColor()
" method exactly once.
The default value for the command line option cardinality is CommandLineOption.Cardinality.OPTIONAL
.
To enforce that a particular number of a set of command line options must be given, use the group()
element of the @CommandLineOption
annotation:
@CommandLineOption(group = Sources.class) setFile(File file) { this.file = file; } @CommandLineOption(group = Sources.class) setStdin() { this.stdin = true; } // This interface solely serves as the "connector" between the related command line options; it is (typically) // not used otherwise. @CommandLineOptionGroup(cardinality = CommandLineOptionGroup.Cardinality.EXACTLY_ONE) interface Sources {}
For this example, it is now guaranteed that parse(String[], Object)
will invoke exactly one of the
methods "setFile()
" and "setStdin()
".
The default value for the command line option group cardinality is ZERO_OR_ONE
.
args strings are converted to match the parameter types of the methods as follows:
CommandLineOptionException
- An error occurred during the parsing; typically a command-line application
would print the message of the exception to STDERR and call "System.exit(1)
"@Nullable public static Method getMethodForOption(String optionName, Class<?> targetClass)
target.getClass()
that is applicable for the given optionName. The
rules for matching are as follows:
@CommandLineOption
.name
" element:
name
value starts with "-":
name
value.
name
value does not start with "-":
"-"+name
or "--"+name
@CommandLineOption(name = { "alpha", "-beta" }) public void method() { ...
"-alpha"
, "--alpha"
and "-beta"
.
name
" element:
lower-case-hyphenated
, then prefixed with "-" and "--", equals the
optionName.
null
iff there is no applicable methodpublic static int applyCommandLineOption(String optionName, Method option, String[] args, int optionArgumentIndex, @Nullable Object target) throws CommandLineOptionException
Iff the method is a varargs
method, then all remaining arguments are converted to an array.
optionArgumentIndex
- The position of the first option argument in argsCommandLineOptionException
- An error occurred during the parsingAssertionError
- The method is not annotated with @CommandLineOption
public static void printResource(Class<?> baseClass, String relativeResourceName, @Nullable Charset resourceCharset, OutputStream outputStream) throws IOException
${
system-property-name}
" with the value of the designated system property,
and writes the result to the outputStream (typically System.out
).
The resource is found through the baseClass's class loader and the name "
package-name/
simple-class-name.
relativeResourceName"
, where all periods in the package-name have been replaced with slashes.
To ensure that the resource is decoded with the same charset as it was encoded, you should not use the JVM charset (which could be different in the build environment and the runtime environment).
baseClass
- Poses the base for the resource namerelativeResourceName
- The name of the resource, relative to the baseClassresourceCharset
- The charset to use for decoding the contents of the resource; null
for the
JVM default charsetFileNotFoundException
- The resource could not be foundIOException
Class.getResource(String)
public static void printResource(ClassLoader classLoader, String resourceName, @Nullable Charset resourceCharset, OutputStream outputStream) throws IOException
${
system-property-name}
" with the value of the designated system property,
and writes the result to the outputStream (typically System.out
).
The resource is found through the classLoader and (absolute) resourceName.
To ensure that the resource is decoded with the same charset as it was encoded, you should not use the JVM charset (which could be different in the build environment and the runtime environment).
resourceCharset
- The charset to use for decoding the contents of the resource; null
for the
JVM default charsetFileNotFoundException
- The resource could not be foundIOException
ClassLoader.getResource(String)
Copyright © 2018 Arno Unkrig. All rights reserved.