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

io.smallrye.mutiny.groups.MultiIfEmpty Maven / Gradle / Ivy

package io.smallrye.mutiny.groups;

import static io.smallrye.mutiny.helpers.ParameterValidation.SUPPLIER_PRODUCED_NULL;
import static io.smallrye.mutiny.helpers.ParameterValidation.doesNotContainNull;
import static io.smallrye.mutiny.helpers.ParameterValidation.nonNull;

import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.concurrent.Flow;
import java.util.function.Consumer;
import java.util.function.Supplier;

import io.smallrye.mutiny.shaded.io.smallrye.common.annotation.CheckReturnValue;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.infrastructure.Infrastructure;
import io.smallrye.mutiny.operators.multi.MultiSwitchOnEmpty;
import io.smallrye.mutiny.subscription.MultiEmitter;

public class MultiIfEmpty {

    private final Multi upstream;

    MultiIfEmpty(Multi upstream) {
        this.upstream = upstream;
    }

    /**
     * When the current {@link Multi} completes without having emitted items, the passed failure is sent downstream.
     *
     * @param failure the failure
     * @return the new {@link Multi}
     */
    @CheckReturnValue
    public Multi failWith(Throwable failure) {
        nonNull(failure, "failure");
        return failWith(() -> failure);
    }

    /**
     * When the current {@link Multi} completes without having emitted items, a failure produced by the given
     * {@link Supplier} is sent downstream.
     *
     * @param supplier the supplier to produce the failure, must not be {@code null}, must not produce {@code null}
     * @return the new {@link Multi}
     */
    @CheckReturnValue
    public Multi failWith(Supplier supplier) {
        Supplier actual = Infrastructure.decorate(nonNull(supplier, "supplier"));
        return switchToEmitter(createMultiFromFailureSupplier(actual));
    }

    static  Consumer> createMultiFromFailureSupplier(Supplier supplier) {
        // supplier already decorated.
        return emitter -> {
            Throwable throwable;
            try {
                throwable = supplier.get();
            } catch (Throwable e) {
                emitter.fail(e);
                return;
            }

            if (throwable == null) {
                emitter.fail(new NullPointerException(SUPPLIER_PRODUCED_NULL));
            } else {
                emitter.fail(throwable);
            }
        };
    }

    /**
     * Like {@link #failWith(Throwable)} but using a {@link NoSuchElementException}.
     *
     * @return the new {@link Multi}
     */
    @CheckReturnValue
    public Multi fail() {
        return failWith(NoSuchElementException::new);
    }

    /**
     * When the upstream {@link Multi} completes without having emitted items, it continues with the events fired with
     * the emitter passed to the {@code consumer} callback.
     * 

* If the upstream {@link Multi} fails, the switch does not apply. * * @param consumer the callback receiving the emitter to fire the events. Must not be {@code null}. Throwing exception * in this function propagates a failure downstream. * @return the new {@link Multi} */ @CheckReturnValue public Multi switchToEmitter(Consumer> consumer) { Consumer> actual = Infrastructure.decorate(nonNull(consumer, "consumer")); return switchTo(() -> Multi.createFrom().emitter(actual)); } /** * When the upstream {@link Multi} completes without having emitted items, it continues with the events fired by the * passed {@link Flow.Publisher} / {@link Multi}. *

* If the upstream {@link Multi} fails, the switch does not apply. * * @param other the stream to switch to when the upstream completes. * @return the new {@link Multi} */ @CheckReturnValue public Multi switchTo(Flow.Publisher other) { return switchTo(() -> other); } /** * When the upstream {@link Multi} completes without having emitted items, it continues with the events fired by a * {@link Flow.Publisher} produces with the given {@link Supplier}. * * @param supplier the supplier to use to produce the publisher, must not be {@code null}, must not return {@code null}s * @return the new {@link Uni} */ @CheckReturnValue public Multi switchTo(Supplier> supplier) { Supplier> actual = Infrastructure.decorate(nonNull(supplier, "supplier")); return Infrastructure.onMultiCreation(new MultiSwitchOnEmpty<>(upstream, actual)); } /** * When the upstream {@link Multi} completes without having emitted items, continue with the given items. * * @param items the items, must not be {@code null}, must not contain {@code null} * @return the new {@link Multi} */ @SafeVarargs @CheckReturnValue public final Multi continueWith(T... items) { nonNull(items, "items"); doesNotContainNull(items, "items"); return continueWith(() -> Arrays.asList(items)); } /** * When the upstream {@link Multi} completes without having emitted items, continue with the given items. * * @param items the items, must not be {@code null}, must not contain {@code null} * @return the new {@link Multi} */ @CheckReturnValue public Multi continueWith(Iterable items) { nonNull(items, "items"); doesNotContainNull(items, "items"); return continueWith(() -> items); } /** * When the upstream {@link Multi} completes without having emitted items, continue with the items produced by the * given {@link Supplier}. * * @param supplier the supplier to produce the items, must not be {@code null}, must not produce {@code null} * @return the new {@link Multi} */ @CheckReturnValue public Multi continueWith(Supplier> supplier) { Supplier> actual = Infrastructure.decorate(nonNull(supplier, "supplier")); return switchTo(() -> createMultiFromIterableSupplier(actual)); } static Flow.Publisher createMultiFromIterableSupplier(Supplier> supplier) { Iterable iterable; try { iterable = supplier.get(); } catch (Throwable e) { return Multi.createFrom().failure(e); } if (iterable == null) { return Multi.createFrom().failure(new NullPointerException(SUPPLIER_PRODUCED_NULL)); } else { return Multi.createFrom().iterable(iterable); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy