Building a Command-Line Interface


As shown in the preparation code of CommandLineDemo in Listing 13-1, the short versions of the arguments for the command-line application are provided as String values. These values are used in several places in the application.

As part of the initialization, the getOptions() method returns a configured set of CLI options. These options are used both to parse the incoming arguments as well as generate the output of the "help" documentation displayed upon request or when a user enters incorrect input. Various Option objects are used to configure the various kinds of optionsfor example, some options are merely off/on switches, whereas others accept an additional argument.

Listing 13-1. CLI Example Initialization
 package com.cascadetg.ch13; import java.util.Iterator; import java.util.Map; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.MissingArgumentException; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.PosixParser; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.lang.SystemUtils; public class CommandLineDemo {     public static final String VERBOSE = "v";     public static final String RECURSION = "r";     public static final String IGNORE_JAVA_CP = "ijcp";     public static final String IGNORE_BOOT_CP = "ibcp";     public static final String USER_CP = "p";     public static final String SEARCH = "s";     public static final String HELP = "?";     public static final boolean HAS_ARGUMENTS = true;     public static final boolean NO_ARGUMENTS = false;     public static Options getOptions()     {         Options myOptions = new Options();         Option verbose = new Option(VERBOSE, "verbose", NO_ARGUMENTS,                 "Show additional details");         Option help = new Option(HELP, "help", NO_ARGUMENTS,                 "Show available options");         Option recursive = new Option(                 RECURSION,                 "recursion",                 HAS_ARGUMENTS,          "Search recursively in specified directories. Default (-1) is"                         + " unlimited depth. 0 for no recursion.");         recursive.setType(Integer.class);         recursive.setArgName("depth");         Option ignoreJavaClassPath = new Option(IGNORE_JAVA_CP,                 "ignoreJavaCP", NO_ARGUMENTS,                 "Ignore the system Java class path setting");         Option ignoreBootClassPath = new Option(IGNORE_BOOT_CP,                 "ignoreBootCP", NO_ARGUMENTS,                 "Ignore the Java boot class path setting");         Option searchClass = new Option(SEARCH, "search",                 HAS_ARGUMENTS,                 "REQUIRED: The fully qualified class name to find "                         + "(e.g. java.lang.String)");         searchClass.setArgName("classname");         searchClass.setType(String.class);         Option searchDirectory = new Option(USER_CP, "path",                 HAS_ARGUMENTS,                 "Set additional user defined search path[s]");         searchDirectory.setArgName("path["                 + SystemUtils.PATH_SEPARATOR + "path...]");         searchDirectory.setType(String.class);         myOptions.addOption(searchClass);         myOptions.addOption(verbose);         myOptions.addOption(recursive);         myOptions.addOption(ignoreJavaClassPath);         myOptions.addOption(ignoreBootClassPath);         myOptions.addOption(searchDirectory);         myOptions.addOption(help);         return myOptions;     } 

Listing 13-2 shows how the output is generated upon successful configuration and execution of ClassPathTool. The returned information is a Map, with the key being the path of the located directory or file and the value being the timestamp of the file.

Listing 13-2. CLI Output
 public static void displayResults(ClassPathTool cp) {     Map foundEntries = cp.getEntries();     if (foundEntries.size() > 0)     {         System.out.println();         System.out.println("Found " + cp.getSearchClass()                 + " at :");         Iterator found = foundEntries.keySet().iterator();         while (found.hasNext())         {             Object foundFile = found.next();             System.out.print("[");             System.out.print(foundEntries.get(foundFile));             System.out.print("] ");             System.out.println(foundFile.toString());         }         System.out.println();         System.out.println("Files checked: "                 + cp.filesChecked);         System.out.println("Directories checked: "                 + cp.directoriesChecked);         System.out.println("Elapsed time: "                 + cp.getTimeElapsed() / 1000 + "."                 + cp.getTimeElapsed() % 1000 + " sec");     } else     {         System.out.println("Unable to find entry.");     } } 

Listing 13-3 shows how the command-line options parsed by CLI (via the CommandLine object) are used to configure the ClassPathTool instance. Given that the CommandLine object performs the "heavy lifting" of parsing the input, the actual configuration and execution of ClassPathTool is quite straightforward.

Listing 13-3. Using CLI to Configure ClassPathTool
 public static void useApp(CommandLine line) throws Exception {     if (!line.hasOption(SEARCH))     {         throw new MissingArgumentException(                 "No search class specified.");     } else     {         System.out.println("Searching for "                 + line.getOptionValue(SEARCH) + "...");     }     ClassPathTool cp = new ClassPathTool();     cp.setSearchClass(line.getOptionValue(SEARCH));     if (line.hasOption(RECURSION))     {         cp.setMaxSearchDepth(Integer.parseInt(line                 .getOptionValue(RECURSION)));     }     if (line.hasOption(VERBOSE))         cp.setVerbose(true);     if (line.hasOption(IGNORE_JAVA_CP))         cp.setUseJavaClassPath(false);     if (line.hasOption(IGNORE_BOOT_CP))          cp.setUseBootClassPath(false);     if (line.hasOption(USER_CP))         cp.setUserDefinedClassPath(line                 .getOptionValue(USER_CP));     displayResults(cp); } 

Listing 13-4 shows the actual main() method and the core process behind the use of CLI. A CommandLineParser is created, the options defined in getOptions and the command-line arguments are passed to the parser, and assuming no exceptions are thrown, execution proceeds normally. If the user entered -? as an option or an exception is thrown, the application prints the help output and terminates. Note that the same options used to configure the parser are used to generate the help information.

Listing 13-4. Running ClassPathTool with CLI
     public static void main(String[] args)     {         try         {             CommandLineParser parser = new PosixParser();             CommandLine line = parser.parse(getOptions(), args);             if (line.hasOption("?"))             {                 HelpFormatter formatter = new HelpFormatter();                 formatter.printHelp("CommandLineDemo",                         getOptions());             } else             {  useApp(line); }         } catch (Exception e)         {             System.out.println("ERROR: " + e.getClass());             System.out.println(e.getMessage());             HelpFormatter formatter = new HelpFormatter();             formatter.printHelp("CommandLineDemo", getOptions());         }     } } 



    Apache Jakarta Commons(c) Reusable Java Components
    Real World Web Services
    ISBN: N/A
    EAN: 2147483647
    Year: 2006
    Pages: 137
    Authors: Will Iverson

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net