I'm writing a IRC bot that responds to commands like !time, !sayHello and similar. One of the challenges I've had is that parsing these commands ended up with a long if/else bundle. To get around this problem of a big if/else tumble, I'm trying to use annotations to add extra commands into the bot, this makes the code look far cleaner and is easier to maintain and extend.
It looks like this;
public class ExampleChatPlugin extends Plugin {
@CommandMessage(command="!time")
public void handleTime(Bot bot, String channel, Command fullMessage) {
bot.sendMessage(channel, "I don't know the time :(");
}
@CommandMessage(command="!sayHello")
public void handleSayHello(Bot bot, String channel, Command fullMessage) {
bot.sendMessage(channel, "Oh, hi there.");
}
// etc...
}
So! I have message handling method in the superclass Plugin that works out which method to call when a message is received. This method is here;
public void callCommandMessages(String channel, String sender, String input) {
Command command = new Command(input);
for (Method m : this.getMethodsWithAnnotation()) {
String keyword = m.getAnnotation(CommandMessage.class).keyword();
if (keyword.isEmpty()) {
keyword = m.getName();
}
if (command.supportsKeyword(keyword)) {
if (m.getGenericParameterTypes().length < 4) {
MessagePlugin.LOG.debug("InputSelector method found for " + input + ", but this method needs to 4 arguments");
} else {
try {
m.invoke(this, channel, sender, command);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
System.out.println("Could not find: " + input);
}
So, my problem is that this method checks if the @CommandMessage method takes 4 parameters, but this isn't very strict and most importantly it's only detected at runtime. It sucks!
Is there I way that I get get an annotated method to be forced to have the parameters Bot bot, String channel, String sender, Command command
I know the most obvious way would be an interface as that is precisely what they were designed for, but this means having a class for every single @CommandMessage and that really sucks too.