Add missing documentation

This commit is contained in:
Alexander Söderberg 2020-09-07 11:07:04 +02:00
parent 6c813a209b
commit 667e7cc49d
No known key found for this signature in database
GPG key ID: C0207FF7EA146678
16 changed files with 179 additions and 25 deletions

View file

@ -82,4 +82,8 @@ public abstract class BukkitCommandSender implements CommandSender {
@Nonnull
public abstract Player asPlayer();
@Override
public boolean hasPermission(@Nonnull final String permission) {
return this.internalSender.hasPermission(permission);
}
}

View file

@ -144,7 +144,13 @@ public class Command<C extends CommandSender> {
}
public static class Builder<C extends CommandSender> {
/**
* Builder for {@link Command} instances. The builder is immutable, and each
* setter method will return a new builder instance.
*
* @param <C> Command sender type
*/
public static final class Builder<C extends CommandSender> {
@Nonnull private final List<CommandComponent<C, ?>> commandComponents;
@Nonnull private final CommandExecutionHandler<C> commandExecutionHandler;
@ -155,10 +161,10 @@ public class Command<C extends CommandSender> {
@Nonnull final List<CommandComponent<C, ?>> commandComponents,
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
@Nonnull final String commandPermission) {
this.commandComponents = commandComponents;
this.commandExecutionHandler = commandExecutionHandler;
this.senderType = senderType;
this.commandPermission = commandPermission;
this.commandComponents = Objects.requireNonNull(commandComponents, "Components may not be null");
this.commandExecutionHandler = Objects.requireNonNull(commandExecutionHandler, "Execution handler may not be null");
this.commandPermission = Objects.requireNonNull(commandPermission, "Permission may not be null");
}
/**

View file

@ -59,11 +59,28 @@ public abstract class CommandManager<C extends CommandSender> {
this.commandRegistrationHandler = commandRegistrationHandler;
}
/**
* Execute a command and get a future that completes with the result
*
* @param commandSender Sender of the command
* @param input Input provided by the sender
* @return Command result
*/
@Nonnull
public CompletableFuture<CommandResult> executeCommand(@Nonnull final C commandSender, @Nonnull final String input) {
final CommandContext<C> context = new CommandContext<>(commandSender);
return this.commandExecutionCoordinator.coordinateExecution(context, tokenize(input));
}
/**
* Get command suggestions for the "next" argument that would yield a correctly
* parsing command input
*
* @param commandSender Sender of the command
* @param input Input provided by the sender
* @return List of suggestions
*/
@Nonnull
public List<String> suggest(@Nonnull final C commandSender, @Nonnull final String input) {
final CommandContext<C> context = new CommandContext<>(commandSender);
return this.commandTree.getSuggestions(context, tokenize(input));
@ -105,10 +122,15 @@ public abstract class CommandManager<C extends CommandSender> {
*
* @param commandSyntaxFormatter New formatter
*/
public void setCommandSyntaxFormatter(@Nonnull final CommandSyntaxFormatter commandSyntaxFormatter) {
public void setCommandSyntaxFormatter(@Nonnull final CommandSyntaxFormatter<C> commandSyntaxFormatter) {
this.commandSyntaxFormatter = commandSyntaxFormatter;
}
/**
* Get the command registration handler
*
* @return Command registration handler
*/
@Nonnull
protected CommandRegistrationHandler getCommandRegistrationHandler() {
return this.commandRegistrationHandler;

View file

@ -172,8 +172,7 @@ public class CommandTree<C extends CommandSender> {
commandContext.getCommandSender(), this.getChain(root)
.stream()
.map(Node::getValue)
.collect(
Collectors.toList()));
.collect(Collectors.toList()));
}
} else {
final Iterator<Node<CommandComponent<C, ?>>> childIterator = root.getChildren().iterator();
@ -258,7 +257,8 @@ public class CommandTree<C extends CommandSender> {
if (component.getValue() == null || !this.isPermitted(commandContext.getCommandSender(), component)) {
continue;
}
suggestions.addAll(component.getValue().getParser().suggestions(commandContext, stringOrEmpty(commandQueue.peek())));
suggestions.addAll(
component.getValue().getParser().suggestions(commandContext, stringOrEmpty(commandQueue.peek())));
}
return suggestions;
}
@ -410,6 +410,11 @@ public class CommandTree<C extends CommandSender> {
}
/**
* Very simple tree structure
*
* @param <T> Node value type
*/
private static final class Node<T> {
private final Map<String, String> nodeMeta = new HashMap<>();

View file

@ -179,7 +179,13 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
}
public static class Builder<C extends CommandSender, T> {
/**
* Mutable builder for {@link CommandComponent} instances
*
* @param <C> Command sender type
* @param <T> Component value type
*/
public static final class Builder<C extends CommandSender, T> {
private String name;
private boolean required = true;

View file

@ -29,6 +29,11 @@ import javax.annotation.Nonnull;
import java.util.List;
import java.util.function.Function;
/**
* Utility that formats chains of {@link CommandComponent command components} into syntax strings
*
* @param <C> Command sender type
*/
@FunctionalInterface
public interface CommandSyntaxFormatter<C extends CommandSender> extends Function<List<CommandComponent<C, ?>>, String> {

View file

@ -29,6 +29,16 @@ import javax.annotation.Nonnull;
import java.util.Iterator;
import java.util.List;
/**
* {@link CommandSyntaxFormatter} implementation that uses the following rules:
* <ul>
* <li>static components are serialized as their name, without a bracket</li>
* <li>required components are serialized as their name, surrounded by angle brackets</li>
* <li>optional components are serialized as their name, surrounded by square brackets</li>
* </ul>
*
* @param <C> Command sender type
*/
public class StandardCommandSyntaxFormatter<C extends CommandSender> implements CommandSyntaxFormatter<C> {
public StandardCommandSyntaxFormatter() {

View file

@ -37,18 +37,39 @@ import java.util.Locale;
import java.util.Queue;
import java.util.Set;
/**
* {@link CommandComponent} type that recognizes fixed strings. This type does not parse variables.
*
* @param <C> Command sender type
*/
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));
}
/**
* Create a new static component instance for a required command component
*
* @param name Component name
* @param aliases Component aliases
* @param <C> Command sender type
* @return Constructed component
*/
@Nonnull
public static <C extends CommandSender> StaticComponent<C> required(@Nonnull final String name,
@Nonnull final String... aliases) {
return new StaticComponent<>(true, name, aliases);
}
/**
* Create a new static component instance for an optional command component
*
* @param name Component name
* @param aliases Component aliases
* @param <C> Command sender type
* @return Constructed component
*/
@Nonnull
public static <C extends CommandSender> StaticComponent<C> optional(@Nonnull final String name,
@Nonnull final String... aliases) {
@ -72,7 +93,7 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
@Nonnull final Queue<String> inputQueue) {
final String string = inputQueue.peek();
if (string == null) {
return ComponentParseResult.failure(this.name);
return ComponentParseResult.failure(new NullPointerException("No input provided"));
}
for (final String acceptedString : this.acceptedStrings) {
if (string.equalsIgnoreCase(acceptedString)) {
@ -81,7 +102,7 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
return ComponentParseResult.success(this.name);
}
}
return ComponentParseResult.failure(this.name);
return ComponentParseResult.failure(new IllegalArgumentException(string));
}
@Nonnull

View file

@ -30,11 +30,21 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Command context used to assist in the parsing of commands
*
* @param <C> Command sender type
*/
public class CommandContext<C extends CommandSender> {
private final Map<String, Object> internalStorage = new HashMap<>();
private final C commandSender;
/**
* Create a new command context instance
*
* @param commandSender Sender of the command
*/
public CommandContext(@Nonnull final C commandSender) {
this.commandSender = commandSender;
}

View file

@ -29,6 +29,9 @@ import com.intellectualsites.commands.sender.CommandSender;
import javax.annotation.Nonnull;
import java.util.List;
/**
* Exception sent when a {@link CommandSender} inputs invalid command syntax
*/
public class InvalidSyntaxException extends CommandParseException {
private final String correctSyntax;
@ -40,6 +43,11 @@ public class InvalidSyntaxException extends CommandParseException {
this.correctSyntax = correctSyntax;
}
/**
* Get the correct syntax of the command
*
* @return Correct command syntax
*/
@Nonnull
public String getCorrectSyntax() {
return this.correctSyntax;

View file

@ -77,7 +77,12 @@ public abstract class CommandExecutionCoordinator<C extends CommandSender> {
}
public static class SimpleCoordinator<C extends CommandSender> extends CommandExecutionCoordinator<C> {
/**
* A simple command execution coordinator that executes all commands immediately, on the calling thread
*
* @param <C> Command sender type
*/
public static final class SimpleCoordinator<C extends CommandSender> extends CommandExecutionCoordinator<C> {
private SimpleCoordinator(@Nonnull final CommandTree<C> commandTree) {
super(commandTree);

View file

@ -45,11 +45,15 @@ public interface CommandExecutionHandler<C extends CommandSender> {
void execute(@Nonnull final CommandContext<C> commandContext);
/**
* Command execution handler that does nothing
*
* @param <C> Command sender type
*/
class NullCommandExecutionHandler<C extends CommandSender> implements CommandExecutionHandler<C> {
@Override
public void execute(@Nonnull final CommandContext<C> commandContext) {
}
}

View file

@ -23,5 +23,8 @@
//
package com.intellectualsites.commands.execution;
/**
* The result of a command execution
*/
public class CommandResult {
}

View file

@ -26,26 +26,55 @@ package com.intellectualsites.commands.parser;
import javax.annotation.Nonnull;
import java.util.Optional;
/**
* Result of the parsing done by a {@link ComponentParser}
*
* @param <T> Parser return type
*/
public abstract class ComponentParseResult<T> {
private ComponentParseResult() {
}
/**
* Indicate that the parsing failed
*
* @param failure Failure reason
* @param <T> Parser return type
* @return Failed parse result
*/
@Nonnull
public static <T> ComponentParseResult<T> failure(@Nonnull final String failure) {
public static <T> ComponentParseResult<T> failure(@Nonnull final Throwable failure) {
return new ParseFailure<>(failure);
}
/**
* Indicate that the parsing succeeded
*
* @param value Value produced by the parser
* @param <T> Parser return type
* @return Succeeded parse result
*/
@Nonnull
public static <T> ComponentParseResult<T> success(@Nonnull final T value) {
return new ParseSuccess<>(value);
}
/**
* Get the parsed value, if it exists
*
* @return Optional containing the parsed value
*/
@Nonnull
public abstract Optional<T> getParsedValue();
/**
* Get the failure reason, if it exists
*
* @return Optional containing the failure reason
*/
@Nonnull
public abstract Optional<String> getFailure();
public abstract Optional<Throwable> getFailure();
private static final class ParseSuccess<T> extends ComponentParseResult<T> {
@ -64,7 +93,7 @@ public abstract class ComponentParseResult<T> {
@Nonnull
@Override
public Optional<String> getFailure() {
public Optional<Throwable> getFailure() {
return Optional.empty();
}
@ -73,9 +102,9 @@ public abstract class ComponentParseResult<T> {
private static final class ParseFailure<T> extends ComponentParseResult<T> {
private final String failure;
private final Throwable failure;
private ParseFailure(@Nonnull final String failure) {
private ParseFailure(@Nonnull final Throwable failure) {
this.failure = failure;
}
@ -87,7 +116,7 @@ public abstract class ComponentParseResult<T> {
@Nonnull
@Override
public Optional<String> getFailure() {
public Optional<Throwable> getFailure() {
return Optional.of(this.failure);
}
}

View file

@ -31,6 +31,12 @@ import java.util.Collections;
import java.util.List;
import java.util.Queue;
/**
* Parser that parses strings into values of a specific type
*
* @param <C> Command sender type
* @param <T> Value type
*/
@FunctionalInterface
public interface ComponentParser<C extends CommandSender, T> {
@ -44,6 +50,13 @@ public interface ComponentParser<C extends CommandSender, T> {
@Nonnull
ComponentParseResult<T> parse(@Nonnull CommandContext<C> commandContext, @Nonnull Queue<String> inputQueue);
/**
* Get a list of suggested arguments that would be correctly parsed by this parser
*
* @param commandContext Command context
* @param input Input string
* @return List of suggestions
*/
@Nonnull
default List<String> suggestions(@Nonnull final CommandContext<C> commandContext, @Nonnull final String input) {
return Collections.emptyList();

View file

@ -27,8 +27,11 @@ import javax.annotation.Nonnull;
public interface CommandSender {
default boolean hasPermission(@Nonnull final String permission) {
return true;
}
/**
* Check if the command sender has a given permission node
*
* @param permission Permission node
*/
boolean hasPermission(@Nonnull String permission);
}