106 lines
3.1 KiB
Java
106 lines
3.1 KiB
Java
package dev.kske.eventbus.core.handler;
|
|
|
|
import java.lang.reflect.*;
|
|
|
|
import dev.kske.eventbus.core.*;
|
|
import dev.kske.eventbus.core.Event.USE_PARAMETER;
|
|
|
|
/**
|
|
* An event handler wrapping a method annotated with {@link Event} and executing it using
|
|
* reflection.
|
|
*
|
|
* @author Kai S. K. Engelbart
|
|
* @since 1.2.0
|
|
*/
|
|
public final class ReflectiveEventHandler implements EventHandler {
|
|
|
|
private final Object listener;
|
|
private final Method method;
|
|
private final Class<?> eventType;
|
|
private final boolean useParameter;
|
|
private final boolean polymorphic;
|
|
private final int priority;
|
|
|
|
/**
|
|
* Constructs a reflective event handler.
|
|
*
|
|
* @param listener the listener containing the handler
|
|
* @param method the handler method
|
|
* @param annotation the event annotation
|
|
* @param defPolymorphism the predefined polymorphism (default or listener-level)
|
|
* @param defPriority the predefined priority (default or listener-level)
|
|
* @throws EventBusException if the method or the annotation do not comply with the
|
|
* specification
|
|
* @since 1.2.0
|
|
*/
|
|
public ReflectiveEventHandler(Object listener, Method method, Event annotation,
|
|
boolean defPolymorphism, int defPriority) throws EventBusException {
|
|
this.listener = listener;
|
|
this.method = method;
|
|
useParameter = annotation.value() == USE_PARAMETER.class;
|
|
|
|
// Check handler signature
|
|
if (method.getParameterCount() == 0 && useParameter)
|
|
throw new EventBusException(method + " does not define an event type!");
|
|
|
|
if (method.getParameterCount() == 1 && !useParameter)
|
|
throw new EventBusException(method + " defines an ambiguous event type!");
|
|
|
|
if (method.getParameterCount() > 1)
|
|
throw new EventBusException(method + " defines more than one parameter!");
|
|
|
|
// Determine handler properties
|
|
eventType = useParameter ? method.getParameterTypes()[0] : annotation.value();
|
|
polymorphic = method.isAnnotationPresent(Polymorphic.class)
|
|
? method.getAnnotation(Polymorphic.class).value()
|
|
: defPolymorphism;
|
|
priority = method.isAnnotationPresent(Priority.class)
|
|
? method.getAnnotation(Priority.class).value()
|
|
: defPriority;
|
|
|
|
// Allow access if the method is non-public
|
|
method.setAccessible(true);
|
|
}
|
|
|
|
@Override
|
|
public void execute(Object event) throws EventBusException, InvocationTargetException {
|
|
try {
|
|
if (useParameter)
|
|
method.invoke(getListener(), event);
|
|
else
|
|
method.invoke(getListener());
|
|
} catch (IllegalArgumentException e) {
|
|
throw new EventBusException("Event handler rejected target / argument!", e);
|
|
} catch (IllegalAccessException e) {
|
|
throw new EventBusException("Event handler is not accessible!", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return String.format(
|
|
"ReflectiveEventHandler[eventType=%s, polymorphic=%b, priority=%d, method=%s, useParameter=%b]",
|
|
eventType, polymorphic, priority, method, useParameter);
|
|
}
|
|
|
|
@Override
|
|
public Object getListener() {
|
|
return listener;
|
|
}
|
|
|
|
@Override
|
|
public Class<?> getEventType() {
|
|
return eventType;
|
|
}
|
|
|
|
@Override
|
|
public int getPriority() {
|
|
return priority;
|
|
}
|
|
|
|
@Override
|
|
public boolean isPolymorphic() {
|
|
return polymorphic;
|
|
}
|
|
}
|