4

我目前正在尝试改进 Spring Shell 应用程序,如果它支持值和选项的制表符补全,那么它会变得更好。

例如,如果我的 CLI 有一个 command getInfo --name <name>,其中<name>是 DB 中一组有限名称中的一个名称,那么能够做到这一点会很方便

> getInfo --name Lu<tab>
  Lucy Luke Lulu
> getInfo --name Luk<tab>
> getInfo --name Luke

有没有办法使用现有的 Spring Shell 工具来做到这一点?我在文档中四处寻找,找不到任何关于自动完成值的信息..

干杯!

4

2 回答 2

4

对于 Spring Shell 2,您需要实现ValueProvider接口。

import org.springframework.shell.standard.ValueProvider;

@Component
public class MyValueProvider implements ValueProvider {

    @Override
    public boolean supports(MethodParameter methodParameter, CompletionContext completionContext) {
        return true;
    }

    @Override
    public List<CompletionProposal> complete(MethodParameter methodParameter, CompletionContext completionContext, String[] strings) {

        List<CompletionProposal> result = new ArrayList();
        List<String> knownThings = new ArrayList<>();
        knownPaths.add("something");

        String userInput = completionContext.currentWordUpToCursor();
        knownThings.stream()
                .filter(t -> t.startsWith(userInput))
                .forEach(t -> result.add(new CompletionProposal(t)));

        return result;
    }
}
于 2018-10-08T08:09:01.450 回答
1

您可以注册一个 Converter 来将此功能转换为 String 类型。已经有一些已经创建的转换器,并且org.springframework.shell.converters.EnumConverter具有您正在寻找的功能。

要注册一个转换器,您需要实现org.springframework.shell.core.Converter 接口:

@Component
public class PropertyConverter implements Converter<String> {

    public boolean supports(Class<?> type, String optionContext) {
        return String.class.isAssignableFrom(type)
                && optionContext != null && optionContext.contains("enable-prop-converter");
    }

    public String convertFromText(String value, Class<?> targetType, String optionContext) {
        return value;
    }

    public boolean getAllPossibleValues(List<Completion> completions, Class<?> targetType, String existingData,
            String optionContext, MethodTarget target) {
        boolean result = false;

        if (String.class.isAssignableFrom(targetType)) {
            String [] values = {"ONE", "BOOKING", "BOOK"};

            for (String candidate : values) {
                if ("".equals(existingData) || candidate.startsWith(existingData) || existingData.startsWith(candidate)
                        || candidate.toUpperCase().startsWith(existingData.toUpperCase())
                        || existingData.toUpperCase().startsWith(candidate.toUpperCase())) {
                    completions.add(new Completion(candidate));
                }
            }

            result = true;
        }
        return result;
    }

}

在前面的示例中,我为 String 对象注册了一个转换器,当 @CliOption 注解的 optionContext 具有enable-prop-converter.

您还必须禁用默认的 StringConverter。在下一行中,我禁用了 @CliOption 注解中的默认字符串转换器,disable-string-converter并启用了新的 PropertyConverter enable-prop-converter

@CliOption(key = { "idProp" }, mandatory = true, help = "The the id of the property", optionContext="disable-string-converter,enable-prop-converter") final String idProp
于 2017-08-08T07:52:04.853 回答