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

com.opencredo.concursus.mapping.events.methods.reflection.StateClassInfo Maven / Gradle / Ivy

The newest version!
package com.opencredo.concursus.mapping.events.methods.reflection;

import com.opencredo.concursus.data.tuples.TupleSchema;
import com.opencredo.concursus.domain.events.Event;
import com.opencredo.concursus.domain.events.EventType;
import com.opencredo.concursus.domain.events.binding.EventTypeBinding;
import com.opencredo.concursus.domain.events.matching.EventTypeMatcher;
import com.opencredo.concursus.mapping.annotations.HandlesEventsFor;
import com.opencredo.concursus.mapping.events.methods.reflection.dispatching.EventDispatcher;
import com.opencredo.concursus.mapping.events.methods.reflection.dispatching.EventDispatchers;
import com.opencredo.concursus.mapping.events.methods.reflection.dispatching.InitialEventDispatcher;
import com.opencredo.concursus.mapping.events.methods.reflection.interpreting.EventMethodMapping;
import com.opencredo.concursus.mapping.events.methods.reflection.interpreting.EventMethodType;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Stream.concat;

public final class StateClassInfo {

    private static final ConcurrentMap, StateClassInfo> cache = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public static  StateClassInfo forStateClass(Class stateClass) {
        return (StateClassInfo) cache.computeIfAbsent(stateClass, StateClassInfo::forStateClassUncached);
    }

    private static  StateClassInfo forStateClassUncached(Class stateClass) {
        checkNotNull(stateClass, "stateClass must not be null");
        checkArgument(stateClass.isAnnotationPresent(HandlesEventsFor.class),
                "stateClass %s is not annotated with @HandlesEventsFor", stateClass);

        String aggregateType = stateClass.getAnnotation(HandlesEventsFor.class).value();

        Map factoryMethodMappings = EventMethodType.FACTORY.getEventMethodInfo(aggregateType, stateClass);
        Map updateMethodMappings = EventMethodType.UPDATER.getEventMethodInfo(aggregateType, stateClass);

        Collection typeMappings = getTypeMappings(factoryMethodMappings, updateMethodMappings);
        Map eventTypeMappings = EventMethodMapping.getEventTypeMappings(typeMappings);

        return new StateClassInfo<>(
                eventTypeMappings,
                EventTypeBinding.of(aggregateType, EventTypeMatcher.matchingAgainst(eventTypeMappings)),
                EventMethodMapping.makeCausalOrdering(typeMappings),
                EventDispatchers.dispatchingInitialEventsByType(stateClass, factoryMethodMappings),
                EventDispatchers.dispatchingEventsByType(updateMethodMappings));
    }

    private static Collection getTypeMappings(Map factoryMethodMappings, Map updateMethodMappings) {
        return concat(
                    factoryMethodMappings.values().stream(),
                    updateMethodMappings.values().stream()).collect(toList());
    }

    private final Map eventTypeMappings;
    private final EventTypeBinding eventTypeBinding;
    private final Comparator causalOrder;
    private final InitialEventDispatcher initialEventDispatcher;
    private final EventDispatcher updateEventDispatcher;

    public StateClassInfo(Map eventTypeMappings, EventTypeBinding eventTypeBinding, Comparator causalOrder, InitialEventDispatcher initialEventDispatcher, EventDispatcher updateEventDispatcher) {
        this.eventTypeMappings = eventTypeMappings;
        this.eventTypeBinding = eventTypeBinding;
        this.causalOrder = causalOrder;
        this.initialEventDispatcher = initialEventDispatcher;
        this.updateEventDispatcher = updateEventDispatcher;
    }

    public Map getEventTypeMappings() {
        return eventTypeMappings;
    }

    public EventTypeBinding getEventTypeBinding() {
        return eventTypeBinding;
    }

    public Comparator getCausalOrder() {
        return causalOrder;
    }

    public InitialEventDispatcher getInitialEventDispatcher() {
        return initialEventDispatcher;
    }

    public EventDispatcher getUpdateEventDispatcher() {
        return updateEventDispatcher;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy