Skip to content

Commit

Permalink
Added MissingSubcommandException, plus some more internal changes
Browse files Browse the repository at this point in the history
  • Loading branch information
prokopyl committed Dec 17, 2020
1 parent fd54913 commit 02f02dd
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package fr.zcraft.quartzlib.components.commands;

import fr.zcraft.quartzlib.components.commands.exceptions.CommandException;
import fr.zcraft.quartzlib.components.commands.exceptions.MissingSubcommandException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;

class CommandGroup extends CommandNode {
public class CommandGroup extends CommandNode {
private final Class<?> commandGroupClass;

@Nullable
Expand Down Expand Up @@ -52,7 +54,7 @@ private CommandGroup(
DiscoveryUtils.getSubCommands(this, typeCollection).forEach(this::addSubCommand);
}

public Iterable<CommandNode> getSubCommands() {
public Collection<CommandNode> getSubCommands() {
return this.subCommands.values();
}

Expand Down Expand Up @@ -91,6 +93,10 @@ void run(Object parentInstance, CommandSender sender, String[] args) throws Comm
}

private void runSelf(Object instance, CommandSender sender, String[] args) throws CommandException {
if (args.length == 0) {
throw new MissingSubcommandException(this);
}

String commandName = args[0];
CommandNode subCommand = subCommands.get(commandName);
// TODO: handle null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CommandMethod {
if (parameter.isAnnotationPresent(Sender.class)) { // TODO: check for multiple sender arguments
senderArgument = new CommandMethodSenderArgument(parameter, i, typeCollection);
} else {
arguments.add(new CommandMethodArgument(parameter, i, typeCollection));
arguments.add(new CommandMethodArgument(this, parameter, i, typeCollection));
}
}

Expand Down Expand Up @@ -69,4 +69,8 @@ private Object[] parseArguments(CommandSender sender, String[] args)
public CommandMethodArgument[] getArguments() {
return arguments;
}

public Method getMethod() {
return method;
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package fr.zcraft.quartzlib.components.commands;

import fr.zcraft.quartzlib.components.commands.exceptions.ArgumentParseException;
import fr.zcraft.quartzlib.components.commands.exceptions.UnknownArgumentTypeException;
import java.lang.reflect.Parameter;

public class CommandMethodArgument {
private final Parameter parameter;
private final int position;
private final ArgumentTypeWrapper<?> typeHandler;

public CommandMethodArgument(Parameter parameter, int position, TypeCollection typeCollection) {
public CommandMethodArgument(
CommandMethod parent,
Parameter parameter,
int position,
TypeCollection typeCollection
) {
this.parameter = parameter;
this.position = position;
this.typeHandler = typeCollection.findArgumentType(parameter.getType()).get(); // FIXME: handle unknown types
this.typeHandler = typeCollection.findArgumentType(parameter.getType())
.orElseThrow(() -> new UnknownArgumentTypeException(parent.getMethod(), parameter.getType()));
}

public Object parse(String raw) throws ArgumentParseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;

abstract class CommandNode {
public abstract class CommandNode {
private final String name;
@Nullable private final CommandGroup parent;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package fr.zcraft.quartzlib.components.commands;

import org.bukkit.command.CommandSender;

public class ExecutionContext {
private final CommandSender sender;
private final String[] fullArgs;

public ExecutionContext(CommandSender sender, String[] fullArgs) {
this.sender = sender;
this.fullArgs = fullArgs;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.zcraft.quartzlib.components.commands;

import fr.zcraft.quartzlib.components.commands.exceptions.CommandException;
import fr.zcraft.quartzlib.tools.text.RawMessage;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
Expand All @@ -19,7 +20,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
try {
group.run(sender, args);
} catch (CommandException e) {
throw new RuntimeException(e); // TODO
RawMessage.send(sender, e.display(sender).build());
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ private void registerNativeTypes() {
register(new ArgumentTypeWrapper<>(Integer.class, new IntegerArgumentType()));
register(new ArgumentTypeWrapper<>(String.class, s -> s));

register(new ArgumentTypeWrapper<>(int.class, new IntegerArgumentType()));

// Generic types
register(new EnumArgumentType());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
package fr.zcraft.quartzlib.components.commands.exceptions;

import fr.zcraft.quartzlib.components.rawtext.RawText;
import org.bukkit.command.CommandSender;

public class ArgumentParseException extends CommandException {
@Override
public RawText display(CommandSender sender) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
package fr.zcraft.quartzlib.components.commands.exceptions;

import fr.zcraft.quartzlib.components.rawtext.RawText;
import org.bukkit.command.CommandSender;

public abstract class CommandException extends Exception {
public abstract RawText display(CommandSender sender);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
package fr.zcraft.quartzlib.components.commands.exceptions;

import fr.zcraft.quartzlib.components.rawtext.RawText;
import org.bukkit.command.CommandSender;

public class InvalidSenderException extends CommandException {
@Override
public RawText display(CommandSender sender) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package fr.zcraft.quartzlib.components.commands.exceptions;

import fr.zcraft.quartzlib.components.commands.CommandGroup;
import fr.zcraft.quartzlib.components.commands.CommandNode;
import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.components.rawtext.RawText;
import fr.zcraft.quartzlib.components.rawtext.RawTextPart;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;

public class MissingSubcommandException extends CommandException {
private final CommandGroup commandGroup;

public MissingSubcommandException(CommandGroup commandGroup) {
this.commandGroup = commandGroup;
}

@Override
public RawText display(CommandSender sender) {
RawTextPart<?> text = new RawText(I.t("Missing subcommand: "))
.color(ChatColor.RED)
.then("/").color(ChatColor.WHITE)
.then(getParents()).color(ChatColor.AQUA)
.then(" <").style(ChatColor.GRAY)
.then(I.t("sub-command"))
.style(ChatColor.GRAY, ChatColor.UNDERLINE)
.hover(appendSubCommandList(new RawText()))
.then(">").style(ChatColor.GRAY);

return text.build();
}

private String getParents() {
StringBuilder builder = new StringBuilder();

CommandGroup group = commandGroup;

do {
if (builder.length() > 0) {
builder.append(' ');
}
builder.append(group.getName());
group = group.getParent();
} while (group != null);

return builder.toString();
}

private RawTextPart<?> appendSubCommandList(RawTextPart<?> text) {
boolean first = true;
text = text.then(I.t("One of the following:\n "));
for (CommandNode subCommand : commandGroup.getSubCommands()) {
if (!first) {
text = text.then(", ").color(ChatColor.GRAY);
}
first = false;

text = text.then(subCommand.getName()).color(ChatColor.AQUA);
}

return text;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package fr.zcraft.quartzlib.components.commands.exceptions;

import java.lang.reflect.Method;

public class UnknownArgumentTypeException extends RuntimeException {
public UnknownArgumentTypeException(Method method, Class<?> foundType) {
super(getErrorMessage(method, foundType));
}

private static String getErrorMessage(Method method, Class<?> foundType) {
return "Found unknown command argument type: '" + foundType
+ "' (found in '" + method.toString() + "'). "
+ "Did you forget to register it to the CommandManager?";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* Utility to send JSON messages.
*
* <p>This tool uses the /tellraw command to send the messages. If the JSON is not correctly
* formatted, the message will not be sent and a Runtime exception containing the exception throw by
* formatted, the message will not be sent and a Runtime exception containing the exception thrown by
* the vanilla /tellraw command will be thrown.</p>
*/
public final class RawMessage {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.junit.Before;
import org.junit.Test;

public class CommandRegistrationTests extends MockedToasterTest {
public class CommandExecutionTests extends MockedToasterTest {
private CommandManager commands;

@Before
Expand Down
9 changes: 7 additions & 2 deletions ztoaster/src/main/java/fr/zcraft/ztoaster/Toaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

package fr.zcraft.ztoaster;

import fr.zcraft.quartzlib.components.commands.CommandManager;
import fr.zcraft.quartzlib.components.gui.Gui;
import fr.zcraft.quartzlib.components.i18n.I18n;
import fr.zcraft.quartzlib.components.scoreboard.Sidebar;
Expand Down Expand Up @@ -64,14 +65,16 @@ public class Toaster extends QuartzPlugin implements Listener {
*/
private Sidebar toasterSidebar;

public Toaster () {}
public Toaster() {
}

protected Toaster(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file);
}

/**
* .
*
* @return The id for a new toast.
*/
public static int newToastId() {
Expand All @@ -80,6 +83,7 @@ public static int newToastId() {

/**
* .
*
* @return an array of all the toasts ever created (until toaster restart).
*/
public static Toast[] getToasts() {
Expand All @@ -106,7 +110,8 @@ public void onEnable() {

loadComponents(Gui.class, ToasterWorker.class, SidebarScoreboard.class, I18n.class);

// Commands.register("toaster", AddCommand.class, OpenCommand.class, ListCommand.class);
new CommandManager()
.registerCommand("toaster", ToastCommands.class, ToastCommands::new);

I18n.useDefaultPrimaryLocale();
I18n.setFallbackLocale(Locale.US);
Expand Down

0 comments on commit 02f02dd

Please sign in to comment.