All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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 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