Args4j – альтернатива Apache Commons CLI

Posted on: July 31st, 2011 by Spade No Comments »

Недавно мы писали о том, как apache commons cli может оказать нам неоценимую помощь в таком нудном use-case как разбор опций командной строки. Но отношение будет справедливым, только если мы опишем альтернативу: args4j. Этот нано микро-фреймворк делает тоже самое с помощью аннотаций. С этим механизмом мы задаем имя, описание и др. аттрибуты параметра командной строки прямо рядом с полем, куда будем сохранять значение. Реализована поддержка сложных типов(не только обычных строк): Boolean, File, URL… Хотя у меня лично булевский тип отказался работать как описано. В данном случае нам будет удобно создать класс опций и описать параметры внутри него как поля.

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
 
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
 
public class Settings implements Serializable {
 
    @Option(name = "--name", usage = "Set connection user name", required = true)
    private String name;
 
    @Option(name = "--password", usage = "Set connection user password", required = true)
    private String password;
 
    @Option(name = "--charset", usage = "Set connection charset")
    private String charset;
 
    @Option(name = "--url", usage = "Set connection url")
    private String url;
 
    @Option(name = "--config", usage = "Additional config options")
    private File config;
 
    @Argument
    private List extraArgs = new ArrayList();
 
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }
}

Два типа аннотации: @Option и @Argument полностью покроют ваши нужды (если вы не входите в те самые 7% «особенных»). Второй тип аннотации используется для «всех остальных опций» – то есть все что не описано будет туда сохранено. Если его не будет, то любая не описанная опция вызовет выброс исключения о том, что она не распознана. Пример класса, который разберет его видим ниже:

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
 
public class Main {
 
    public static void main(String[] args) throws Exception{
 
        Settings settings = new Settings();
        CmdLineParser parser = new CmdLineParser(settings);
 
        try {
            parser.parseArgument(args);
            System.out.println("settings = " + settings);
        } catch (CmdLineException e) {
            System.err.println("e = " + e.toString());
            parser.printUsage(System.out);
        }
    }
}

Класс CmdLineParser осуществляет сам процесс разбора. Свойства аннотации @Option:

  • String name() – имя параметра cli
  • String[] aliases() default {} – список псевдонимов параметра
  • String usage() default “” – описание параметра
  • String metaVar() default “” – имя в описании
  • boolean required() default false – является ли параметр обязательным
  • handler() default null – обработчик для сложных типов
  • multiValued() default false – может ли иметь более одного значения

Из объективных преимуществ перед Apache:

  • Нет зависимости от других библиотек. Apache Commons CLI – зависит от Apache Commons Lang
  • Добавление персональных типов
  • Сохранение всех аргументов, в том числе не распознанных
  • Многоязычность – поддерживается обеими решениями

Перейду на субъективщину – на мой взгляд этот подход намного более удобный чем, решение от apache. А там уж вам решать…

Leave a Reply