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?
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() + " "))