Lots of progress
This commit is contained in:
parent
a9b2524238
commit
d4143246b7
17 changed files with 606 additions and 84 deletions
1
commands-jline/README.md
Normal file
1
commands-jline/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Command implementation for [JLine](https://github.com/jline/jline3)
|
||||
24
commands-jline/pom.xml
Normal file
24
commands-jline/pom.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>Commands</artifactId>
|
||||
<groupId>com.intellectualsites</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>commands-jline</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jline</groupId>
|
||||
<artifactId>jline</artifactId>
|
||||
<version>3.16.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.intellectualsites</groupId>
|
||||
<artifactId>Commands</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands.jline;
|
||||
|
||||
import com.intellectualsites.commands.Command;
|
||||
import com.intellectualsites.commands.CommandManager;
|
||||
import com.intellectualsites.commands.CommandTree;
|
||||
import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
|
||||
import com.intellectualsites.commands.internal.CommandRegistrationHandler;
|
||||
import org.jline.reader.*;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Command manager for use with JLine
|
||||
*/
|
||||
public class JLineCommandManager extends CommandManager<JLineCommandSender> implements Completer {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// TODO: REMOVE THIS!!!!
|
||||
final JLineCommandManager jLineCommandManager = new JLineCommandManager(CommandExecutionCoordinator.simpleCoordinator());
|
||||
final Terminal terminal = TerminalBuilder.builder().dumb(true).build();
|
||||
LineReader lineReader = LineReaderBuilder.builder()
|
||||
.completer(jLineCommandManager).terminal(terminal).appName("Test").build();
|
||||
boolean[] shouldStop = new boolean[] { false };
|
||||
jLineCommandManager.registerCommand(Command.newBuilder("stop").withHandler(commandContext ->
|
||||
shouldStop[0] = true).build());
|
||||
while (!shouldStop[0]) {
|
||||
final String line = lineReader.readLine();
|
||||
if (line == null || line.isEmpty() || !line.startsWith("/")) {
|
||||
continue;
|
||||
}
|
||||
jLineCommandManager.executeCommand(new JLineCommandSender(), line.substring(1)).join();
|
||||
if (shouldStop[0]) {
|
||||
System.out.println("Stopping.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JLineCommandManager(@Nonnull final Function<CommandTree<JLineCommandSender>, CommandExecutionCoordinator<JLineCommandSender>> executionCoordinatorFunction) {
|
||||
super(executionCoordinatorFunction, CommandRegistrationHandler.NULL_COMMAND_REGISTRATION_HANDLER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(@Nonnull final LineReader lineReader, @Nonnull final ParsedLine parsedLine, @Nonnull final List<Candidate> list) {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands.jline;
|
||||
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
public class JLineCommandSender implements CommandSender {
|
||||
}
|
||||
5
pom.xml
5
pom.xml
|
|
@ -7,7 +7,10 @@
|
|||
<groupId>com.intellectualsites</groupId>
|
||||
<artifactId>Commands</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<modules>
|
||||
<module>commands-jline</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
<inceptionYear>2020</inceptionYear>
|
||||
<licenses>
|
||||
<license>
|
||||
|
|
|
|||
|
|
@ -24,33 +24,50 @@
|
|||
package com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualsites.commands.components.CommandComponent;
|
||||
import com.intellectualsites.commands.components.StaticComponent;
|
||||
import com.intellectualsites.commands.execution.CommandExecutionHandler;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A command consists out of a chain of {@link com.intellectualsites.commands.components.CommandComponent command components}.
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
public class Command {
|
||||
public class Command<C extends CommandSender> {
|
||||
|
||||
private final CommandComponent<?>[] components;
|
||||
private final CommandComponent<C, ?>[] components;
|
||||
private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
|
||||
private Command(@Nonnull final CommandComponent<?>[] commandComponents) {
|
||||
protected Command(@Nonnull final CommandComponent<C, ?>[] commandComponents, @Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
this.components = Objects.requireNonNull(commandComponents, "Command components may not be null");
|
||||
if (this.components.length == 0){
|
||||
if (this.components.length == 0) {
|
||||
throw new IllegalArgumentException("At least one command component is required");
|
||||
}
|
||||
// Enforce ordering of command components
|
||||
boolean foundOptional = false;
|
||||
for (final CommandComponent<?> component : this.components) {
|
||||
for (final CommandComponent<C, ?> component : this.components) {
|
||||
if (foundOptional && component.isRequired()) {
|
||||
throw new IllegalArgumentException(String.format("Command component '%s' cannot be placed after an optional component", component.getName()));
|
||||
} else if (!component.isRequired()) {
|
||||
foundOptional = true;
|
||||
}
|
||||
}
|
||||
this.commandExecutionHandler = commandExecutionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new command builder
|
||||
*
|
||||
* @param commandName Base command component
|
||||
* @return Command builder
|
||||
*/
|
||||
@Nonnull
|
||||
public static <C extends CommandSender> Builder<C> newBuilder(@Nonnull final String commandName) {
|
||||
return new Builder<>(Collections.singletonList(StaticComponent.required(commandName)),
|
||||
new CommandExecutionHandler.NullCommandExecutionHandler<>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -58,10 +75,18 @@ public class Command {
|
|||
*
|
||||
* @return Copy of the command component array
|
||||
*/
|
||||
@Nonnull public CommandComponent<?>[] getComponents() {
|
||||
final CommandComponent<?>[] commandComponents = new CommandComponent<?>[this.components.length];
|
||||
System.arraycopy(this.components, 0, commandComponents, 0, this.components.length);
|
||||
return commandComponents;
|
||||
@Nonnull @SuppressWarnings("ALL")
|
||||
public CommandComponent<C, ?>[] getComponents() {
|
||||
return (CommandComponent<C, ?>[]) Arrays.asList(this.components).toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command execution handler
|
||||
*
|
||||
* @return Command execution handler
|
||||
*/
|
||||
@Nonnull public CommandExecutionHandler<C> getCommandExecutionHandler() {
|
||||
return this.commandExecutionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,8 +95,8 @@ public class Command {
|
|||
*
|
||||
* @return List containing the longest shared component chain
|
||||
*/
|
||||
public List<CommandComponent<?>> getSharedComponentChain(@Nonnull final Command other) {
|
||||
final List<CommandComponent<?>> commandComponents = new LinkedList<>();
|
||||
public List<CommandComponent<C, ?>> getSharedComponentChain(@Nonnull final Command<C> other) {
|
||||
final List<CommandComponent<C, ?>> commandComponents = new LinkedList<>();
|
||||
for (int i = 0; i < this.components.length && i < other.components.length; i++) {
|
||||
if (this.components[i].equals(other.components[i])) {
|
||||
commandComponents.add(this.components[i]);
|
||||
|
|
@ -82,4 +107,52 @@ public class Command {
|
|||
return commandComponents;
|
||||
}
|
||||
|
||||
|
||||
public static class Builder<C extends CommandSender> {
|
||||
|
||||
private final List<CommandComponent<C, ?>> commandComponents;
|
||||
private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
|
||||
private Builder(@Nonnull final List<CommandComponent<C, ?>> commandComponents, @Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
this.commandComponents = commandComponents;
|
||||
this.commandExecutionHandler = commandExecutionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new command component to the command
|
||||
*
|
||||
* @param component Component to add
|
||||
* @param <T> Component type
|
||||
* @return New builder instance with the command component inserted into the component list
|
||||
*/
|
||||
@Nonnull
|
||||
public <T> Builder<C> withComponent(@Nonnull final CommandComponent<C, T> component) {
|
||||
final List<CommandComponent<C, ?>> commandComponents = new LinkedList<>(this.commandComponents);
|
||||
commandComponents.add(component);
|
||||
return new Builder<>(commandComponents, this.commandExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the command execution handler
|
||||
*
|
||||
* @param commandExecutionHandler New execution handler
|
||||
* @return New builder instance using the command execution handler
|
||||
*/
|
||||
@Nonnull
|
||||
public Builder<C> withHandler(@Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
return new Builder<>(this.commandComponents, commandExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a command using the builder instance
|
||||
*
|
||||
* @return Built command
|
||||
*/
|
||||
@Nonnull
|
||||
public Command<C> build() {
|
||||
return new Command<>(this.commandComponents.toArray(new CommandComponent[0]), this.commandExecutionHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands;
|
||||
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
|
||||
import com.intellectualsites.commands.execution.CommandResult;
|
||||
import com.intellectualsites.commands.internal.CommandRegistrationHandler;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* The manager is responsible for command registration, parsing delegation, etc.
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
public abstract class CommandManager<C extends CommandSender> {
|
||||
|
||||
private final CommandExecutionCoordinator<C> commandExecutionCoordinator;
|
||||
private final CommandTree<C> commandTree;
|
||||
|
||||
protected CommandManager(@Nonnull final Function<CommandTree<C>, CommandExecutionCoordinator<C>> commandExecutionCoordinator,
|
||||
@Nonnull final CommandRegistrationHandler commandRegistrationHandler) {
|
||||
this.commandTree = CommandTree.newTree(commandRegistrationHandler);
|
||||
this.commandExecutionCoordinator = commandExecutionCoordinator.apply(commandTree);
|
||||
}
|
||||
|
||||
public CompletableFuture<CommandResult> executeCommand(@Nonnull final C commandSender, @Nonnull final String input) {
|
||||
final StringTokenizer stringTokenizer = new StringTokenizer(input, " ");
|
||||
final Queue<String> tokens = new LinkedList<>();
|
||||
while (stringTokenizer.hasMoreElements()) {
|
||||
tokens.add(stringTokenizer.nextToken());
|
||||
}
|
||||
final CommandContext<C> context = new CommandContext<>(commandSender);
|
||||
return this.commandExecutionCoordinator.coordinateExecution(context, tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new command
|
||||
*
|
||||
* @param command Command to register
|
||||
*/
|
||||
public void registerCommand(@Nonnull final Command command) {
|
||||
this.commandTree.insertCommand(command);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import com.google.common.base.Objects;
|
|||
import com.google.common.collect.Lists;
|
||||
import com.intellectualsites.commands.components.CommandComponent;
|
||||
import com.intellectualsites.commands.components.StaticComponent;
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.exceptions.NoSuchCommandException;
|
||||
import com.intellectualsites.commands.internal.CommandRegistrationHandler;
|
||||
import com.intellectualsites.commands.parser.ComponentParseResult;
|
||||
|
|
@ -44,7 +45,7 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
public class CommandTree<C extends CommandSender> {
|
||||
|
||||
private final Node<CommandComponent<?>> internalTree = new Node<>(null);
|
||||
private final Node<CommandComponent<C, ?>> internalTree = new Node<>(null);
|
||||
private final CommandRegistrationHandler commandRegistrationHandler;
|
||||
|
||||
private CommandTree(@Nonnull final CommandRegistrationHandler commandRegistrationHandler) {
|
||||
|
|
@ -63,26 +64,25 @@ public class CommandTree<C extends CommandSender> {
|
|||
return new CommandTree<>(commandRegistrationHandler);
|
||||
}
|
||||
|
||||
public Optional<Command> parse(@Nonnull final C commandSender, @Nonnull final String[] args) throws NoSuchCommandException {
|
||||
final Queue<String> commandQueue = new LinkedList<>(Arrays.asList(args));
|
||||
return parseCommand(commandSender, commandQueue, this.internalTree);
|
||||
public Optional<Command<C>> parse(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> args) throws NoSuchCommandException {
|
||||
return parseCommand(commandContext, args, this.internalTree);
|
||||
}
|
||||
|
||||
private Optional<Command> parseCommand(@Nonnull final C commandSender, @Nonnull final Queue<String> commandQueue,
|
||||
@Nonnull final Node<CommandComponent<?>> root) throws NoSuchCommandException {
|
||||
private Optional<Command<C>> parseCommand(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> commandQueue,
|
||||
@Nonnull final Node<CommandComponent<C, ?>> root) throws NoSuchCommandException {
|
||||
|
||||
final List<Node<CommandComponent<?>>> children = root.getChildren();
|
||||
final List<Node<CommandComponent<C, ?>>> children = root.getChildren();
|
||||
if (children.size() == 1 && !(children.get(0).getValue() instanceof StaticComponent)) {
|
||||
// The value has to be a variable
|
||||
final Node<CommandComponent<?>> child = children.get(0);
|
||||
final Node<CommandComponent<C, ?>> child = children.get(0);
|
||||
if (child.getValue() != null) {
|
||||
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandSender, commandQueue);
|
||||
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandContext, commandQueue);
|
||||
if (result.getParsedValue().isPresent()) {
|
||||
/* TODO: Add context */
|
||||
if (child.isLeaf()) {
|
||||
return Optional.ofNullable(child.getValue().getOwningCommand());
|
||||
} else {
|
||||
return this.parseCommand(commandSender, commandQueue, child);
|
||||
return this.parseCommand(commandContext, commandQueue, child);
|
||||
}
|
||||
} else if (result.getFailure().isPresent()) {
|
||||
/* TODO: Return error */
|
||||
|
|
@ -97,13 +97,12 @@ public class CommandTree<C extends CommandSender> {
|
|||
return Optional.of(root.getValue().getOwningCommand());
|
||||
} else {
|
||||
/* TODO: Indicate that we could not resolve the command here */
|
||||
final List<CommandComponent<?>> components = this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList());
|
||||
final List<CommandComponent<C, ?>> components = this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList());
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
final String popped = commandQueue.poll();
|
||||
if (popped == null) {
|
||||
/* Not enough arguments */
|
||||
/* TODO: Send correct usage */
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +121,6 @@ public class CommandTree<C extends CommandSender> {
|
|||
} else if (comparison > 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
/* We found a match */
|
||||
if (node.isLeaf()) {
|
||||
return Optional.ofNullable(node.getValue().getOwningCommand());
|
||||
} else {
|
||||
|
|
@ -130,26 +128,27 @@ public class CommandTree<C extends CommandSender> {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* We could not find a match */
|
||||
throw new NoSuchCommandException(commandSender, getChain(root).stream().map(Node::getValue).collect(Collectors.toList()), popped);
|
||||
}
|
||||
|
||||
/*
|
||||
final Iterator<Node<CommandComponent<?>>> childIterator = root.getChildren().iterator();
|
||||
final Iterator<Node<CommandComponent<C, ?>>> childIterator = root.getChildren().iterator();
|
||||
if (childIterator.hasNext()) {
|
||||
while (childIterator.hasNext()) {
|
||||
final Node<CommandComponent<?>> child = childIterator.next();
|
||||
final Node<CommandComponent<C, ?>> child = childIterator.next();
|
||||
if (child.getValue() != null) {
|
||||
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandSender, commandQueue);
|
||||
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandContext, commandQueue);
|
||||
if (result.getParsedValue().isPresent()) {
|
||||
return this.parseCommand(commandSender, commandQueue, child);
|
||||
return this.parseCommand(commandContext, commandQueue, child);
|
||||
} else if (result.getFailure().isPresent() && root.children.size() == 1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* We could not find a match */
|
||||
throw new NoSuchCommandException(commandContext.getCommandSender(),
|
||||
getChain(root).stream().map(Node::getValue).collect(Collectors.toList()),
|
||||
java.util.Objects.requireNonNull(commandQueue.peek()));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
|
@ -159,10 +158,10 @@ public class CommandTree<C extends CommandSender> {
|
|||
*
|
||||
* @param command Command to insert
|
||||
*/
|
||||
public void insertCommand(@Nonnull final Command command) {
|
||||
Node<CommandComponent<?>> node = this.internalTree;
|
||||
for (final CommandComponent<?> component : command.getComponents()) {
|
||||
Node<CommandComponent<?>> tempNode = node.getChild(component);
|
||||
public void insertCommand(@Nonnull final Command<C> command) {
|
||||
Node<CommandComponent<C, ?>> node = this.internalTree;
|
||||
for (final CommandComponent<C, ?> component : command.getComponents()) {
|
||||
Node<CommandComponent<C, ?>> tempNode = node.getChild(component);
|
||||
if (tempNode == null) {
|
||||
tempNode = node.addChild(component);
|
||||
}
|
||||
|
|
@ -202,12 +201,12 @@ public class CommandTree<C extends CommandSender> {
|
|||
/* TODO: Figure out a way to register all combinations along a command component path */
|
||||
}
|
||||
|
||||
private void checkAmbiguity(@Nonnull final Node<CommandComponent<?>> node) {
|
||||
private void checkAmbiguity(@Nonnull final Node<CommandComponent<C, ?>> node) {
|
||||
if (node.isLeaf()) {
|
||||
return;
|
||||
}
|
||||
final int size = node.children.size();
|
||||
for (final Node<CommandComponent<?>> child : node.children) {
|
||||
for (final Node<CommandComponent<C, ?>> child : node.children) {
|
||||
if (child.getValue() != null && !child.getValue().isRequired() && size > 1) {
|
||||
// TODO: Use a custom exception type here
|
||||
throw new IllegalStateException("Ambiguous command node found: " + node.getValue());
|
||||
|
|
@ -216,8 +215,8 @@ public class CommandTree<C extends CommandSender> {
|
|||
node.children.forEach(this::checkAmbiguity);
|
||||
}
|
||||
|
||||
private List<CommandComponent<?>> getLeaves(@Nonnull final Node<CommandComponent<?>> node) {
|
||||
final List<CommandComponent<?>> leaves = new LinkedList<>();
|
||||
private List<CommandComponent<C, ?>> getLeaves(@Nonnull final Node<CommandComponent<C, ?>> node) {
|
||||
final List<CommandComponent<C, ?>> leaves = new LinkedList<>();
|
||||
if (node.isLeaf()) {
|
||||
if (node.getValue() != null) {
|
||||
leaves.add(node.getValue());
|
||||
|
|
@ -228,9 +227,9 @@ public class CommandTree<C extends CommandSender> {
|
|||
return leaves;
|
||||
}
|
||||
|
||||
private List<Node<CommandComponent<?>>> getChain(@Nullable final Node<CommandComponent<?>> end) {
|
||||
final List<Node<CommandComponent<?>>> chain = new LinkedList<>();
|
||||
Node<CommandComponent<?>> tail = end;
|
||||
private List<Node<CommandComponent<C, ?>>> getChain(@Nullable final Node<CommandComponent<C, ?>> end) {
|
||||
final List<Node<CommandComponent<C, ?>>> chain = new LinkedList<>();
|
||||
Node<CommandComponent<C, ?>> tail = end;
|
||||
while (tail != null) {
|
||||
chain.add(tail);
|
||||
tail = end.getParent();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ package com.intellectualsites.commands.components;
|
|||
|
||||
import com.intellectualsites.commands.Command;
|
||||
import com.intellectualsites.commands.parser.ComponentParser;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -34,9 +35,10 @@ import java.util.regex.Pattern;
|
|||
/**
|
||||
* A component that belongs to a command
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
* @param <T> The type that the component parses into
|
||||
*/
|
||||
public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
||||
public class CommandComponent<C extends CommandSender, T> implements Comparable<CommandComponent<?, ?>> {
|
||||
|
||||
private static final Pattern NAME_PATTERN = Pattern.compile("[A-Za-z0-9]+");
|
||||
|
||||
|
|
@ -57,12 +59,12 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
* The parser that is used to parse the command input
|
||||
* into the corresponding command type
|
||||
*/
|
||||
private final ComponentParser<T> parser;
|
||||
private final ComponentParser<C, T> parser;
|
||||
|
||||
private Command owningCommand;
|
||||
private Command<C> owningCommand;
|
||||
|
||||
CommandComponent(final boolean required, @Nonnull final String name,
|
||||
@Nonnull final ComponentParser<T> parser) {
|
||||
@Nonnull final ComponentParser<C, T> parser) {
|
||||
this.required = required;
|
||||
this.name = Objects.requireNonNull(name, "Name may not be null");
|
||||
if (!NAME_PATTERN.asPredicate().test(name)) {
|
||||
|
|
@ -75,10 +77,11 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
* Create a new command component
|
||||
*
|
||||
* @param clazz Argument class
|
||||
* @param <C> Command sender type
|
||||
* @param <T> Argument Type
|
||||
* @return Component builder
|
||||
*/
|
||||
@Nonnull public static <T> CommandComponent.Builder<T> ofType(@Nonnull final Class<T> clazz) {
|
||||
@Nonnull public static <C extends CommandSender, T> CommandComponent.Builder<C, T> ofType(@Nonnull final Class<T> clazz) {
|
||||
return new Builder<>();
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +109,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
*
|
||||
* @return Command parser
|
||||
*/
|
||||
@Nonnull public ComponentParser<T> getParser() {
|
||||
@Nonnull public ComponentParser<C, T> getParser() {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +122,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
*
|
||||
* @return Owning command
|
||||
*/
|
||||
@Nullable public Command getOwningCommand() {
|
||||
@Nullable public Command<C> getOwningCommand() {
|
||||
return this.owningCommand;
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +131,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
*
|
||||
* @param owningCommand Owning command
|
||||
*/
|
||||
public void setOwningCommand(@Nonnull final Command owningCommand) {
|
||||
public void setOwningCommand(@Nonnull final Command<C> owningCommand) {
|
||||
if (this.owningCommand != null) {
|
||||
throw new IllegalStateException("Cannot replace owning command");
|
||||
}
|
||||
|
|
@ -143,7 +146,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final CommandComponent<?> that = (CommandComponent<?>) o;
|
||||
final CommandComponent<?, ?> that = (CommandComponent<?, ?>) o;
|
||||
return isRequired() == that.isRequired() && com.google.common.base.Objects.equal(getName(), that.getName());
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +156,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull final CommandComponent<?> o) {
|
||||
public int compareTo(@Nonnull final CommandComponent<?, ?> o) {
|
||||
if (this instanceof StaticComponent) {
|
||||
if (o instanceof StaticComponent) {
|
||||
return (this.getName().compareTo(o.getName()));
|
||||
|
|
@ -170,11 +173,11 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
}
|
||||
|
||||
|
||||
public static class Builder<T> {
|
||||
public static class Builder<C extends CommandSender, T> {
|
||||
|
||||
private String name;
|
||||
private boolean required = true;
|
||||
private ComponentParser<T> parser;
|
||||
private ComponentParser<C, T> parser;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
|
@ -185,7 +188,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
* @param name Alphanumeric component name
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<T> named(@Nonnull final String name) {
|
||||
@Nonnull public Builder<C, T> named(@Nonnull final String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -199,7 +202,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
*
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<T> asRequired() {
|
||||
@Nonnull public Builder<C, T> asRequired() {
|
||||
this.required = true;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -213,7 +216,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
*
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<T> asOptional() {
|
||||
@Nonnull public Builder<C, T> asOptional() {
|
||||
this.required = false;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -224,7 +227,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
* @param parser Component parser
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<T> withParser(@Nonnull final ComponentParser<T> parser) {
|
||||
@Nonnull public Builder<C, T> withParser(@Nonnull final ComponentParser<C, T> parser) {
|
||||
this.parser = Objects.requireNonNull(parser, "Parser may not be null");
|
||||
return this;
|
||||
}
|
||||
|
|
@ -234,7 +237,7 @@ public class CommandComponent<T> implements Comparable<CommandComponent<?>> {
|
|||
*
|
||||
* @return Constructed component
|
||||
*/
|
||||
@Nonnull public CommandComponent<T> build() {
|
||||
@Nonnull public CommandComponent<C, T> build() {
|
||||
return new CommandComponent<>(this.required, this.name, this.parser);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
//
|
||||
package com.intellectualsites.commands.components;
|
||||
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.parser.ComponentParseResult;
|
||||
import com.intellectualsites.commands.parser.ComponentParser;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
|
@ -33,14 +34,22 @@ import java.util.HashSet;
|
|||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
public final class StaticComponent extends CommandComponent<String> {
|
||||
public final class StaticComponent<C extends CommandSender> extends CommandComponent<C, String> {
|
||||
|
||||
private StaticComponent(final boolean required, @Nonnull final String name, @Nonnull final String ... aliases) {
|
||||
super(required, name, new StaticComponentParser(name, aliases));
|
||||
super(required, name, new StaticComponentParser<>(name, aliases));
|
||||
}
|
||||
|
||||
@Nonnull public static <C extends CommandSender> StaticComponent<C> required(@Nonnull final String name, @Nonnull final String ... aliases) {
|
||||
return new StaticComponent<>(true, name, aliases);
|
||||
}
|
||||
|
||||
@Nonnull public static <C extends CommandSender> StaticComponent<C> optional(@Nonnull final String name, @Nonnull final String ... aliases) {
|
||||
return new StaticComponent<>(false, name, aliases);
|
||||
}
|
||||
|
||||
|
||||
private static final class StaticComponentParser implements ComponentParser<String> {
|
||||
private static final class StaticComponentParser<C extends CommandSender> implements ComponentParser<C, String> {
|
||||
|
||||
private final String name;
|
||||
private final Set<String> acceptedStrings = new HashSet<>();
|
||||
|
|
@ -50,7 +59,7 @@ public final class StaticComponent extends CommandComponent<String> {
|
|||
this.acceptedStrings.addAll(Arrays.asList(aliases));
|
||||
}
|
||||
|
||||
@Nonnull @Override public ComponentParseResult<String> parse(@Nonnull final CommandSender sender, @Nonnull final Queue<String> inputQueue) {
|
||||
@Nonnull @Override public ComponentParseResult<String> parse(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> inputQueue) {
|
||||
final String string = inputQueue.peek();
|
||||
if (string == null) {
|
||||
return ComponentParseResult.failure(this.name);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands.context;
|
||||
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class CommandContext<C extends CommandSender> {
|
||||
|
||||
private final C commandSender;
|
||||
|
||||
public CommandContext(@Nonnull final C commandSender) {
|
||||
this.commandSender = commandSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sender that executed the command
|
||||
*
|
||||
* @return Command sender
|
||||
*/
|
||||
@Nonnull public C getCommandSender() {
|
||||
return this.commandSender;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ import java.util.List;
|
|||
public class CommandParseException extends IllegalArgumentException {
|
||||
|
||||
private final CommandSender commandSender;
|
||||
private final List<CommandComponent<?>> currentChain;
|
||||
private final List<CommandComponent<?, ?>> currentChain;
|
||||
|
||||
/**
|
||||
* Construct a new command parse exception
|
||||
|
|
@ -44,7 +44,7 @@ public class CommandParseException extends IllegalArgumentException {
|
|||
* @param commandSender Sender who executed the command
|
||||
* @param currentChain Chain leading up to the exception
|
||||
*/
|
||||
protected CommandParseException(@Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?>> currentChain) {
|
||||
protected CommandParseException(@Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?, ?>> currentChain) {
|
||||
this.commandSender = commandSender;
|
||||
this.currentChain = currentChain;
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ public class CommandParseException extends IllegalArgumentException {
|
|||
* @return Unmodifiable list of command components
|
||||
*/
|
||||
@Nonnull
|
||||
public List<CommandComponent<?>> getCurrentChain() {
|
||||
public List<CommandComponent<?, ?>> getCurrentChain() {
|
||||
return Collections.unmodifiableList(this.currentChain);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class NoSuchCommandException extends CommandParseException {
|
|||
* @param currentChain Chain leading up to the exception
|
||||
* @param command Entered command (following the command chain)
|
||||
*/
|
||||
public NoSuchCommandException(@Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?>> currentChain,
|
||||
public NoSuchCommandException(@Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?, ?>> currentChain,
|
||||
@Nonnull final String command) {
|
||||
super(commandSender, currentChain);
|
||||
this.suppliedCommand = command;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands.execution;
|
||||
|
||||
import com.intellectualsites.commands.CommandTree;
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* The command execution coordinator is responsible for
|
||||
* coordinating command execution. This includes determining
|
||||
* what thread the command should be executed on, whether or
|
||||
* not command may be executed in parallel, etc.
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
public abstract class CommandExecutionCoordinator<C extends CommandSender> {
|
||||
|
||||
private final CommandTree<C> commandTree;
|
||||
|
||||
/**
|
||||
* Construct a new command execution coordinator
|
||||
*
|
||||
* @param commandTree Command tree
|
||||
*/
|
||||
public CommandExecutionCoordinator(@Nonnull final CommandTree<C> commandTree) {
|
||||
this.commandTree = commandTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple command execution coordinator that executes all commands immediately, on the calling thread
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
* @return New coordinator instance
|
||||
*/
|
||||
public static <C extends CommandSender> Function<CommandTree<C>, CommandExecutionCoordinator<C>> simpleCoordinator() {
|
||||
return SimpleCoordinator::new;
|
||||
}
|
||||
|
||||
public abstract CompletableFuture<CommandResult> coordinateExecution(@Nonnull final CommandContext<C> commandContext,
|
||||
@Nonnull final Queue<String> input);
|
||||
|
||||
/**
|
||||
* Get the command tree
|
||||
*
|
||||
* @return Command tree
|
||||
*/
|
||||
@Nonnull protected CommandTree<C> getCommandTree() {
|
||||
return this.commandTree;
|
||||
}
|
||||
|
||||
|
||||
public static class SimpleCoordinator<C extends CommandSender> extends CommandExecutionCoordinator<C> {
|
||||
|
||||
private SimpleCoordinator(@Nonnull final CommandTree<C> commandTree) {
|
||||
super(commandTree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> coordinateExecution(@Nonnull CommandContext<C> commandContext, @Nonnull Queue<String> input) {
|
||||
final CompletableFuture<CommandResult> completableFuture = new CompletableFuture<>();
|
||||
try {
|
||||
this.getCommandTree().parse(commandContext, input).ifPresent(
|
||||
command -> command.getCommandExecutionHandler().execute(commandContext));
|
||||
completableFuture.complete(new CommandResult());
|
||||
} catch (final Exception e) {
|
||||
completableFuture.completeExceptionally(e);
|
||||
}
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands.execution;
|
||||
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Handler that is invoked whenever a {@link com.intellectualsites.commands.Command} is executed
|
||||
* by a {@link com.intellectualsites.commands.sender.CommandSender}
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
@FunctionalInterface public interface CommandExecutionHandler<C extends CommandSender> {
|
||||
|
||||
/**
|
||||
* Handle command execution
|
||||
*
|
||||
* @param commandContext Command context
|
||||
*/
|
||||
void execute(@Nonnull final CommandContext<C> commandContext);
|
||||
|
||||
|
||||
class NullCommandExecutionHandler<C extends CommandSender> implements CommandExecutionHandler<C> {
|
||||
|
||||
@Override
|
||||
public void execute(@Nonnull final CommandContext<C> commandContext) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020 IntellectualSites
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
package com.intellectualsites.commands.execution;
|
||||
|
||||
public class CommandResult {
|
||||
}
|
||||
|
|
@ -23,20 +23,23 @@
|
|||
//
|
||||
package com.intellectualsites.commands.parser;
|
||||
|
||||
import com.intellectualsites.commands.context.CommandContext;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Queue;
|
||||
|
||||
@FunctionalInterface public interface ComponentParser<T> {
|
||||
@FunctionalInterface
|
||||
public interface ComponentParser<C extends CommandSender, T> {
|
||||
|
||||
/**
|
||||
* Parse command input into a command result
|
||||
*
|
||||
* @param sender Sender who sent the command
|
||||
* @param commandContext Command context
|
||||
* @param inputQueue The queue of arguments
|
||||
* @return Parsed command result
|
||||
*/
|
||||
@Nonnull ComponentParseResult<T> parse(@Nonnull CommandSender sender, @Nonnull Queue<String> inputQueue);
|
||||
@Nonnull
|
||||
ComponentParseResult<T> parse(@Nonnull CommandContext<C> commandContext, @Nonnull Queue<String> inputQueue);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue