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 @Nonnull
public abstract Player asPlayer(); 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 List<CommandComponent<C, ?>> commandComponents;
@Nonnull private final CommandExecutionHandler<C> commandExecutionHandler; @Nonnull private final CommandExecutionHandler<C> commandExecutionHandler;
@ -155,10 +161,10 @@ public class Command<C extends CommandSender> {
@Nonnull final List<CommandComponent<C, ?>> commandComponents, @Nonnull final List<CommandComponent<C, ?>> commandComponents,
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler, @Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
@Nonnull final String commandPermission) { @Nonnull final String commandPermission) {
this.commandComponents = commandComponents;
this.commandExecutionHandler = commandExecutionHandler;
this.senderType = senderType; 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; 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) { public CompletableFuture<CommandResult> executeCommand(@Nonnull final C commandSender, @Nonnull final String input) {
final CommandContext<C> context = new CommandContext<>(commandSender); final CommandContext<C> context = new CommandContext<>(commandSender);
return this.commandExecutionCoordinator.coordinateExecution(context, tokenize(input)); 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) { public List<String> suggest(@Nonnull final C commandSender, @Nonnull final String input) {
final CommandContext<C> context = new CommandContext<>(commandSender); final CommandContext<C> context = new CommandContext<>(commandSender);
return this.commandTree.getSuggestions(context, tokenize(input)); return this.commandTree.getSuggestions(context, tokenize(input));
@ -105,10 +122,15 @@ public abstract class CommandManager<C extends CommandSender> {
* *
* @param commandSyntaxFormatter New formatter * @param commandSyntaxFormatter New formatter
*/ */
public void setCommandSyntaxFormatter(@Nonnull final CommandSyntaxFormatter commandSyntaxFormatter) { public void setCommandSyntaxFormatter(@Nonnull final CommandSyntaxFormatter<C> commandSyntaxFormatter) {
this.commandSyntaxFormatter = commandSyntaxFormatter; this.commandSyntaxFormatter = commandSyntaxFormatter;
} }
/**
* Get the command registration handler
*
* @return Command registration handler
*/
@Nonnull @Nonnull
protected CommandRegistrationHandler getCommandRegistrationHandler() { protected CommandRegistrationHandler getCommandRegistrationHandler() {
return this.commandRegistrationHandler; return this.commandRegistrationHandler;

View file

@ -172,8 +172,7 @@ public class CommandTree<C extends CommandSender> {
commandContext.getCommandSender(), this.getChain(root) commandContext.getCommandSender(), this.getChain(root)
.stream() .stream()
.map(Node::getValue) .map(Node::getValue)
.collect( .collect(Collectors.toList()));
Collectors.toList()));
} }
} else { } else {
final Iterator<Node<CommandComponent<C, ?>>> childIterator = root.getChildren().iterator(); 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)) { if (component.getValue() == null || !this.isPermitted(commandContext.getCommandSender(), component)) {
continue; continue;
} }
suggestions.addAll(component.getValue().getParser().suggestions(commandContext, stringOrEmpty(commandQueue.peek()))); suggestions.addAll(
component.getValue().getParser().suggestions(commandContext, stringOrEmpty(commandQueue.peek())));
} }
return suggestions; 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 static final class Node<T> {
private final Map<String, String> nodeMeta = new HashMap<>(); 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 String name;
private boolean required = true; private boolean required = true;

View file

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

View file

@ -37,18 +37,39 @@ import java.util.Locale;
import java.util.Queue; import java.util.Queue;
import java.util.Set; 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> { public final class StaticComponent<C extends CommandSender> extends CommandComponent<C, String> {
private StaticComponent(final boolean required, @Nonnull final String name, @Nonnull final String... aliases) { 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));
} }
/**
* 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 @Nonnull
public static <C extends CommandSender> StaticComponent<C> required(@Nonnull final String name, public static <C extends CommandSender> StaticComponent<C> required(@Nonnull final String name,
@Nonnull final String... aliases) { @Nonnull final String... aliases) {
return new StaticComponent<>(true, name, 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 @Nonnull
public static <C extends CommandSender> StaticComponent<C> optional(@Nonnull final String name, public static <C extends CommandSender> StaticComponent<C> optional(@Nonnull final String name,
@Nonnull final String... aliases) { @Nonnull final String... aliases) {
@ -72,7 +93,7 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
@Nonnull final Queue<String> inputQueue) { @Nonnull final Queue<String> inputQueue) {
final String string = inputQueue.peek(); final String string = inputQueue.peek();
if (string == null) { if (string == null) {
return ComponentParseResult.failure(this.name); return ComponentParseResult.failure(new NullPointerException("No input provided"));
} }
for (final String acceptedString : this.acceptedStrings) { for (final String acceptedString : this.acceptedStrings) {
if (string.equalsIgnoreCase(acceptedString)) { if (string.equalsIgnoreCase(acceptedString)) {
@ -81,7 +102,7 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
return ComponentParseResult.success(this.name); return ComponentParseResult.success(this.name);
} }
} }
return ComponentParseResult.failure(this.name); return ComponentParseResult.failure(new IllegalArgumentException(string));
} }
@Nonnull @Nonnull

View file

@ -30,11 +30,21 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional; 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> { public class CommandContext<C extends CommandSender> {
private final Map<String, Object> internalStorage = new HashMap<>(); private final Map<String, Object> internalStorage = new HashMap<>();
private final C commandSender; private final C commandSender;
/**
* Create a new command context instance
*
* @param commandSender Sender of the command
*/
public CommandContext(@Nonnull final C commandSender) { public CommandContext(@Nonnull final C commandSender) {
this.commandSender = commandSender; this.commandSender = commandSender;
} }

View file

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

View file

@ -45,11 +45,15 @@ public interface CommandExecutionHandler<C extends CommandSender> {
void execute(@Nonnull final CommandContext<C> commandContext); 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> { class NullCommandExecutionHandler<C extends CommandSender> implements CommandExecutionHandler<C> {
@Override @Override
public void execute(@Nonnull final CommandContext<C> commandContext) { public void execute(@Nonnull final CommandContext<C> commandContext) {
} }
} }

View file

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

View file

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

View file

@ -31,6 +31,12 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
/**
* Parser that parses strings into values of a specific type
*
* @param <C> Command sender type
* @param <T> Value type
*/
@FunctionalInterface @FunctionalInterface
public interface ComponentParser<C extends CommandSender, T> { public interface ComponentParser<C extends CommandSender, T> {
@ -44,6 +50,13 @@ public interface ComponentParser<C extends CommandSender, T> {
@Nonnull @Nonnull
ComponentParseResult<T> parse(@Nonnull CommandContext<C> commandContext, @Nonnull Queue<String> inputQueue); 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 @Nonnull
default List<String> suggestions(@Nonnull final CommandContext<C> commandContext, @Nonnull final String input) { default List<String> suggestions(@Nonnull final CommandContext<C> commandContext, @Nonnull final String input) {
return Collections.emptyList(); return Collections.emptyList();

View file

@ -27,8 +27,11 @@ import javax.annotation.Nonnull;
public interface CommandSender { 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);
} }