Test priorities for inheritance
All checks were successful
zdm/event-bus/pipeline/head This commit looks good

This commit is contained in:
Kai S. K. Engelbart 2022-01-12 15:59:45 +01:00
parent 7fb633d69f
commit 722bf2b999
Signed by: kske
GPG Key ID: 8BEB13EC5DF7EF13
5 changed files with 25 additions and 11 deletions

View File

@ -225,7 +225,10 @@ To avoid this, system events never cause system events and instead just issue a
When a superclass or an interface of an event listener defines event handlers, they will be detected and registered by Event Bus, even if they are `private`.
If an event handler is overridden by the listener, the `@Event` annotation of the overridden method is automatically considered present on the overriding method.
If the overridden method contains an implementation, it is ignored as expected.
If the overridden method already contains an implementation in the superclass, the superclass implementation is ignored as expected.
The `@Priority` and `@Polymorphic` annotations are inherited both on a class and on a method level.
If the priority or polymorphism has to be redefined on an inherited handler, the `@Event` annotation has to be added explicitly.
## Debugging

View File

@ -7,7 +7,6 @@ import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import dev.kske.eventbus.core.handler.*;
@ -272,8 +271,9 @@ public final class EventBus {
Set<Method> methods = getMethodsAnnotatedWith(listenerClass, Event.class);
// Recursively add superclass handlers
if (listenerClass.getSuperclass() != null)
methods.addAll(getHandlerMethods(listenerClass.getSuperclass()));
Class<?> superClass = listenerClass.getSuperclass();
if (superClass != null && superClass != Object.class)
methods.addAll(getHandlerMethods(superClass));
// Recursively add interface handlers
for (Class<?> iClass : listenerClass.getInterfaces())
@ -292,9 +292,12 @@ public final class EventBus {
*/
private Set<Method> getMethodsAnnotatedWith(Class<?> enclosingClass,
Class<? extends Annotation> annotationClass) {
return Arrays.stream(enclosingClass.getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(annotationClass))
.collect(Collectors.toSet());
var methods = new HashSet<Method>();
for (var method : enclosingClass.getDeclaredMethods())
if (method.isAnnotationPresent(annotationClass))
methods.add(method);
return methods;
}
/**

View File

@ -5,7 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertSame;
import org.junit.jupiter.api.Test;
/**
* Tests whether event handlers correctly work in the context of an inheritance hierarchy.
* Tests whether event handlers correctly work in the context of an inheritance hierarchy. The
* effect of handler priorities is also accounted for.
*
* @author Kai S. K. Engelbart
* @since 1.3.0
@ -20,12 +21,12 @@ class InheritanceTest extends SimpleEventListenerBase implements SimpleEventList
var event = new SimpleEvent();
bus.dispatch(event);
assertSame(4, event.getCounter());
assertSame(3, event.getCounter());
}
@Override
void onSimpleEventAbstractHandler(SimpleEvent event) {
event.increment();
assertSame(1, event.getCounter());
}
@Override
@ -35,6 +36,7 @@ class InheritanceTest extends SimpleEventListenerBase implements SimpleEventList
@Event
private void onSimpleEventPrivate(SimpleEvent event) {
assertSame(0, event.getCounter());
event.increment();
}
}

View File

@ -1,20 +1,25 @@
package dev.kske.eventbus.core;
import static org.junit.jupiter.api.Assertions.*;
/**
* An abstract class defining a package-private and a private handler for {@link SimpleEvent}.
*
* @author Kai S. K. Engelbart
* @since 1.3.0
*/
@Priority(200)
abstract class SimpleEventListenerBase {
@Event
void onSimpleEventAbstractHandler(SimpleEvent event) {
event.increment();
fail("This handler should not be invoked");
}
@Priority(150)
@Event
private void onSimpleEventPrivate(SimpleEvent event) {
assertSame(1, event.getCounter());
event.increment();
}
}

View File

@ -8,6 +8,7 @@ package dev.kske.eventbus.core;
*/
interface SimpleEventListenerInterface {
@Priority(120)
@Event
void onSimpleEventInterfaceHandler(SimpleEvent event);
}