select from a small amount of options in spring shell

后端 未结 3 943
感情败类
感情败类 2021-01-23 15:53

I am currently trying to make an cli app with Spring Shell.

I want the user to able to fast pick one of 2-3 options. My current code works fine in eclipse but when I sta

3条回答
  •  礼貌的吻别
    2021-01-23 16:15

    I use TextIO for this to do something similar. More specifically, I use the read method on [IntInputReader][2] which is handy as according to its docs:

    Reads a value of type T. It repeatedly prompts the users to enter the value, until they provide a valid input string.

    As I've needed this functionality many times in my Spring Shell application (for users to select from different types of objects), I wrote a generic method which

    Presents the user with a list of items of a given type {@code T} and prompts them to select one or more. Optionally, once selection is complete, the user is presented with a summary of their selection for their confirmation.

    Unfortunately StackOverflow is playing havoc with my Javadoc, so I've created a Gist with the full documented method.

      public  List cliObjectSelector(List items, boolean allowMultiple, 
      boolean requireConfirmation, @Nullable String customPromptMessage,
      Function f) throws OperationCancelledException {
    
    if(items == null || items.isEmpty()) {
      textIO.getTextTerminal().print("No items found.  Cannot continue");
      throw new OperationCancelledException("The provided list of items is empty");
    }
    
    String userPrompt = (customPromptMessage != null) ? customPromptMessage + ":\n" : 
      String.format("Please select one of the %d items from the list:\n", items.size());
    
    List optionsList = items.stream()
        .map(item -> {
          return String.format("[%d] - %s", items.indexOf(item), f.apply(item));
        }).collect(Collectors.toList());
    
    List selectedItems = new ArrayList<>();
    
    optionsList.add(0, userPrompt);
    
    while(true) {
      textIO.getTextTerminal().println(optionsList);
    
      T selected = items.get(
          textIO.newIntInputReader()
          .withMinVal(0)
          .withMaxVal(items.size() - 1)
          .read("Option number"));
    
      selectedItems.add(selected);
    
      if(allowMultiple == false) {
        break;
      }
    
      if( ! askYesNo("Select another item?")) {
        break;
      }
    }
    
    if(requireConfirmation == false) {
      return selectedItems;
    }
    
    if(confirmSelection(selectedItems.stream()
        .map(item -> f.apply(item))
        .collect(Collectors.toList()))) {
      return selectedItems;
    } else {
      throw new OperationCancelledException();
    }
    }
    

    Sample usage:

      @ShellMethod(
      key = "select-something",
      value = "Select something")
    public void select() {
        Instance selected = cliObjectSelector(instances, false, requireConfirmation,
            "Please select one of the " + instances.size() + " instances from the list",
            instance -> instance.getX().getName()).get(0);
      }
    

提交回复
热议问题