My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members
Links

Simple, flexible, lightweight annotation based CLI

Features:

  • L10N
  • Supports Map/Collection/File/String/boolean etc. data types
  • CommonBean for frequently used switches like '-help, -verbose'
  • Bean class is extensible
  • Extendable Usage module

Have you ever tired of doing this

if (args.length > 0 && !StringUtils.isEmpty(args[0])) {
   importFile = new File(args[0]);
}
if (args.length > 1 && !StringUtils.isEmpty(args[1])) {
   exportFile = new File(args[1]);
}

You're probably answering YES.

Have you ever gotten sick of the complex APIs you find on the Net?

You're probably answering YES again.

So, now we present the simple, lightweight solution, that's JaCli, an annotation based CLI.

Simple Form

1. Put the annotation on the private field that you want to make an argument

public final class Bean {
   @Argument(id = 0)
   private File basedir;
   @Argument(id = 1)
   private boolean verbose;

public File getBasedir() {
   return this.basedir;
}
public boolean isVerbose() {
   return this.verbose;
}
}

2. Resolve the argument, and set values into the bean

public static void main(String[] args) {
    Bean bean = new Bean();
    CommandLineParser.parse(bean, args);

    System.out.println("## check the basedir: " + bean.getBasedir());
    System.out.println("## check the verbose: " + bean.isVerbose());
}

A possible argument line is

    Main /data true

Option Form

1. Put the annotation on the private field that you want to make an argument

public class SampleBean extends CommonBean {
    @Argument(shortName = "d", option = "output", documentation = "OUTPUT_DIR")
    private File outputDir;

    @Argument(option = "p", documentation = "PACKAGE_MAP", delimiter="=")
    private Map<String, String> packageMap;

    @Argument(shortName = "c", option = "compile")
    private boolean compile;

    @Argument(documentation = 'file path of the wsdl file')
    private File wsdlLocation;

    // ... omit the getter/setter
    // find the complete sample in the dist.
}

Messages.properties file are used to define the command documentation

HELP = print the help messages
VERBOSE = produce verbose output

Messages_zh_CN.properties to define the translation of doc in Chinese

HELP = \u6253\u5370\u5e2e\u52a9\u4fe1\u606f
VERBOSE = \u663e\u793a\u6700\u8be6\u7ec6\u4fe1\u606f

2. Resolve the argument, and set values into the bean

public static void main(String[] args) {
    SampleBean bean = new SampleBean ();
    CommandLine commandLine = CommandLineParser.parse(bean, args);

    System.out.println("## check the basedir: " + bean.getOutput());
    System.out.println("## check the verbose: " + bean.isVerbose());
    System.out.println("## check the packageMap: " +
    bean.getPackageMap().keySet());
    System.out.println("## check the packageMap: " +
    bean.getPackageMap().values());

    commandLine.printUsage();

    commandLine.printUsage(new MyUsage());
}

Possible argument lines are:

Main -d /data -v -p http://cxf.apache.org=org.cxf -p http://code.google/p/jacli=org.jacli /src/hello.wsdl

Or

Main -verbose -d /data /src/hello.wsdl

Can it be simpler? Let us know your ideas, and post your requirements as

Exception Handling

    SampleBean bean = new SampleBean ();
    CommandLine commandLine = CommandLineParser.parse(bean, args);
    if (commandLine.hasException()) {
        for (Exception e : commandLine.getExceptions()) {
           System.err.println(e.getMessage());
        }
        commandLine.printUsage();
    }

Unix Style Prefix

If you like the Unix style prefix, for example

  -a, --all
  -A, --almost-all
      --author
  -b, --escape

Use the '-' for the short name and '--' for the full name, in JaCli, you can pass in the prefix

    SampleBean bean = new SampleBean ();
    CommandLine commandLine = CommandLineParser.parse(bean, args, "--", "-");

JaCli's Buddy

Using CSVParser with the JaCli you can parse a CSV file to a Collection of Beans

Powered by Google Project Hosting