CmdLn: Java Command Line Parser

A command line parser for array of strings passed to Java main methods.

There are three ways to use the command line parser, as detailed with three examples below. Each of the examples creates a command line application that accepts --help --file and --delay arguments with the following help message:

demo command line application
  -f --file <?>   file to open
  --delay <?>     delay in seconds (default 5 seconds)

Option Enum

import com.Ostermiller.util.*;
/**
 * Associate each option with a Java enum.
 * Good when:
 * Need for a static context.
 * Compiler can enforce handling of all command line options.
 * Properly preserves argument ordering when a later option may cancel out an earlier option.
 * Drawbacks:
 * Glue code to associate each command line option with an enum.
 * Can create a long switch statement to deal with arguments
 * Does not work when arguments not known at compile time
 */
public class OptionEnum {
    private enum EnumOptions {
        HELP(new CmdLnOption("help",'h')),
        FILE(new CmdLnOption("file",'f').setRequiredArgument().setDescription("file to open")),
        DELAY(new CmdLnOption("delay").setOptionalArgument().setDescription("delay in seconds (default 5 seconds)"));
        private CmdLnOption option;
        private EnumOptions(CmdLnOption option){
            option.setUserObject(this);
            this.option = option;
        }
        private CmdLnOption getCmdLineOption(){
            return option;
        }
    }
    public static void main(String[] args) throws Exception {
        CmdLn cmdLn = new CmdLn(args).setDescription("demo command line application");
        for (EnumOptions option: EnumOptions.values()){
            cmdLn.addOption(option.getCmdLineOption());
        }
        String fileName = null;
        int delay = 0;
        for(CmdLnResult result: cmdLn.getResults()){
            switch((EnumOptions)result.getOption().getUserObject()){
                case HELP:{
                    cmdLn.printHelp();
                    System.exit(0);
                } break;
                case FILE:{
                    fileName = result.getArgument();
                } break;
                case DELAY:{
                    delay = 5000;
                    if (result.getArgumentCount() > 0){
                        delay = Integer.parseInt(result.getArgument()) * 1000;
                    }
                } break;
            }
        }
        if (delay > 0){
            Thread.sleep(delay);
        }
        if (fileName != null){
            // open file and do work...
        }
        for(String argument: cmd.getNonOptionArguments()){
            // other arguments
        }
    }
}

Call Back to Listeners

import com.Ostermiller.util.*;
/**
 * Associate each option with a listener.
 * Good when:
 * Multiple places need to know about command line options.
 * Properly preserves argument ordering when a later option may cancel out an earlier option.
 * Drawbacks:
 * Requires non-static context.
 */
public class OptionCallback {
    private String fileName = null;
    private int delay = 0;
    private void parseCommandLine(String[] args){
        final CmdLn cmdLn = new CmdLn(args).setDescription("demo command line application");
        cmdLn.addOption(
            new CmdLnOption("help",'h').setListener(
                new CmdLnListener(){
                    public void found(CmdLnResult result){
                        cmdLn.printHelp();
                        System.exit(0);
                    }
                }
            )
        );
        cmdLn.addOption(
            new CmdLnOption("file",'f').setRequiredArgument().setDescription("file to open").setListener(
                new CmdLnListener(){
                    public void found(CmdLnResult result){
                        fileName = result.getArgument();
                    }
                }
            )
        );
        cmdLn.addOption(
            new CmdLnOption("delay").setOptionalArgument().setDescription("delay in seconds (default 5 seconds)").setListener(
                new CmdLnListener(){
                    public void found(CmdLnResult result){
                        delay = 5000;
                        if (result.getArgumentCount() > 0){
                            delay = Integer.parseInt(result.getArgument()) * 1000;
                        }
                    }
                }
            )
        );
        cmdLn.parse();
    }
    public static void main(String[] args) throws Exception {
        OptionCallback optionCallback = new OptionCallback();
        optionCallback.parseCommandLine(args);
        if (optionCallback.delay > 0){
            Thread.sleep(optionCallback.delay);
        }
        if (fileName != null){
            // open file and do work...
        }
        for(String argument: cmd.getNonOptionArguments()){
            // other arguments
        }
    }
}

Options by Name

import com.Ostermiller.util.*;
/**
 * Query the command line for each option by name.
 * Good when:
 * Compact code desired.
 * Drawbacks:
 * Does not properly preserve argument ordering when a later option may cancel out an earlier option.
 */
public class OptionCallback {
    public static void main(String[] args) throws Exception {
        CmdLn cmdLn = new CmdLn(args).setDescription("demo command line application");
        cmdLn.addOptions(new CmdLnOption[]{
            new CmdLnOption("help",'h'),
            new CmdLnOption("file",'f').setRequiredArgument().setDescription("file to open"),
            new CmdLnOption("delay").setOptionalArgument().setDescription("delay in seconds (default 5 seconds)").
        });
        if(cmdLn.getResult('h').present()){
            cmdLn.printHelp();
            System.exit(0);
        }
        if(cmdLn.getResult("delay").present()){
            delay = 5000;
            if (cmdLn.getResult("delay").getArgumentCount() > 0){
                delay = Integer.parseInt(cmdLn.getResult("delay").getArgument()) * 1000;
            }
            Thread.sleep(delay);
        }
        if(cmdLn.getResult('f').present()){
            // open file and do work...
        }
        for(String argument: cmd.getNonOptionArguments()){
            // other arguments
        }
    }
}