
com.opencredo.concursus.mapping.events.methods.reflection.dispatching.EventDispatchers Maven / Gradle / Ivy
The newest version!
package com.opencredo.concursus.mapping.events.methods.reflection.dispatching;
import com.opencredo.concursus.domain.events.Event;
import com.opencredo.concursus.domain.events.EventType;
import com.opencredo.concursus.mapping.events.methods.reflection.interpreting.EventMethodMapping;
import com.opencredo.concursus.mapping.reflection.MethodInvoking;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import static com.google.common.base.Preconditions.*;
import static java.util.stream.Collectors.toMap;
public final class EventDispatchers {
private EventDispatchers() {
}
public static InitialEventDispatcher toFactoryMethod(Class extends T> targetClass, Method method, EventMethodMapping methodInfo) {
return event -> MethodInvoking.invokingStatic(targetClass, method).apply(methodInfo.mapEvent(event));
}
public static EventDispatcher toUpdateOrEmitterMethod(Method method, EventMethodMapping methodInfo) {
return (target, event) -> MethodInvoking.invokingInstance(method, target).apply(methodInfo.mapEvent(event));
}
public static InitialEventDispatcher dispatchingInitialEventsByType(Class extends T> stateClass, Map factoryMethodInfo) {
return new TypeMappingInitialEventDispatcher(makeEventTypeMap(
factoryMethodInfo,
(method, interpreter) -> toFactoryMethod(stateClass, method, interpreter)));
}
public static MultiTypeEventDispatcher dispatchingEventsByType(Map updateMethodInterpreters) {
return new TypeMappingEventDispatcher<>(makeEventTypeMap(updateMethodInterpreters, EventDispatchers::toUpdateOrEmitterMethod));
}
private static Map makeEventTypeMap(Map interpreterMap, BiFunction dispatcherBuilder) {
return interpreterMap.entrySet().stream().collect(toMap(
e -> e.getValue().getEventType(),
e -> dispatcherBuilder.apply(e.getKey(), e.getValue())
));
}
private static final class TypeMappingEventDispatcher implements MultiTypeEventDispatcher {
private final Map> eventDispatchers;
private TypeMappingEventDispatcher(Map> eventDispatchers) {
this.eventDispatchers = eventDispatchers;
}
@Override
public void accept(T target, Event event) {
checkNotNull(event, "event must not be null");
final EventDispatcher dispatcher = eventDispatchers.get(event.getType());
checkState(dispatcher != null,
"No dispatcher found for event " + event);
dispatcher.accept(target, event);
}
@Override
public Set getHandledEventTypes() {
return eventDispatchers.keySet();
}
}
private static final class TypeMappingInitialEventDispatcher implements InitialEventDispatcher {
private final Map> eventDispatchers;
private TypeMappingInitialEventDispatcher(Map> eventDispatchers) {
this.eventDispatchers = eventDispatchers;
}
@Override
public T apply(Event event) {
checkNotNull(event, "event must not be null");
InitialEventDispatcher dispatcher = eventDispatchers.get(event.getType());
checkArgument(dispatcher != null,
"No dispatcher found for initial event %s", event);
return dispatcher.apply(event);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy