Make use of the parser repository in the component builder
This commit is contained in:
parent
14b5d9fc3c
commit
b3d75496b5
4 changed files with 116 additions and 42 deletions
|
|
@ -135,7 +135,8 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
public static <C extends CommandSender, M extends CommandMeta> Builder<C, M> newBuilder(@Nonnull final String commandName,
|
||||
@Nonnull final M commandMeta,
|
||||
@Nonnull final String... aliases) {
|
||||
return new Builder<>(commandMeta, null, Collections.singletonList(StaticComponent.required(commandName, aliases)),
|
||||
return new Builder<>(null, commandMeta, null,
|
||||
Collections.singletonList(StaticComponent.required(commandName, aliases)),
|
||||
new CommandExecutionHandler.NullCommandExecutionHandler<>(), "");
|
||||
}
|
||||
|
||||
|
|
@ -223,12 +224,15 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
@Nonnull private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
@Nullable private final Class<? extends C> senderType;
|
||||
@Nonnull private final String commandPermission;
|
||||
@Nullable private final CommandManager<C, M> commandManager;
|
||||
|
||||
private Builder(@Nonnull final M commandMeta,
|
||||
private Builder(@Nullable final CommandManager<C, M> commandManager,
|
||||
@Nonnull final M commandMeta,
|
||||
@Nullable final Class<? extends C> senderType,
|
||||
@Nonnull final List<CommandComponent<C, ?>> commandComponents,
|
||||
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
|
||||
@Nonnull final String commandPermission) {
|
||||
this.commandManager = commandManager;
|
||||
this.senderType = senderType;
|
||||
this.commandComponents = Objects.requireNonNull(commandComponents, "Components may not be null");
|
||||
this.commandExecutionHandler = Objects.requireNonNull(commandExecutionHandler, "Execution handler may not be null");
|
||||
|
|
@ -236,6 +240,20 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
this.commandMeta = Objects.requireNonNull(commandMeta, "Meta may not be null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply a command manager instance to the builder. This will be used when attempting to
|
||||
* retrieve command component parsers, in the case that they're needed. This
|
||||
* is optional
|
||||
*
|
||||
* @param commandManager Command manager
|
||||
* @return New builder instance using the provided command manager
|
||||
*/
|
||||
@Nonnull
|
||||
public Builder<C, M> manager(@Nullable final CommandManager<C, M> commandManager) {
|
||||
return new Builder<>(commandManager, this.commandMeta, this.senderType, this.commandComponents,
|
||||
this.commandExecutionHandler, this.commandPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new command component to the command
|
||||
*
|
||||
|
|
@ -247,8 +265,8 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
public <T> Builder<C, M> component(@Nonnull final CommandComponent<C, T> component) {
|
||||
final List<CommandComponent<C, ?>> commandComponents = new LinkedList<>(this.commandComponents);
|
||||
commandComponents.add(component);
|
||||
return new Builder<>(this.commandMeta, this.senderType, commandComponents, this.commandExecutionHandler,
|
||||
this.commandPermission);
|
||||
return new Builder<>(this.commandManager, this.commandMeta, this.senderType, commandComponents,
|
||||
this.commandExecutionHandler, this.commandPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -265,6 +283,9 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
@Nonnull final String name,
|
||||
@Nonnull final Consumer<CommandComponent.Builder<C, T>> builderConsumer) {
|
||||
final CommandComponent.Builder<C, T> builder = CommandComponent.ofType(clazz, name);
|
||||
if (this.commandManager != null) {
|
||||
builder.manager(this.commandManager);
|
||||
}
|
||||
builderConsumer.accept(builder);
|
||||
return this.component(builder.build());
|
||||
}
|
||||
|
|
@ -277,8 +298,8 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
*/
|
||||
@Nonnull
|
||||
public Builder<C, M> handler(@Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
return new Builder<>(this.commandMeta, this.senderType, this.commandComponents, commandExecutionHandler,
|
||||
this.commandPermission);
|
||||
return new Builder<>(this.commandManager, this.commandMeta, this.senderType, this.commandComponents,
|
||||
commandExecutionHandler, this.commandPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -289,8 +310,8 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
*/
|
||||
@Nonnull
|
||||
public Builder<C, M> withSenderType(@Nonnull final Class<? extends C> senderType) {
|
||||
return new Builder<>(this.commandMeta, senderType, this.commandComponents, this.commandExecutionHandler,
|
||||
this.commandPermission);
|
||||
return new Builder<>(this.commandManager, this.commandMeta, senderType, this.commandComponents,
|
||||
this.commandExecutionHandler, this.commandPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -301,8 +322,8 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
*/
|
||||
@Nonnull
|
||||
public Builder<C, M> withPermission(@Nonnull final String permission) {
|
||||
return new Builder<>(this.commandMeta, this.senderType, this.commandComponents, this.commandExecutionHandler,
|
||||
permission);
|
||||
return new Builder<>(this.commandManager, this.commandMeta, this.senderType, this.commandComponents,
|
||||
this.commandExecutionHandler, permission);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -312,8 +333,8 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
|
|||
*/
|
||||
@Nonnull
|
||||
public Command<C, M> build() {
|
||||
return new Command<>(Collections.unmodifiableList(this.commandComponents), this.commandExecutionHandler,
|
||||
this.senderType, this.commandPermission, this.commandMeta);
|
||||
return new Command<>(Collections.unmodifiableList(this.commandComponents),
|
||||
this.commandExecutionHandler, this.senderType, this.commandPermission, this.commandMeta);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
package com.intellectualsites.commands;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.intellectualsites.commands.components.CommandComponent;
|
||||
import com.intellectualsites.commands.components.CommandSyntaxFormatter;
|
||||
import com.intellectualsites.commands.components.StandardCommandSyntaxFormatter;
|
||||
import com.intellectualsites.commands.components.parser.ParserRegistry;
|
||||
|
|
@ -231,7 +232,20 @@ public abstract class CommandManager<C extends CommandSender, M extends CommandM
|
|||
*/
|
||||
@Nonnull
|
||||
public Command.Builder<C, M> commandBuilder(@Nonnull final String name) {
|
||||
return Command.newBuilder(name, this.createDefaultCommandMeta());
|
||||
return Command.<C, M>newBuilder(name, this.createDefaultCommandMeta()).manager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new command component builder
|
||||
*
|
||||
* @param type Component type
|
||||
* @param name Component name
|
||||
* @param <T> Generic component name
|
||||
* @return Component builder
|
||||
*/
|
||||
@Nonnull
|
||||
public <T> CommandComponent.Builder<C, T> componentBuilder(@Nonnull final Class<T> type, @Nonnull final String name) {
|
||||
return CommandComponent.<C, T>ofType(type, name).manager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,9 +23,12 @@
|
|||
//
|
||||
package com.intellectualsites.commands.components;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.intellectualsites.commands.Command;
|
||||
import com.intellectualsites.commands.CommandManager;
|
||||
import com.intellectualsites.commands.components.parser.ComponentParseResult;
|
||||
import com.intellectualsites.commands.components.parser.ComponentParser;
|
||||
import com.intellectualsites.commands.components.parser.ParserParameters;
|
||||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
|
@ -263,9 +266,9 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
private final Class<T> valueType;
|
||||
private final String name;
|
||||
|
||||
private CommandManager<C, ?> manager;
|
||||
private boolean required = true;
|
||||
private ComponentParser<C, T> parser = (c, i) -> ComponentParseResult.failure(
|
||||
new UnsupportedOperationException("No parser was specified"));
|
||||
private ComponentParser<C, T> parser;
|
||||
private String defaultValue = "";
|
||||
|
||||
protected Builder(@Nonnull final Class<T> valueType,
|
||||
|
|
@ -274,6 +277,19 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command manager. Will be used to create a default parser
|
||||
* if none was provided
|
||||
*
|
||||
* @param manager Command manager
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull
|
||||
public Builder<C, T> manager(@Nonnull final CommandManager<C, ?> manager) {
|
||||
this.manager = manager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the component is required.
|
||||
* All components prior to any other required
|
||||
|
|
@ -340,6 +356,14 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*/
|
||||
@Nonnull
|
||||
public CommandComponent<C, T> build() {
|
||||
if (this.parser == null && this.manager != null) {
|
||||
this.parser = this.manager.getParserRegistry().createParser(TypeToken.of(valueType), ParserParameters.empty())
|
||||
.orElse(null);
|
||||
}
|
||||
if (this.parser == null) {
|
||||
this.parser = (c, i) -> ComponentParseResult
|
||||
.failure(new UnsupportedOperationException("No parser was specified"));
|
||||
}
|
||||
return new CommandComponent<>(this.required, this.name, this.parser, this.defaultValue, this.valueType);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,66 +42,81 @@ import java.util.concurrent.CompletionException;
|
|||
class CommandTreeTest {
|
||||
|
||||
private static final int EXPECTED_INPUT_NUMBER = 15;
|
||||
private static CommandManager<CommandSender, SimpleCommandMeta> commandManager;
|
||||
private static CommandManager<CommandSender, SimpleCommandMeta> manager;
|
||||
|
||||
@BeforeAll
|
||||
static void newTree() {
|
||||
commandManager = new TestCommandManager();
|
||||
commandManager.command(commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("one")).build())
|
||||
.command(commandManager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("two")).withPermission("no").build())
|
||||
.command(commandManager.commandBuilder("test", Collections.singleton("other"),
|
||||
SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("opt", "öpt"))
|
||||
.component(IntegerComponent
|
||||
manager = new TestCommandManager();
|
||||
manager.command(manager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("one")).build())
|
||||
.command(manager.commandBuilder("test", SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("two")).withPermission("no").build())
|
||||
.command(manager.commandBuilder("test", Collections.singleton("other"),
|
||||
SimpleCommandMeta.empty())
|
||||
.component(StaticComponent.required("opt", "öpt"))
|
||||
.component(IntegerComponent
|
||||
.optional("num", EXPECTED_INPUT_NUMBER))
|
||||
.build())
|
||||
.command(commandManager.commandBuilder("req").withSenderType(SpecificCommandSender.class).build());
|
||||
.build())
|
||||
.command(manager.commandBuilder("req").withSenderType(SpecificCommandSender.class).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void parse() {
|
||||
final Optional<Command<CommandSender, SimpleCommandMeta>> command = commandManager.getCommandTree()
|
||||
.parse(new CommandContext<>(
|
||||
final Optional<Command<CommandSender, SimpleCommandMeta>> command = manager.getCommandTree()
|
||||
.parse(new CommandContext<>(
|
||||
new TestCommandSender()),
|
||||
new LinkedList<>(
|
||||
Arrays.asList("test",
|
||||
"one")));
|
||||
Assertions.assertTrue(command.isPresent());
|
||||
Assertions.assertThrows(NoPermissionException.class, () -> commandManager.getCommandTree()
|
||||
.parse(new CommandContext<>(
|
||||
Assertions.assertThrows(NoPermissionException.class, () -> manager.getCommandTree()
|
||||
.parse(new CommandContext<>(
|
||||
new TestCommandSender()),
|
||||
new LinkedList<>(
|
||||
Arrays.asList("test", "two"))));
|
||||
commandManager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt")))
|
||||
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
|
||||
commandManager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt", "12")))
|
||||
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
|
||||
manager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt")))
|
||||
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
|
||||
manager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt", "12")))
|
||||
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAlias() {
|
||||
commandManager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("other", "öpt", "12")))
|
||||
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
|
||||
manager.getCommandTree()
|
||||
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("other", "öpt", "12")))
|
||||
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSuggestions() {
|
||||
Assertions.assertFalse(
|
||||
commandManager.getCommandTree().getSuggestions(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
|
||||
manager.getCommandTree().getSuggestions(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
|
||||
Collections.singletonList("test "))).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRequiredSender() {
|
||||
Assertions.assertThrows(CompletionException.class, () ->
|
||||
commandManager.executeCommand(new TestCommandSender(), "req").join());
|
||||
manager.executeCommand(new TestCommandSender(), "req").join());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultParser() {
|
||||
manager.command(
|
||||
manager.commandBuilder("default")
|
||||
.component(manager.componentBuilder(Integer.class, "int").build())
|
||||
.handler(context -> {
|
||||
final int number = context.getRequired("int");
|
||||
System.out.printf("Supplied number is: %d\n", number);
|
||||
})
|
||||
.build()
|
||||
);
|
||||
manager.executeCommand(new TestCommandSender(), "default 5").join();
|
||||
}
|
||||
|
||||
|
||||
public static final class SpecificCommandSender extends TestCommandSender {
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue