    1   /* CommandLineParser
    2    *
    3    * Created on Feb 2, 2004
    4    *
    5    * Copyright (C) 2004 Internet Archive.
    6    *
    7    * This file is part of the Heritrix web crawler (crawler.archive.org).
    8    *
    9    * Heritrix is free software; you can redistribute it and/or modify
    10   * it under the terms of the GNU Lesser Public License as published by
    11   * the Free Software Foundation; either version 2.1 of the License, or
    12   * any later version.
    13   *
    14   * Heritrix is distributed in the hope that it will be useful,
    15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17   * GNU Lesser Public License for more details.
    18   *
    19   * You should have received a copy of the GNU Lesser Public License
    20   * along with Heritrix; if not, write to the Free Software
    21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22   */
    23  package org.archive.crawler;
    24
    25  import java.io.PrintWriter;
    26  import java.util.List;
    27
    28  import org.apache.commons.cli.CommandLine;
    29  import org.apache.commons.cli.HelpFormatter;
    30  import org.apache.commons.cli.Option;
    31  import org.apache.commons.cli.Options;
    32  import org.apache.commons.cli.ParseException;
    33  import org.apache.commons.cli.PosixParser;
    34  import org.apache.commons.cli.UnrecognizedOptionException;
    35
    36
    37  /***
    38   * Print Heritrix command-line usage message.
    39   *
    40   * @author stack
    41   * @version $Id: CommandLineParser.java 4551 2006-08-29 00:47:56Z stack-sf $
    42   */
    43  public class CommandLineParser {
    44      private static final String USAGE = "Usage: ";
    45      private static final String NAME = "heritrix";
    46      private Options options = null;
    47      private CommandLine commandLine = null;
    48      private PrintWriter out = null;
    49      private String version = null;
    50
    51      /***
    52       * Block default construction.
    53       *
    54       */
    55      private CommandLineParser() {
    56          super();
    57      }
    58
    59      /***
    60       * Constructor.
    61       *
    62       * @param args Command-line arguments to process.
    63       * @param out PrintStream to write on.
    64       * @param version Heritrix version
    65       *
    66       * @throws ParseException Failied parse of command line.
    67       */
    68      public CommandLineParser(String [] args, PrintWriter out, String version)
    69      throws ParseException {
    70          super();
    71
    72          this.out = out;
    73          this.version = version;
    74
    75          this.options = new Options();
    76          this.options.addOption(new Option("h","help", false,
    77              "Prints this message and exits."));
    78          this.options.addOption(new Option("b", "bind", true,
    79              "Comma-separated list of IP addresses or hostnames for web server "
    80              + "to listen on.  Set to / to listen on all available\nnetwork "
    81              + "interfaces.  Default is 127.0.0.1."));
    82          this.options.addOption(new Option("p","port", true,
    83              "Port to run web user interface on.  Default: 8080."));
    84          this.options.addOption(new Option("a", "admin", true,
    85              "Login and password for web user interface administration. " +
    86              "Required (unless passed via the 'heritrix.cmdline.admin'\n" +
    87              "system property).  Pass value of the form 'LOGIN:PASSWORD'."));
    88          this.options.addOption(new Option("r", "run", false,
    89              "Put heritrix into run mode. If ORDER.XML begin crawl."));
    90          this.options.addOption(new Option("n", "nowui", false,
    91              "Put heritrix into run mode and begin crawl using ORDER.XML." +
    92              " Do not put up web user interface."));
    93          Option option = new Option("s", "selftest", true,
    94              "Run the integrated selftests. Pass test name to test it only" +
    95              " (Case sensitive: E.g. pass 'Charset' to run charset selftest).");
    96          option.setOptionalArg(true);
    97          this.options.addOption(option);
    98
    99          PosixParser parser = new PosixParser();
    100         try {
    101             this.commandLine = parser.parse(this.options, args, false);
    102         } catch (UnrecognizedOptionException e) {
    103             usage(e.getMessage(), 1);
    104         }
    105     }
    106
    107     /***
    108      * Print usage then exit.
    109      */
    110     public void usage() {
    111         usage(0);
    112     }
    113
    114     /***
    115      * Print usage then exit.
    116      *
    117      * @param exitCode
    118      */
    119     public void usage(int exitCode) {
    120         usage(null, exitCode);
    121     }
    122
    123     /***
    124      * Print message then usage then exit.
    125      *
    126      * The JVM exits inside in this method.
    127      *
    128      * @param message Message to print before we do usage.
    129      * @param exitCode Exit code to use in call to System.exit.
    130      */
    131     public void usage(String message, int exitCode) {
    132         outputAndExit(message, true, exitCode);
    133     }
    134
    135     /***
    136      * Print message and then exit.
    137      *
    138      * The JVM exits inside in this method.
    139      *
    140      * @param message Message to print before we do usage.
    141      * @param exitCode Exit code to use in call to System.exit.
    142      */
    143     public void message(String message, int exitCode) {
    144         outputAndExit(message, false, exitCode);
    145     }
    146
    147     /***
    148      * Print out optional message an optional usage and then exit.
    149      *
    150      * Private utility method.  JVM exits from inside in this method.
    151      *
    152      * @param message Message to print before we do usage.
    153      * @param doUsage True if we are to print out the usage message.
    154      * @param exitCode Exit code to use in call to System.exit.
    155      */
    156     private void outputAndExit(String message, boolean doUsage, int exitCode) {
    157         if (message !=  null) {
    158             this.out.println(message);
    159         }
    160
    161         if (doUsage) {
    162             HeritrixHelpFormatter formatter =
    163                 new HeritrixHelpFormatter();
    164             formatter.printHelp(this.out, 80, NAME, "Options:", this.options,
    165                 1, 2, "Arguments:", false);
    166             this.out.println(" ORDER.XML       Crawl order to run.\n");
    167         }
    168
    169         // Close printwriter so stream gets flushed.
    170         this.out.close();
    171         System.exit(exitCode);
    172     }
    173
    174     /***
    175      * @return Options passed on the command line.
    176      */
    177     public Option [] getCommandLineOptions() {
    178         return this.commandLine.getOptions();
    179     }
    180
    181     /***
    182      * @return Arguments passed on the command line.
    183      */
    184     public List getCommandLineArguments() {
    185         return this.commandLine.getArgList();
    186     }
    187
    188     /***
    189      * @return Command line.
    190      */
    191     public CommandLine getCommandLine() {
    192         return this.commandLine;
    193     }
    194
    195     /***
    196      * @return Returns the version.
    197      */
    198     public String getVersion() {
    199         return this.version;
    200     }
    201
    202     /***
    203      * Override so can customize usage output.
    204      *
    205      * @author stack
    206      * @version $Id: CommandLineParser.java 4551 2006-08-29 00:47:56Z stack-sf $
    207      */
    208     public class HeritrixHelpFormatter
    209     extends HelpFormatter {
    210         public HeritrixHelpFormatter() {
    211             super();
    212         }
    213
    214         public void printUsage(PrintWriter pw, int width,
    215                 String cmdLineSyntax) {
    216             out.println(USAGE + NAME + " --help");
    217             out.println(USAGE + NAME + " --nowui ORDER.XML");
    218             out.println(USAGE + NAME + " [--port=#]" +
    219                 " [--run] [--bind=IP,IP...] " +
    220                 "--admin=LOGIN:PASSWORD //\n\t[ORDER.XML]");
    221             out.println(USAGE + NAME + " [--port=#] --selftest[=TESTNAME]");
    222             out.println("Version: " + getVersion());
    223         }
    224
    225         public void printUsage(PrintWriter pw, int width,
    226             String app, Options options) {
    227             this.printUsage(pw, width, app);
    228         }
    229     }
    230 }