Статьи

Интерфейсы командной строки Java (часть 1): CLI Apache Commons

Хотя я обычно использую Groovy для написания JVM-сценариев, запускаемых из командной строки, бывают случаи, когда мне нужно проанализировать параметры командной строки в приложениях Java, и существует множество библиотек, доступных для разработчиков Java для использования для анализа параметры командной строки. В этой статье я расскажу об одной из самых известных библиотек синтаксического анализа Java: Apache Commons CLI .

Я уже писал в блоге об Apache Commons CLI , но этому посту уже более восьми лет и он описывает Apache Commons CLI 1.1 . Два класса, которые я продемонстрировал в этом посте, GnuParser и PosixParser , с тех пор устарели. Примеры в этом текущем посте основаны на Apache Commons CLI 1.4 и используют более новый DefaultParser, который был представлен с CLI 1.3, чтобы заменить GnuParser и PosixParser .

Документация Apache Commons CLI « Введение » объясняет, как Commons CLI выполняет «три этапа [обработки] командной строки» («определение», «анализ» и «опрос»). Эти три этапа отображаются в CLI Commons на классы Option и Options («определение»), на интерфейс CommandLineParser («синтаксический анализ») и на класс CommandLine («опрос»).

Для примеров, построенных здесь с помощью Apache Commons CLI, ожидаемые аргументы командной строки относительно просты. Один аргумент является необязательным и, если он указан, указывает, что подробный вывод включен. Другой аргумент является обязательным и используется для указания файла, который должен обрабатываться мнимым приложением. Необязательный аргумент не имеет значения, связанного с флагом, и выражается как -v или --verbose . За обязательным аргументом должно следовать значение, представляющее собой путь и имя файла. Этот флаг либо -f либо --file . В следующем листинге кода демонстрируется использование Option.Builder интерфейса командной строки Commons (представлен в Commons CLI 1.3 ) для создания ожидаемых параметров в рамках этапа «определения».

Пример использования Apache Commons CLI Option.Builder для «Стадии определения»

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * "Definition" stage of command-line parsing with Apache Commons CLI.
 * @return Definition of command-line options.
 */
private static Options generateOptions()
{
   final Option verboseOption = Option.builder("v")
      .required(false)
      .hasArg(false)
      .longOpt(VERBOSE_OPTION)
      .desc("Print status with verbosity.")
      .build();
   final Option fileOption = Option.builder("f")
      .required()
      .longOpt(FILE_OPTION)
      .hasArg()
      .desc("File to be processed.")
      .build();
   final Options options = new Options();
   options.addOption(verboseOption);
   options.addOption(fileOption);
   return options;
}

Шаблон « Построитель », реализованный для интерфейса командной строки Apache Commons, как показано в приведенном выше примере, обладает преимуществами шаблона компоновщика, такими как создание Option в полностью заполненном состоянии в одном операторе и использование хорошо читаемых методов компоновщика для установки различных полей этого экземпляра. В моем предыдущем посте, посвященном Apache Commons CLI, демонстрируется использование альтернативного традиционного подхода конструктора для создания экземпляров Option .

Определив параметры командной строки, пришло время перейти к этапу «синтаксического анализа», и в следующем листинге кода показано, как выполнить синтаксический анализ интерфейса командной строки Apache Commons, просто вызвав метод CommandLinePaser.parse ().

Разбор параметров командной строки с помощью Commons CLI

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * "Parsing" stage of command-line processing demonstrated with
 * Apache Commons CLI.
 *
 * @param options Options from "definition" stage.
 * @param commandLineArguments Command-line arguments provided to application.
 * @return Instance of CommandLine as parsed from the provided Options and
 *    command line arguments; may be {@code null} if there is an exception
 *    encountered while attempting to parse the command line options.
 */
private static CommandLine generateCommandLine(
   final Options options, final String[] commandLineArguments)
{
   final CommandLineParser cmdLineParser = new DefaultParser();
   CommandLine commandLine = null;
   try
   {
      commandLine = cmdLineParser.parse(options, commandLineArguments);
   }
   catch (ParseException parseException)
   {
      out.println(
           "ERROR: Unable to parse command-line arguments "
         + Arrays.toString(commandLineArguments) + " due to: "
         + parseException);
   }
   return commandLine;
}

Обратите внимание, что этот код, использующий более новую версию PosxParser интерфейса Apache Commons, создает экземпляр DefaultParser для выполнения анализа, а не PosxParser или GnuParser как это было в GnuParser коде .

После определения объектов командной строки и анализа командной строки настало время этапа опроса. Следующий листинг кода демонстрирует поддержку интерфейса командной строки Apache Commons CLI.

Опрос командной строки с помощью Commons CLI

1
2
3
4
5
final boolean verbose =
   commandLine.hasOption(VERBOSE_OPTION);
final String fileName =
   commandLine.getOptionValue(FILE_OPTION);
out.println("The file '" + fileName + "' was provided and verbosity is set to '" + verbose + "'.");

Приведенный выше листинг кода демонстрирует использование CommandLine.hasOption (), чтобы определить, присутствует ли конкретный флаг опции, независимо от того, предоставлено ли значение для этого флага (подходит для -v / --verbose в нашем примере). Аналогично, код показывает, что CommandLine.getOptionValue () можно использовать для получения значения, связанного с предоставленным флагом командной строки (соответствует параметру -f / --file в нашем примере).

Следующий снимок экрана демонстрирует вывод из простого примера, чьи списки кодов были показаны выше, и они демонстрируют поддержку параметров командной строки многословия и пути / местоположения файла, описанных выше.

Второй снимок экрана демонстрирует вывод интерфейса командной строки Commons, когда параметры командной строки не содержат обязательного аргумента командной строки.

Полезной частью функциональности для любой среды построения синтаксического анализа командной строки Java является возможность поддержки использования и справочной информации. Это достигается с помощью HelpFormatter CLI Commons . В следующем листинге кода показано использование HelpFormatter для HelpFormatter справки и информации об использовании, а снимок экрана после листинга кода демонстрирует вид справки и использования при использовании.

Получение сведений об «использовании» и «помощи» с помощью CLI Commons

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 * Generate usage information with Apache Commons CLI.
 *
 * @param options Instance of Options to be used to prepare
 *    usage formatter.
 * @return HelpFormatter instance that can be used to print
 *    usage information.
 */
private static void printUsage(final Options options)
{
   final HelpFormatter formatter = new HelpFormatter();
   final String syntax = "Main";
   out.println("\n=====");
   out.println("USAGE");
   out.println("=====");
   final PrintWriter pw  = new PrintWriter(out);
   formatter.printUsage(pw, 80, syntax, options);
   pw.flush();
}
 
/**
 * Generate help information with Apache Commons CLI.
 *
 * @param options Instance of Options to be used to prepare
 *    help formatter.
 * @return HelpFormatter instance that can be used to print
 *    help information.
 */
private static void printHelp(final Options options)
{
   final HelpFormatter formatter = new HelpFormatter();
   final String syntax = "Main";
   final String usageHeader = "Example of Using Apache Commons CLI";
   final String usageFooter = "See http://marxsoftware.blogspot.com/ for further details.";
   out.println("\n====");
   out.println("HELP");
   out.println("====");
   formatter.printHelp(syntax, usageHeader, options, usageFooter);
}

В этом посте продемонстрировано использование интерфейса командной строки Apache Commons для достижения некоторых наиболее распространенных функций, связанных с синтаксическим анализом командной строки в приложениях Java, включая параметр «определение», «синтаксический анализ» аргументов командной строки, «опрос» проанализированных аргументов командной строки, и справка / подробности использования, связанные с аргументами командной строки. Вот некоторые дополнительные характеристики интерфейса командной строки Apache Commons, которые следует учитывать при выборе платформы или библиотеки, которые помогут при синтаксическом анализе командной строки в Java.

Для меня одно из самых больших преимуществ интерфейса командной строки Apache Commons при реализации интерфейсов командной строки в простых приложениях Java состоит в том, что я уже знаком со встроенным в Groovy CliBuilder . Поскольку я использую Groovy гораздо чаще для простых сценариев и инструментов на основе командной строки, чем я использую Java, это знакомство с Groovy по основному использованию Apache Commons CLI полезно при возвращении к Java.

Дополнительные ссылки