Строка поиска Picocli Parse

Я хотел бы предоставить строку поиска для моей программы, например:

cmd.execute("getDevices", "-h 1.2.3.4", "-p myPSW", "-u myUser", "-n red|blue&black,-nonprod");

Я хочу создать предикаты для поиска имен хостов, которые содержат красный ИЛИ синий И черный, но НЕ непродуктовые. Мне непонятно, как анализировать логические операторы вместе со строками в Picocli для создания предиката. Есть ли простой и прямой способ разобрать строку на предикат?

Мой CLI настроен следующим образом:

@Command(name = "HostMagicCLI", mixinStandardHelpOptions = true,
        version = "1.0",
        description = "Do Stuff With Hosts"
        ,
        subcommands = {TufinDevices.class}
)

public class HostMagicCLI implements Runnable {

    public static void main(String[] args) {
        CommandLine cmd = new CommandLine(new InterfaceMagicCLI());
        cmd.setExecutionStrategy(new RunAll());
        cmd.getHelpSectionMap().put(SECTION_KEY_COMMAND_LIST, new MyCommandListRenderer());
        cmd.usage(System.out);
        cmd.execute("getDevices", "-h1.2.3.4", "-p myPSW", "-u myUser", "-n red|blue&black");

    }

    @Override
    public void run() {
        System.out.println("Running..");
    }
     }

@Command(name = "getDevices", aliases = {"l"}, description = "SpecifyTufin Credentials", subcommands = {InterfaceCommand.class})

class TufinDevices implements Runnable {
 .
 .//Options to collect user,psw, host etc.
 .
@CommandLine.Option(names = {"-n", "--n"}, split = ",", arity = "0..*", description = "Hostname Contains")
String[] hostNameContains;
private void filter(TufinDeviceCollection<TufinDevice> devices) {
    if (hostNameContains != null) {
        Predicate< ? super TufinDevice> deviceFilter = device -> Arrays.stream(hostNameContains)
                .allMatch(input -> device.getHostName().toLowerCase().contains(input.toLowerCase()));

        devices = devices.stream()
                .sequential()
                .filter(deviceFilter)
                .collect(Collectors.toCollection(TufinDeviceCollection<TufinDevice>::new));
    }
@Override
public void run() {
    try {
        TufinDeviceCollection<TufinDevice> FETCH_DEVICES = Tufin.FETCH_DEVICES(user.trim(), password.trim(), hostName.trim());
        this.filter(FETCH_DEVICES);
    } catch (IOException | NoSuchAlgorithmException | KeyManagementException | IPConverter.InvalidIPException ex) {
        Logger.getLogger(TufinDevices.class.getName()).log(Level.SEVERE, null, ex);
    }

}

}


person Jamie Snipes    schedule 31.07.2019    source источник


Ответы (1)


Я подозреваю, что вы можете использовать библиотеку для анализа строки, которую конечный пользователь указывает в качестве выражения фильтра (параметр -n). Возможно, стоит взглянуть на такие библиотеки, как язык выражений Spring., OGNL, JXPath, могут быть и другие. В качестве альтернативы, если такой фильтр легко написать в Groovy или BeanShell, эти языки можно вызывать из Java, поэтому вы можете вызвать этот фильтр из команды Java.


ВНИМАНИЕ: я заметил, что пример передает параметр синтаксическому анализатору picocli следующим образом:

cmd.execute("getDevices", "-h 1.2.3.4", "-p myPSW", "-u myUser", "-n red|blue&black,-nonprod");

Это, вероятно, приведет к ошибке, объясняющей, что «опция -p myPSW не определена».

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

cmd.execute("getDevices", "-h", "1.2.3.4", "-p", "myPSW", "-u", "myUser", "-n", "red|blue&black,-nonprod");
person Remko Popma    schedule 01.08.2019