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

com.opencredo.concursus.mapping.commands.methods.reflection.CommandInterfaceInfo Maven / Gradle / Ivy

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

import com.opencredo.concursus.domain.commands.CommandType;
import com.opencredo.concursus.domain.commands.CommandTypeInfo;
import com.opencredo.concursus.domain.commands.CommandTypeMatcher;
import com.opencredo.concursus.mapping.annotations.HandlesCommandsFor;
import com.opencredo.concursus.mapping.reflection.MethodSelectors;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

public final class CommandInterfaceInfo {

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

    public static CommandInterfaceInfo forInterface(Class iface) {
        return cache.computeIfAbsent(iface, CommandInterfaceInfo::forInterfaceUncached);
    }

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

        String aggregateType = iface.getAnnotation(HandlesCommandsFor.class).value();
        Map commandMappers = getCommandMappers(iface, aggregateType);
        Map typeInfoMap = commandMappers.values().stream().collect(Collectors.toMap(
                CommandMethodMapping::getCommandType,
                CommandMethodMapping::getCommandTypeInfo
        ));
        MultiTypeCommandDispatcher commandDispatcher = CommandDispatchers.dispatchingCommandsByType(commandMappers);

        return new CommandInterfaceInfo(typeInfoMap, commandMappers, CommandTypeMatcher.matchingAgainst(typeInfoMap), commandDispatcher);
    }

    private static Map getCommandMappers(Class iface, String aggregateType) {
            return Stream.of(iface.getMethods())
                    .filter(MethodSelectors.isCommandIssuingMethod)
                    .distinct()
                    .collect(Collectors.toMap(
                            Function.identity(),
                            method -> CommandMethodMapping.forMethod(method, aggregateType)
                    ));
    }

    private final Map typeInfoMap;
    private final Map commandMappers;
    private final CommandTypeMatcher commandTypeMatcher;
    private final MultiTypeCommandDispatcher commandDispatcher;

    private CommandInterfaceInfo(Map typeInfoMap, Map commandMappers, CommandTypeMatcher commandTypeMatcher, MultiTypeCommandDispatcher commandDispatcher) {
        this.typeInfoMap = typeInfoMap;
        this.commandMappers = commandMappers;
        this.commandTypeMatcher = commandTypeMatcher;
        this.commandDispatcher = commandDispatcher;
    }

    public static ConcurrentMap, CommandInterfaceInfo> getCache() {
        return cache;
    }

    public Map getTypeInfoMap() {
        return typeInfoMap;
    }

    public CommandTypeMatcher getCommandTypeMatcher() {
        return commandTypeMatcher;
    }

    public MultiTypeCommandDispatcher getCommandDispatcher() {
        return commandDispatcher;
    }

    public Map getCommandMappers() {
        return commandMappers;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy