Синтаксис аргументов Java CLI для инициализации объекта - PullRequest
1 голос
/ 08 февраля 2011

Я ищу инструмент, который позволил бы мне использовать строки в стиле командной строки (предпочтительно POSIX) для инициализации свойств и атрибутов объекта.

Например, вы бы предоставили ему вход String, отформатированный так:

String input = "--firstName=John --MiddleName=\"Louis Victor\" --lastName=Smith";

... и это будет setFirstName("John"), setMiddleName("Louis Victor") и setLastName("Smith") для данного объекта. (который может быть JavaBean)

Обратите внимание, что вводом является один String, а не массив String[], как в случае со многими популярными аргументами CLI "парсеры".

Это все похоже на args4j , но я не мог заставить это работать ... и я надеюсь избежать использования @annotations.

У кого-нибудь есть код / ​​библиотеки / инструменты, которые могут это сделать?

Ответы [ 3 ]

4 голосов
/ 08 февраля 2011

В вашем случае, забудьте про обычные парсеры CLI, вам нужно индивидуальное решение. Если у вас действительно такой простой синтаксис аргументов (параметры всегда начинаются с --, в значениях параметров нет вхождений --), вы можете использовать простое решение на основе Guava , например, этого класса:

Разбор строковых аргументов

public class ArgParser{

    // split on (optional whitespace) + "--"
    private final Splitter paramSplitter = Splitter.on(
        Pattern.compile("\\s*\\-{2}")).omitEmptyStrings();

    // find key=value (with optional double quotes around value)
    private final Pattern keyValuePattern = Pattern
        .compile("(.+?)=\"?(.*?)\"?$");

    public Map<String, String> getParamValues(final String posixString){
        final Map<String, String> paramValues = Maps.newLinkedHashMap();
        Matcher matcher;
        for(final String param : paramSplitter.split(posixString)){
            matcher = keyValuePattern.matcher(param);
            if(!matcher.find()){
                throw new IllegalArgumentException("Bad parameter: " + param);
            }
            paramValues.put(matcher.group(1), matcher.group(2));
        }
        return paramValues;
    }

}

Использование

final String input =
    "--firstName=John --middleName=\"Louis Victor\" --lastName=Smith";
System.out.println(new ArgParser().getParamValues(input));

выход

{firstName = Джон, middleName = Луи Виктор, lastName = Смит}

Теперь вы можете взять карту и использовать ее с библиотекой Bean, например commons-beanutils (я лично предпочитаю Spring BeanWrapper, но это имеет смысл, если вы все равно используете Spring)

Определить класс бобов

В любом случае, я буду использовать этот класс держателей значений:

public class Name{

    private String firstName;
    private String middleName;
    private String lastName;

    @Override
    public String toString(){
        return Objects
            .toStringHelper(this)
            .add("first name", firstName)
            .add("middle name", middleName)
            .add("last name", lastName)
            .toString();
    }

    // + getters & setters

}

Установка свойств бина

Теперь мы будем использовать BeanUtils.populate(Object, Map) для применения значений параметров, например:

final String input =
    "--firstName=John --middleName=\"Louis Victor\" --lastName=Smith";
final Map<String, String> paramValues =
    new ArgParser().getParamValues(input);
final Name name = new Name();
BeanUtils.populate(name, paramValues);
System.out.println(name);

Выход:

Имя {имя = Джон, отчество = Луи Виктор, фамилия = Смит}

Предостережение: поддерживаемые типы недвижимости

BeanUtils.populate() поддерживает установку следующих типов свойств:

... String, boolean, int, long, float и double. Кроме того, установщики массива для этих типы (или соответствующий примитив типы) также могут быть идентифицированы.

Источник: BeanUtilsBean.populate(Object, Map)

Если вам нужно преобразование параметров сверх этого, вам, вероятно, стоит подумать об использовании Spring BeanWrapper , в конце концов, он чрезвычайно мощный, имеет множество встроенных редакторов свойств , и вы можете добавить редакторы пользовательских свойств . Просто измените код следующим образом:

final Name name = new Name();
final BeanWrapper wrapper = new BeanWrapperImpl(name);
wrapper.setPropertyValues(paramValues);

Справка:

3 голосов
/ 08 февраля 2011

Если я правильно понимаю, вы ищете библиотеку Java для анализа параметров командной строки в стиле POSIX. Я использовал JSAP некоторое время назад, и это было действительно круто (тогда использовалась конфигурация XML).

0 голосов
/ 08 февраля 2011

Это

-firstName John -lastName Smith

это не POSIX, вы имеете в виду

--firstName John --lastName Smith

Это может быть причиной, почему вы не можете заставить ее работать.

Обновление:

Когда я смотрю на пример, не похоже, что это может быть причиной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...