/*
 * Copyright 2018, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.server.bus;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.spine.core.MessageEnvelope;
import io.spine.type.MessageClass;

import java.util.Set;

/**
 * A dispatcher of a message.
 *
 * @param <C> the type of class of the dispatched messages
 * @param <E> the type of the message envelopes
 * @param <R> the type of the result of the {@linkplain #dispatch(MessageEnvelope) dispatching
 *            function}. For {@linkplain UnicastDispatcher unicast dispatching} is the type of
 *            the IDs of entity that receives a dispatched message.
 *            For {@linkplain MulticastDispatcher multicast dispatching} is the type of the set
 *            of entity IDs.
 * @author Alex Tymchenko
 * @author Alexander Yevsyukov
 */
public interface MessageDispatcher<C extends MessageClass, E extends MessageEnvelope, R> {

    /**
     * Obtains a set of message classes that can be processed by this dispatcher.
     *
     * @return non-empty set of message classes
     */
    Set<C> getMessageClasses();

    /**
     * Dispatches the message contained in the passed envelope.
     *
     * @param envelope the envelope with the message
     * @return ID(s) of entities to which the message was dispatched
     */
    @CanIgnoreReturnValue
    R dispatch(E envelope);

    /**
     * Handles an error occurred during dispatching a message.
     *
     * @param envelope  the message which caused the error
     * @param exception the error
     */
    void onError(E envelope, RuntimeException exception);

    default boolean canDispatch(E envelope) {
        return true;
    }
}

@@ -2560,24 +2560,632 @@
 xception);%0A%0A
+    /**%0A     * Checks if this dispatcher can dispatch the given message.%0A     *%0A     * %3Cp%3EThis method does not check that the type of the message is one of%0A     * the %7B@linkplain #getMessageClasses() dispatched message classes%7D. Instead, it validates%0A     * the message upon some custom rules of this dispatcher.%0A     *%0A     * %3Cp%3EExtend this method to forbid messages from being dispatched to this instance.%0A     *%0A     * @param envelope%0A     *         the message to check%0A     * @return %7B@code true%7D is the given message can be dispatched by this dispatcher,%0A     *         %7B@code false%7D otherwise%0A     */%0A
     default 

Document `MessageDispatcher.canDispatch`.