首页 > 解决方案 > Picocli 解析搜索字符串

问题描述

我想为我的程序提供一个搜索字符串,例如:

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);
    }

}

}

标签: javapredicatepicocli

解决方案


我怀疑您可能希望使用库来解析最终用户指定为过滤器表达式(-n参数)的字符串。查看诸如Spring Expression LanguageOGNLJXPath之类的库可能是一个想法,可能还有其他库。或者,如果在GroovyBeanShell中编写这样的过滤器很容易,则可以从 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");

推荐阅读