package com.github.jeysal.java.util.function;

import lombok.experimental.UtilityClass;

import java.util.Arrays;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author Tim Seckinger
 * @since 12.03.2016
 */
@UtilityClass
public class SupplierUtils {

    /**
     * Returns a {@link Supplier} that supplies the first present {@link Optional} supplied by given suppliers in order,
     * or an empty {@link Optional} if none of the suppliers return a present {@link Optional}.
     *
     * @param suppliers The suppliers to call in order
     * @param <T>       The type of the {@link Optional}
     * @return The {@link Supplier} that supplies the first present {@link Optional}
     */
    @SafeVarargs
    public static <T> Supplier<Optional<T>> firstPresent(Supplier<Optional<T>>... suppliers) {
        return () -> Arrays.stream(suppliers)
                .map(Supplier::get)
                .filter(Optional::isPresent)
                .findFirst().orElse(Optional.empty());
    }

    /**
     * Returns a {@link Supplier} that supplies the content of the first present {@link Optional} supplied by given
     * suppliers in order, or the object supplied by given fallback supplier if none of the suppliers return a present
     * {@link Optional}.
     *
     * @param fallback  The fallback supplier
     * @param suppliers The suppliers to call in order
     * @param <T>       The type of the {@link Optional} content or fallback object
     * @return The {@link Supplier} that supplies the first present {@link Optional}
     */
    @SafeVarargs
    public static <T> Supplier<T> firstPresent(Supplier<T> fallback, Supplier<Optional<T>>... suppliers) {
        return () -> Arrays.stream(suppliers)
                .map(Supplier::get)
                .filter(Optional::isPresent)
                .findFirst().orElseGet(() ->
                        Optional.of(fallback.get())
                ).get();
    }

}

@@ -1940,10 +1940,793 @@
 %0A    %7D%0A%0A
+    /**%0A     * Returns a %7B@link Supplier%7D that delegates calls to given throwingSupplier and returns an %7B@link Optional%7D of the%0A     * result or an empty %7B@link Optional%7D if given throwingSupplier returned null or threw an %7B@link Exception%7D.%0A     *%0A     * @param throwingSupplier The %7B@link Supplier%7D to delegate to%0A     * @param %3CR%3E              The return type of the %7B@link Supplier%7D%0A     * @return The %7B@link Supplier%7D that delegates calls to throwingSupplier%0A     */%0A    public static %3CR%3E Supplier%3COptional%3CR%3E%3E trying(ThrowingSupplier%3CR, ?%3E throwingSupplier) %7B%0A        return () -%3E %7B%0A            try %7B%0A                return Optional.ofNullable(throwingSupplier.get());%0A            %7D catch (Exception e) %7B%0A                return Optional.empty();%0A            %7D%0A        %7D;%0A    %7D%0A
 %7D%0A

add SupplierUtils.trying