Only allow specified command name but still allow additional arguments

DonaldDuck :

I am currently using this code to find a command that the user types in:

final Command command = commands.stream()
        .filter(cmd -> input.startsWith(cmd.getName()))
        .findAny()
        .orElseThrow(() -> new InvalidInputException("unknown command"));

Every command class has its own getName() method. This is how the getName() method of ExitCommand() looks like:

@Override
public String getName() {
    return "exit";
}

Unfortunately, with the current stream, "exittttttt" is also accepted. I can't use .equals(cmd.getName()) though, because there are commands that have subsequent arguments after the command name.

For example:

@Override
public String getName() {
    return "delete track";
}

But the full command is delete track <id>.

Does anyone have an idea how to only allow the command name that is specified in each getName() method but also still allow further arguments?

EDIT:

Each command has its own getArguments() method. The method will return 0 for the exit command and 1 for the delete track command. Maybe this can be used to solve this problem?

ernest_k :

If the space is what always separates commands from arguments, then you can use

.filter(cmd -> (cmd.getArguments() == 0 && input.equals(cmd.getName()))
                 || input.startsWith(cmd.getName() + " "))

This checks that the input matches the command name exactly if the command supports no arguments, or the input has the command name followed by a space.

If commands supporting arguments may be called without arguments, then maybe this is the right predicate:

.filter(cmd -> (cmd.getArguments() == 0 && input.equals(cmd.getName()))
                 || input.equals(cmd.getName()) //no args passed
                 || input.startsWith(cmd.getName() + " "))

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=3711&siteId=1