Allow inherited methods to be event handlers. Addresses BUKKIT-2299

This change lets JavaPluginLoader use a temporary HashSet to store
methods that could possibly have the EventHandler annotation. Duplicates
are prevented by the nature of a Set.

Registering parent listeners is a breaking change for any listener
extending another listener and expecting parent listeners to not be
called. Changing this is justified by the ease-of-use and proper object
inheritance design. If this is undesired behavior, the method may be
overridden without reapplying the method with the EventHandler notation.

By: Wesley Wolfe <weswolf@aol.com>
This commit is contained in:
Bukkit/Spigot 2012-08-26 21:14:28 -05:00
parent f7b46ffa10
commit 29a5295348

View File

@ -276,16 +276,22 @@ public class JavaPluginLoader implements PluginLoader {
boolean useTimings = server.getPluginManager().useTimings();
Map<Class<? extends Event>, Set<RegisteredListener>> ret = new HashMap<Class<? extends Event>, Set<RegisteredListener>>();
Method[] methods;
Set<Method> methods;
try {
methods = listener.getClass().getDeclaredMethods();
Method[] publicMethods = listener.getClass().getMethods();
methods = new HashSet<Method>(publicMethods.length, Float.MAX_VALUE);
for (Method method : publicMethods) {
methods.add(method);
}
for (Method method : listener.getClass().getDeclaredMethods()) {
methods.add(method);
}
} catch (NoClassDefFoundError e) {
plugin.getLogger().severe("Plugin " + plugin.getDescription().getFullName() + " has failed to register events for " + listener.getClass() + " because " + e.getMessage() + " does not exist.");
return ret;
}
for (int i = 0; i < methods.length; i++) {
final Method method = methods[i];
for (final Method method : methods) {
final EventHandler eh = method.getAnnotation(EventHandler.class);
if (eh == null) continue;
final Class<?> checkClass = method.getParameterTypes()[0];