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

com.opencredo.concursus.mapping.events.methods.reflection.EmitterInterfaceInfo 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.EventDispatchers;
import com.opencredo.concursus.mapping.events.methods.reflection.dispatching.MultiTypeEventDispatcher;
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.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;

/**
 * The source of all reflection information about an event interface.
 * @param  The type of the event interface.
 */
public final class EmitterInterfaceInfo {

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

    /**
     * Get event interface information from the supplied interface. This method is cached.
     * @param iface The interface to get information for.
     * @param  The type of the interface.
     * @return The EventInterfaceInfo for the supplied interface.
     */
    @SuppressWarnings("unchecked")
    public static  EmitterInterfaceInfo forInterface(Class iface) {
        return (EmitterInterfaceInfo) cache.computeIfAbsent(iface, EmitterInterfaceInfo::forInterfaceUncached);
    }

    private static  EmitterInterfaceInfo forInterfaceUncached(Class iface) {
        checkNotNull(iface, "iface must not be null");
        checkArgument(iface.isInterface(), "iface must be interface");
        checkArgument(iface.isAnnotationPresent(HandlesEventsFor.class),
                "Interface %s is not annotated with @HandlesEventsFor", iface);

        String aggregateType = iface.getAnnotation(HandlesEventsFor.class).value();
        Map eventMappers = EventMethodType.EMITTER.getEventMethodInfo(aggregateType, iface);

        Map eventTypeMatcherMap = EventMethodMapping.getEventTypeMappings(eventMappers.values());

        return new EmitterInterfaceInfo<>(
                eventTypeMatcherMap,
                EventTypeBinding.of(aggregateType, EventTypeMatcher.matchingAgainst(eventTypeMatcherMap)),
                EventMethodMapper.mappingWith(eventMappers),
                EventDispatchers.dispatchingEventsByType(eventMappers),
                EventMethodMapping.makeCausalOrdering(eventMappers.values()));
    }

    private final Map eventTypeMatcherMap;
    private final EventTypeBinding eventTypeBinding;
    private final EventMethodMapper eventMethodMapper;
    private final MultiTypeEventDispatcher eventDispatcher;
    private final Comparator causalOrderComparator;

    private EmitterInterfaceInfo(Map eventTypeMatcherMap, EventTypeBinding eventTypeBinding, EventMethodMapper eventMethodMapper, MultiTypeEventDispatcher eventDispatcher, Comparator causalOrderComparator) {
        this.eventTypeMatcherMap = eventTypeMatcherMap;
        this.eventTypeBinding = eventTypeBinding;
        this.eventMethodMapper = eventMethodMapper;
        this.eventDispatcher = eventDispatcher;
        this.causalOrderComparator = causalOrderComparator;
    }

    /**
     * Get a {@link Map} of {@link EventType}s to {@link TupleSchema}s that can be used to build an {@link EventTypeMatcher}
     * @return
     */
    public Map getEventTypeMatcherMap() {
        return eventTypeMatcherMap;
    }

    /**
     * Get a {@link Comparator} that can be used to sort events in causal order, based on annotations on the interface.
     * @return The comparator.
     */
    public Comparator getCausalOrderComparator() {
        return causalOrderComparator;
    }

    /**
     * Get {@link EventTypeBinding} for the interface.
     * @return
     */
    public EventTypeBinding getEventTypeBinding() {
        return eventTypeBinding;
    }

    /**
     * Get an {@link EventMethodMapper} for the interface.
     * @return
     */
    public EventMethodMapper getEventMethodMapper() {
        return eventMethodMapper;
    }

    /**
     * Get a {@link MultiTypeEventDispatcher} for the interface.
     * @return
     */
    public MultiTypeEventDispatcher getEventDispatcher() {
        return eventDispatcher;
    }

    /**
     * Get an {@link EventTypeMatcher} for the interface.
     * @return
     */
    public EventTypeMatcher getEventTypeMatcher() {
        return EventTypeMatcher.matchingAgainst(eventTypeMatcherMap);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy