Решение 1: Вариант карты
Самое простое решение - сделать -VAR
a Параметр карты . Это может выглядеть примерно так:
@Command(separator = " ")
class Simple implements Runnable {
enum MyOption {ARGUMENT1, OTHERARG, BOOLEANARG}
@Option(names = "-VAR",
description = "Variable options. Valid keys: ${COMPLETION-CANDIDATES}.")
Map<MyOption, String> options;
@Override
public void run() {
// business logic here
}
public static void main(String[] args) {
new CommandLine(new Simple()).execute(args);
}
}
Справка по использованию для этого примера будет выглядеть следующим образом:
Usage: <main class> [-VAR <MyOption=String>]...
-VAR <MyOption=String>
Variable options. Valid keys: ARGUMENT1, OTHERARG, BOOLEANARG.
Обратите внимание, что в этом решении все значения будут иметь одинаковый тип (String
в этом примере), и вам может потребоваться преобразовать в нужный тип (boolean
, int
, другие ...) в приложении.
Однако, это может быть неприемлемо, учитывая это предложение в вашем посте:
Мне также не разрешено сворачивать несколько аргументов в качестве параметров в один параметр -VAR.
Решение 2: Группы аргументов
Одной из идей альтернативы является использование групп аргументов : мы можем сделать ARGUMENT1
, OTHERARG
и BOOLEANARG
отдельными опциями и поместить их в группу так, чтобы они должны предшествует опция -VAR
.
Полученная справка по использованию выглядит примерно так:
Usage: group-demo [-VAR (ARGUMENT1=<arg1> | OTHERARG=<otherValue> |
BOOLEANARG=<bool>)]... [-hV]
-VAR Option prefix. Must be followed by one of
ARGUMENT1, OTHERARG or BOOLEANARG
ARGUMENT1=<arg1> An arg. Must be preceded by -VAR.
OTHERARG=<otherValue> Another arg. Must be preceded by -VAR.
BOOLEANARG=<bool> A boolean arg. Must be preceded by -VAR.
-h, --help Show this help message and exit.
-V, --version Print version information and exit.
И реализация может выглядеть примерно так:
@Command(name = "group-demo", mixinStandardHelpOptions = true,
sortOptions = false)
class UsingGroups implements Runnable {
static class MyGroup {
@Option(names = "-VAR", required = true,
description = "Option prefix. Must be followed by one of ARGUMENT1, OTHERARG or BOOLEANARG")
boolean ignored;
static class InnerGroup {
@Option(names = "ARGUMENT1", description = "An arg. Must be preceded by -VAR.")
String arg1;
@Option(names = "OTHERARG", description = "Another arg. Must be preceded by -VAR.")
String otherValue;
@Option(names = "BOOLEANARG", arity = "1",
description = "A boolean arg. Must be preceded by -VAR.")
Boolean bool;
}
// exclusive: only one of these options can follow a -VAR option
// multiplicity=1: InnerGroup must occur once
@ArgGroup(multiplicity = "1", exclusive = true)
InnerGroup inner;
}
// non-exclusive means co-occurring, so if -VAR is specified,
// then it must be followed by one of the InnerGroup options
@ArgGroup(multiplicity = "0..*", exclusive = false)
List<MyGroup> groupOccurrences;
@Override
public void run() {
// business logic here
System.out.printf("You specified %d -VAR options.%n", groupOccurrences.size());
for (MyGroup group : groupOccurrences) {
System.out.printf("ARGUMENT1=%s, ARGUMENT2=%s, BOOLEANARG=%s%n",
group.inner.arg1, group.inner.arg2, group.inner.arg3);
}
}
public static void main(String[] args) {
new CommandLine(new UsingGroups()).execute(args);
}
}
Затем вызов с помощью java UsingGroups -VAR ARGUMENT1=abc -VAR BOOLEANARG=true
дает:
You specified 2 -VAR options.
ARGUMENT1=abc, OTHERARG=null, BOOLEANARG=null
ARGUMENT1=null, OTHERARG=null, BOOLEANARG=true
С этим ок. О, вы получите объект MyGroup
каждый раз, когда конечный пользователь указывает -VAR
. Этот MyGroup
объект имеет InnerGroup
, который имеет много полей, всех, кроме одного из которых будет null
. Только поле, указанное пользователем, будет не null
. В этом недостаток этого подхода: в приложении вам нужно будет проверить все поля, чтобы найти не-1053 *, указанное пользователем. Преимущество заключается в том, что при выборе правильного типа для поля, помеченного @Option
, значения будут автоматически преобразованы в тип назначения.