Статьи

Интерфейсы командной строки Java (часть 5): JewelCli

Посмотрев на обработку командной строки в Java с помощью Apache Commons CLI , args4j , jbock и Commandline в предыдущих статьях , я обращаю внимание в этом посте на использование JewelCli для выполнения аналогичной обработки аргументов командной строки в Java.

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

«Определение» JewelCli реализовано с аннотированным интерфейсом

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package examples.dustin.commandline.jewelcli;
 
import com.lexicalscope.jewel.cli.Option;
 
/**
 * Interface defining JewelCli-friendly command-line parameters.
 */
public interface MainCommandLine
{
   @Option(shortName="f", description="Name and path of file to be used.")
   String getFile();
 
   @Option(shortName="v", description="Indicate whether status should be reported verbosely.")
   boolean isVerbose();
 
   @Option(helpRequest=true, description="Usage details on command-line arguments.")
   boolean getHelp();
}

Простой интерфейс, показанный выше, объединяет многое из обработки в командной строке. Для этих опций короткие имена с одним дефисом явно указываются с shortName элемента типа аннотации shortName и неявно указываются через имя метода «get» (хотя элемент типа аннотации longName доступен для явного указания версии длинного имени [двойных дефисов] переключатель). Опции командной строки также имеют свои соответствующие описания, предоставленные посредством аннотации Option . Использование helpRequest=true описывает, какой параметр командной строки следует использовать для отображения информации об использовании / справке. В этом случае, поскольку метод аннотации называется getHelp() , ключ --help будет отображать информацию об использовании. Если бы я назвал метод getDustin() и аннотировал его с помощью @Option(helpRequest=true) , переключатель был бы --dustin для отображения использования.

JewelCli использует преимущества соглашения над конфигурацией в случаях, кроме длинного имени коммутатора, совпадающего с именами методов. С аннотированными определениями соответствующих параметров интерфейса командной строки, как показано выше, переключатель многословия (который возвращает boolean ) является необязательным. Переключатель имени файла необходим, потому что его соответствующий метод getFile() возвращает String . Если бы я хотел сделать имя файла необязательным, я мог бы предоставить defaultValue для аннотации defaultValue в @Option getFile() например @Option(defaultValue="") .

Благодаря интерфейсу (в данном случае названному MainCommandLine ), помеченному аннотациями JewelCli @Option , мы можем перейти к этапу «синтаксического анализа» с помощью JewelCli. Это продемонстрировано вместе с этапом «допроса» в следующем листинге кода для Main .

Этапы «разбора» и «допроса» с JewelCli

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package examples.dustin.commandline.jewelcli;
 
import static java.lang.System.out;
 
import com.lexicalscope.jewel.cli.CliFactory;
 
/**
 * Demonstrates use of JewelCli for parsing command-line
 * parameters in Java.
 */
public class Main
{
   public static void main(final String[] arguments)
   {
      final MainCommandLine main = CliFactory.parseArguments(MainCommandLine.class, arguments);
      out.println("You specified file '" + main.getFile() + "' with verbosity setting of '" + main.isVerbose() + "'.");
   }
}

Только что показанный класс Main имеет одну строку, которая «анализирует» [вызов CliFactory.parseArguments(Class<T>, String...) ] и одну строку, которая «опрашивает» [строку, которая обращается к методам, определенным в JewelCli- аннотированный интерфейс, показанный ранее].

Следующие три снимка экрана демонстрируют примеры кода на основе JewelCli в действии. Первое изображение демонстрирует использование --help для просмотра использования (обратите внимание, что трассировка стека включена в вывод). Второе изображение показывает различные комбинации длинных ( - ) и коротких ( -- ) опционных переключателей. Третье изображение показывает выходное сообщение и связанную трассировку стека, которые представлены, когда не указан обязательный аргумент командной строки (в данном случае --file или -f ).

Перечни кодов для обоих классов, использованные в этом посте для демонстрации применения JewelCli, доступны на GitHub .

Вот некоторые дополнительные характеристики JewelCli, которые следует учитывать при выборе библиотеки, чтобы помочь с анализом командной строки в Java.

  • JewelCli имеет открытый исходный код и распространяется по лицензии Apache Software License версии 2 .
  • Текущий JAR JewelCli ( 0.8.9 ) ( jewelcli-0.8.9.jar / февраль 2014) имеет размер приблизительно 542 КБ.
  • Для использования JewelCli никаких дополнительных библиотек не требуется.
  • Как показано в примере выше, JewelCli использует аннотации на интерфейсах Java для этапа «определения». Любая попытка аннотировать методы «get» класса подобным образом приводит к появлению сообщения, такого как «IllegalArgumentException:… не является интерфейсом» во время выполнения.
  • JewelCli позволяет интерфейсам наследоваться от суперинтерфейсов, а @Option s, определенные в родительских интерфейсах, будут поддерживаться в наследующих интерфейсах.
  • Типы возвращаемых данных методов, аннотированных в интерфейсе, обеспечивают принудительное использование типов значений параметров командной строки. Перечисления могут даже использоваться в качестве возвращаемых типов данных, чтобы сузить возможные типы параметров командной строки до конечного набора возможностей.

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

Дополнительные ресурсы