    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.lang3.function;
    019
    020import java.io.IOException;
    021import java.io.UncheckedIOException;
    022import java.lang.reflect.UndeclaredThrowableException;
    023import java.util.Collection;
    024import java.util.Objects;
    025import java.util.Optional;
    026import java.util.concurrent.Callable;
    027import java.util.function.BiConsumer;
    028import java.util.function.BiFunction;
    029import java.util.function.BiPredicate;
    030import java.util.function.Consumer;
    031import java.util.function.Function;
    032import java.util.function.Predicate;
    033import java.util.function.Supplier;
    034import java.util.stream.Stream;
    035
    036import org.apache.commons.lang3.exception.ExceptionUtils;
    037import org.apache.commons.lang3.stream.Streams;
    038import org.apache.commons.lang3.stream.Streams.FailableStream;
    039
    040/**
    041 * This class provides utility functions, and classes for working with the {@code java.util.function} package, or more
    042 * generally, with Java 8 lambdas. More specifically, it attempts to address the fact that lambdas are supposed not to
    043 * throw Exceptions, at least not checked Exceptions, like instances of {@link Exception}. This enforces the use of
    044 * constructs like:
    045 *
    046 * <pre>{@code
    047 * Consumer<java.lang.reflect.Method> consumer = m -> {
    048 *     try {
    049 *         m.invoke(o, args);
    050 *     } catch (Throwable t) {
    051 *         throw Failable.rethrow(t);
    052 *     }
    053 * };
    054 * }
    055 * </pre>
    056 *
    057 * <p>
    058 * By replacing a {@link java.util.function.Consumer Consumer&lt;O&gt;} with a {@link FailableConsumer
    059 * FailableConsumer&lt;O,? extends Throwable&gt;}, this can be written like follows:
    060 * </p>
    061 *
    062 * <pre>{@code
    063 * Functions.accept(m -> m.invoke(o, args));
    064 * }</pre>
    065 *
    066 * <p>
    067 * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than the second
    068 * version.
    069 * </p>
    070 *
    071 * @since 3.11
    072 */
    073public class Failable {
    074
    075    /**
    076     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    077     *
    078     * @param consumer the consumer to accept, may be null for a noop.
    079     * @param object1 the first object to consume by {@code consumer}
    080     * @param object2 the second object to consume by {@code consumer}
    081     * @param <T> the type of the first argument the consumer accepts
    082     * @param <U> the type of the second argument the consumer accepts
    083     * @param <E> the type of checked exception the consumer may throw
    084     */
    085    public static <T, U, E extends Throwable> void accept(final FailableBiConsumer<T, U, E> consumer, final T object1,
    086        final U object2) {
    087        run(consumer, () -> consumer.accept(object1, object2));
    088    }
    089
    090    /**
    091     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    092     *
    093     * @param consumer the consumer to accept, may be null for a noop.
    094     * @param object the object to consume by {@code consumer}
    095     * @param <T> the type the consumer accepts
    096     * @param <E> the type of checked exception the consumer may throw
    097     */
    098    public static <T, E extends Throwable> void accept(final FailableConsumer<T, E> consumer, final T object) {
    099        run(consumer, () -> consumer.accept(object));
    100    }
    101
    102    /**
    103     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    104     *
    105     * @param consumer the consumer to accept, may be null for a noop.
    106     * @param value the value to consume by {@code consumer}
    107     * @param <E> the type of checked exception the consumer may throw
    108     */
    109    public static <E extends Throwable> void accept(final FailableDoubleConsumer<E> consumer, final double value) {
    110        run(consumer, () -> consumer.accept(value));
    111    }
    112    /**
    113     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    114     *
    115     * @param consumer the consumer to accept, may be null for a noop.
    116     * @param value the value to consume by {@code consumer}
    117     * @param <E> the type of checked exception the consumer may throw
    118     */
    119    public static <E extends Throwable> void accept(final FailableIntConsumer<E> consumer, final int value) {
    120        run(consumer, () -> consumer.accept(value));
    121    }
    122
    123    /**
    124     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    125     *
    126     * @param consumer the consumer to accept, may be null for a noop.
    127     * @param value the value to consume by {@code consumer}
    128     * @param <E> the type of checked exception the consumer may throw
    129     */
    130    public static <E extends Throwable> void accept(final FailableLongConsumer<E> consumer, final long value) {
    131        run(consumer, () -> consumer.accept(value));
    132    }
    133
    134    /**
    135     * Applies a function and rethrows any exception as a {@link RuntimeException}.
    136     *
    137     * @param function the function to apply
    138     * @param input1 the first input to apply {@code function} on
    139     * @param input2 the second input to apply {@code function} on
    140     * @param <T> the type of the first argument the function accepts
    141     * @param <U> the type of the second argument the function accepts
    142     * @param <R> the return type of the function
    143     * @param <E> the type of checked exception the function may throw
    144     * @return the value returned from the function
    145     */
    146    public static <T, U, R, E extends Throwable> R apply(final FailableBiFunction<T, U, R, E> function, final T input1,
    147        final U input2) {
    148        return get(() -> function.apply(input1, input2));
    149    }
    150
    151    /**
    152     * Applies a function and rethrows any exception as a {@link RuntimeException}.
    153     *
    154     * @param function the function to apply
    155     * @param input the input to apply {@code function} on
    156     * @param <T> the type of the argument the function accepts
    157     * @param <R> the return type of the function
    158     * @param <E> the type of checked exception the function may throw
    159     * @return the value returned from the function
    160     */
    161    public static <T, R, E extends Throwable> R apply(final FailableFunction<T, R, E> function, final T input) {
    162        return get(() -> function.apply(input));
    163    }
    164
    165    /**
    166     * Applies a function and rethrows any exception as a {@link RuntimeException}.
    167     *
    168     * @param function the function to apply
    169     * @param left the first input to apply {@code function} on
    170     * @param right the second input to apply {@code function} on
    171     * @param <E> the type of checked exception the function may throw
    172     * @return the value returned from the function
    173     */
    174    public static <E extends Throwable> double applyAsDouble(final FailableDoubleBinaryOperator<E> function,
    175        final double left, final double right) {
    176        return getAsDouble(() -> function.applyAsDouble(left, right));
    177    }
    178
    179    /**
    180     * Applies a value to a function if the value isn't {@code null}, otherwise the method returns {@code null}. If the value isn't {@code null} then return the
    181     * result of the applying function.
    182     *
    183     * <pre>{@code
    184     * Failable.applyNonNull("a", String::toUpperCase)  = "A"
    185     * Failable.applyNonNull(null, String::toUpperCase) = null
    186     * Failable.applyNonNull("a", s -> null)            = null
    187     * }</pre>
    188     * <p>
    189     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
    190     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
    191     * </p>
    192     *
    193     * @param <T>    The type of the input of this method and the function.
    194     * @param <R>    The type of the result of the function and this method.
    195     * @param <E>    The type of thrown exception or error.
    196     * @param value  The value to apply the function to, may be {@code null}.
    197     * @param mapper The function to apply, must not be {@code null}.
    198     * @return The result of the function (which may be {@code null}) or {@code null} if the input value is {@code null}.
    199     * @throws E Thrown by the given function.
    200     * @see #applyNonNull(Object, FailableFunction, FailableFunction)
    201     * @see #applyNonNull(Object, FailableFunction, FailableFunction, FailableFunction)
    202     * @since 3.19.0
    203     */
    204    public static <T, R, E extends Throwable> R applyNonNull(final T value, final FailableFunction<? super T, ? extends R, E> mapper) throws E {
    205        return value != null ? Objects.requireNonNull(mapper, "mapper").apply(value) : null;
    206    }
    207
    208    /**
    209     * Applies values to a chain of functions, where a {@code null} can short-circuit each step. A function is only applied if the previous value is not
    210     * {@code null}, otherwise this method returns {@code null}.
    211     *
    212     * <pre>{@code
    213     * Failable.applyNonNull(" a ", String::toUpperCase, String::trim) = "A"
    214     * Failable.applyNonNull(null, String::toUpperCase, String::trim)  = null
    215     * Failable.applyNonNull(" a ", s -> null, String::trim)           = null
    216     * Failable.applyNonNull(" a ", String::toUpperCase, s -> null)    = null
    217     * }</pre>
    218     * <p>
    219     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
    220     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
    221     * </p>
    222     *
    223     * @param <T>     The type of the input of this method and the first function.
    224     * @param <U>     The type of the result of the first function and the input to the second function.
    225     * @param <R>     The type of the result of the second function and this method.
    226     * @param <E1>    The type of thrown exception or error by the first function.
    227     * @param <E2>    The type of thrown exception or error by the second function.
    228     * @param value1  The value to apply the functions to, may be {@code null}.
    229     * @param mapper1 The first function to apply, must not be {@code null}.
    230     * @param mapper2 The second function to apply, must not be {@code null}.
    231     * @return The result of the final function (which may be {@code null}) or {@code null} if the input value or any intermediate value is {@code null}.
    232     * @throws E1 Thrown by the first function.
    233     * @throws E2 Thrown by the second function.
    234     * @see #applyNonNull(Object, FailableFunction)
    235     * @see #applyNonNull(Object, FailableFunction, FailableFunction, FailableFunction)
    236     * @since 3.19.0
    237     */
    238    public static <T, U, R, E1 extends Throwable, E2 extends Throwable> R applyNonNull(final T value1,
    239            final FailableFunction<? super T, ? extends U, E1> mapper1, final FailableFunction<? super U, ? extends R, E2> mapper2) throws E1, E2 {
    240        return applyNonNull(applyNonNull(value1, mapper1), mapper2);
    241    }
    242
    243    /**
    244     * Applies values to a chain of functions, where a {@code null} can short-circuit each step. A function is only applied if the previous value is not
    245     * {@code null}, otherwise this method returns {@code null}.
    246     *
    247     * <pre>{@code
    248     * Failable.applyNonNull(" abc ", String::toUpperCase, String::trim, StringUtils::reverse) = "CBA"
    249     * Failable.applyNonNull(null, String::toUpperCase, String::trim, StringUtils::reverse)    = null
    250     * Failable.applyNonNull(" abc ", s -> null, String::trim, StringUtils::reverse)           = null
    251     * Failable.applyNonNull(" abc ", String::toUpperCase, s -> null, StringUtils::reverse)    = null
    252     * Failable.applyNonNull(" abc ", String::toUpperCase, String::trim, s -> null)            = null
    253     * }</pre>
    254     * <p>
    255     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
    256     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
    257     * </p>
    258     *
    259     * @param <T>     The type of the input of this method and the first function.
    260     * @param <U>     The type of the result of the first function and the input to the second function.
    261     * @param <V>     The type of the result of the second function and the input to the third function.
    262     * @param <R>     The type of the result of the third function and this method.
    263     * @param <E1>    The type of thrown exception or error by the first function.
    264     * @param <E2>    The type of thrown exception or error by the second function.
    265     * @param <E3>    The type of thrown exception or error by the second function.
    266     * @param value1  The value to apply the first function, may be {@code null}.
    267     * @param mapper1 The first function to apply, must not be {@code null}.
    268     * @param mapper2 The second function to apply, must not be {@code null}.
    269     * @param mapper3 The third function to apply, must not be {@code null}.
    270     * @return The result of the final function (which may be {@code null}) or {@code null} if the input value or any intermediate value is {@code null}.
    271     * @throws E1 Thrown by the first function.
    272     * @throws E2 Thrown by the second function.
    273     * @throws E3 Thrown by the third function.
    274     * @see #applyNonNull(Object, FailableFunction)
    275     * @see #applyNonNull(Object, FailableFunction, FailableFunction)
    276     * @since 3.19.0
    277     */
    278    public static <T, U, V, R, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable> R applyNonNull(final T value1,
    279            final FailableFunction<? super T, ? extends U, E1> mapper1, final FailableFunction<? super U, ? extends V, E2> mapper2,
    280            final FailableFunction<? super V, ? extends R, E3> mapper3) throws E1, E2, E3 {
    281        return applyNonNull(applyNonNull(applyNonNull(value1, mapper1), mapper2), mapper3);
    282    }
    283
    284    /**
    285     * Converts the given {@link FailableBiConsumer} into a standard {@link BiConsumer}.
    286     *
    287     * @param <T> the type of the first argument of the consumers
    288     * @param <U> the type of the second argument of the consumers
    289     * @param consumer a failable {@link BiConsumer}
    290     * @return a standard {@link BiConsumer}
    291     */
    292    public static <T, U> BiConsumer<T, U> asBiConsumer(final FailableBiConsumer<T, U, ?> consumer) {
    293        return (input1, input2) -> accept(consumer, input1, input2);
    294    }
    295
    296    /**
    297     * Converts the given {@link FailableBiFunction} into a standard {@link BiFunction}.
    298     *
    299     * @param <T> the type of the first argument of the input of the functions
    300     * @param <U> the type of the second argument of the input of the functions
    301     * @param <R> the type of the output of the functions
    302     * @param function a {@link FailableBiFunction}
    303     * @return a standard {@link BiFunction}
    304     */
    305    public static <T, U, R> BiFunction<T, U, R> asBiFunction(final FailableBiFunction<T, U, R, ?> function) {
    306        return (input1, input2) -> apply(function, input1, input2);
    307    }
    308
    309    /**
    310     * Converts the given {@link FailableBiPredicate} into a standard {@link BiPredicate}.
    311     *
    312     * @param <T> the type of the first argument used by the predicates
    313     * @param <U> the type of the second argument used by the predicates
    314     * @param predicate a {@link FailableBiPredicate}
    315     * @return a standard {@link BiPredicate}
    316     */
    317    public static <T, U> BiPredicate<T, U> asBiPredicate(final FailableBiPredicate<T, U, ?> predicate) {
    318        return (input1, input2) -> test(predicate, input1, input2);
    319    }
    320
    321    /**
    322     * Converts the given {@link FailableCallable} into a standard {@link Callable}.
    323     *
    324     * @param <V> the type used by the callables
    325     * @param callable a {@link FailableCallable}
    326     * @return a standard {@link Callable}
    327     */
    328    public static <V> Callable<V> asCallable(final FailableCallable<V, ?> callable) {
    329        return () -> call(callable);
    330    }
    331
    332    /**
    333     * Converts the given {@link FailableConsumer} into a standard {@link Consumer}.
    334     *
    335     * @param <T> the type used by the consumers
    336     * @param consumer a {@link FailableConsumer}
    337     * @return a standard {@link Consumer}
    338     */
    339    public static <T> Consumer<T> asConsumer(final FailableConsumer<T, ?> consumer) {
    340        return input -> accept(consumer, input);
    341    }
    342
    343    /**
    344     * Converts the given {@link FailableFunction} into a standard {@link Function}.
    345     *
    346     * @param <T> the type of the input of the functions
    347     * @param <R> the type of the output of the functions
    348     * @param function a {code FailableFunction}
    349     * @return a standard {@link Function}
    350     */
    351    public static <T, R> Function<T, R> asFunction(final FailableFunction<T, R, ?> function) {
    352        return input -> apply(function, input);
    353    }
    354
    355    /**
    356     * Converts the given {@link FailablePredicate} into a standard {@link Predicate}.
    357     *
    358     * @param <T> the type used by the predicates
    359     * @param predicate a {@link FailablePredicate}
    360     * @return a standard {@link Predicate}
    361     */
    362    public static <T> Predicate<T> asPredicate(final FailablePredicate<T, ?> predicate) {
    363        return input -> test(predicate, input);
    364    }
    365
    366    /**
    367     * Converts the given {@link FailableRunnable} into a standard {@link Runnable}.
    368     *
    369     * @param runnable a {@link FailableRunnable}
    370     * @return a standard {@link Runnable}
    371     */
    372    public static Runnable asRunnable(final FailableRunnable<?> runnable) {
    373        return () -> run(runnable);
    374    }
    375
    376    /**
    377     * Converts the given {@link FailableSupplier} into a standard {@link Supplier}.
    378     *
    379     * @param <T> the type supplied by the suppliers
    380     * @param supplier a {@link FailableSupplier}
    381     * @return a standard {@link Supplier}
    382     */
    383    public static <T> Supplier<T> asSupplier(final FailableSupplier<T, ?> supplier) {
    384        return () -> get(supplier);
    385    }
    386
    387    /**
    388     * Calls a callable and rethrows any exception as a {@link RuntimeException}.
    389     *
    390     * @param callable the callable to call
    391     * @param <V> the return type of the callable
    392     * @param <E> the type of checked exception the callable may throw
    393     * @return the value returned from the callable
    394     */
    395    public static <V, E extends Throwable> V call(final FailableCallable<V, E> callable) {
    396        return get(callable::call);
    397    }
    398
    399    /**
    400     * Invokes a supplier, and returns the result.
    401     *
    402     * @param supplier The supplier to invoke.
    403     * @param <T> The suppliers output type.
    404     * @param <E> The type of checked exception, which the supplier can throw.
    405     * @return The object, which has been created by the supplier
    406     */
    407    public static <T, E extends Throwable> T get(final FailableSupplier<T, E> supplier) {
    408        try {
    409            return supplier.get();
    410        } catch (final Throwable t) {
    411            throw rethrow(t);
    412        }
    413    }
    414
    415    /**
    416     * Invokes a boolean supplier, and returns the result.
    417     *
    418     * @param supplier The boolean supplier to invoke.
    419     * @param <E> The type of checked exception, which the supplier can throw.
    420     * @return The boolean, which has been created by the supplier
    421     */
    422    public static <E extends Throwable> boolean getAsBoolean(final FailableBooleanSupplier<E> supplier) {
    423        try {
    424            return supplier.getAsBoolean();
    425        } catch (final Throwable t) {
    426            throw rethrow(t);
    427        }
    428    }
    429
    430    /**
    431     * Invokes a double supplier, and returns the result.
    432     *
    433     * @param supplier The double supplier to invoke.
    434     * @param <E> The type of checked exception, which the supplier can throw.
    435     * @return The double, which has been created by the supplier
    436     */
    437    public static <E extends Throwable> double getAsDouble(final FailableDoubleSupplier<E> supplier) {
    438        try {
    439            return supplier.getAsDouble();
    440        } catch (final Throwable t) {
    441            throw rethrow(t);
    442        }
    443    }
    444
    445    /**
    446     * Invokes an int supplier, and returns the result.
    447     *
    448     * @param supplier The int supplier to invoke.
    449     * @param <E> The type of checked exception, which the supplier can throw.
    450     * @return The int, which has been created by the supplier
    451     */
    452    public static <E extends Throwable> int getAsInt(final FailableIntSupplier<E> supplier) {
    453        try {
    454            return supplier.getAsInt();
    455        } catch (final Throwable t) {
    456            throw rethrow(t);
    457        }
    458    }
    459
    460    /**
    461     * Invokes a long supplier, and returns the result.
    462     *
    463     * @param supplier The long supplier to invoke.
    464     * @param <E> The type of checked exception, which the supplier can throw.
    465     * @return The long, which has been created by the supplier
    466     */
    467    public static <E extends Throwable> long getAsLong(final FailableLongSupplier<E> supplier) {
    468        try {
    469            return supplier.getAsLong();
    470        } catch (final Throwable t) {
    471            throw rethrow(t);
    472        }
    473    }
    474
    475    /**
    476     * Invokes a short supplier, and returns the result.
    477     *
    478     * @param supplier The short supplier to invoke.
    479     * @param <E> The type of checked exception, which the supplier can throw.
    480     * @return The short, which has been created by the supplier
    481     */
    482    public static <E extends Throwable> short getAsShort(final FailableShortSupplier<E> supplier) {
    483        try {
    484            return supplier.getAsShort();
    485        } catch (final Throwable t) {
    486            throw rethrow(t);
    487        }
    488    }
    489
    490    /**
    491     * Rethrows a {@link Throwable} as an unchecked exception. If the argument is already unchecked, namely a
    492     * {@link RuntimeException} or {@link Error} then the argument will be rethrown without modification. If the
    493     * exception is {@link IOException} then it will be wrapped into a {@link UncheckedIOException}. In every other
    494     * cases the exception will be wrapped into a {@code
    495     * UndeclaredThrowableException}
    496     *
    497     * <p>
    498     * Note that there is a declared return type for this method, even though it never returns. The reason for that is
    499     * to support the usual pattern:
    500     * </p>
    501     *
    502     * <pre>
    503     * throw rethrow(myUncheckedException);
    504     * </pre>
    505     *
    506     * <p>
    507     * instead of just calling the method. This pattern may help the Java compiler to recognize that at that point an
    508     * exception will be thrown and the code flow analysis will not demand otherwise mandatory commands that could
    509     * follow the method call, like a {@code return} statement from a value returning method.
    510     * </p>
    511     *
    512     * @param throwable The throwable to rethrow possibly wrapped into an unchecked exception
    513     * @return Never returns anything, this method never terminates normally.
    514     */
    515    public static RuntimeException rethrow(final Throwable throwable) {
    516        Objects.requireNonNull(throwable, "throwable");
    517        ExceptionUtils.throwUnchecked(throwable);
    518        if (throwable instanceof IOException) {
    519            throw new UncheckedIOException((IOException) throwable);
    520        }
    521        throw new UndeclaredThrowableException(throwable);
    522    }
    523
    524    /**
    525     * Runs a runnable and rethrows any exception as a {@link RuntimeException}.
    526     *
    527     * @param runnable The runnable to run, may be null for a noop.
    528     * @param <E> the type of checked exception the runnable may throw.
    529     */
    530    public static <E extends Throwable> void run(final FailableRunnable<E> runnable) {
    531        if (runnable != null) {
    532            try {
    533                runnable.run();
    534            } catch (final Throwable t) {
    535                throw rethrow(t);
    536            }
    537        }
    538    }
    539
    540    private static <E extends Throwable> void run(final Object test, final FailableRunnable<E> runnable) {
    541        if (runnable != null && test != null) {
    542            try {
    543                runnable.run();
    544            } catch (final Throwable t) {
    545                throw rethrow(t);
    546            }
    547        }
    548    }
    549
    550    /**
    551     * Converts the given collection into a {@link FailableStream}. The {@link FailableStream} consists of the
    552     * collections elements. Shortcut for
    553     *
    554     * <pre>
    555     * Functions.stream(collection.stream());
    556     * </pre>
    557     *
    558     * @param collection The collection, which is being converted into a {@link FailableStream}.
    559     * @param <E> The collections element type. (In turn, the result streams element type.)
    560     * @return The created {@link FailableStream}.
    561     */
    562    public static <E> FailableStream<E> stream(final Collection<E> collection) {
    563        return new FailableStream<>(collection.stream());
    564    }
    565
    566    /**
    567     * Converts the given stream into a {@link FailableStream}. The {@link FailableStream} consists of the same
    568     * elements, than the input stream. However, failable lambdas, like {@link FailablePredicate},
    569     * {@link FailableFunction}, and {@link FailableConsumer} may be applied, rather than {@link Predicate},
    570     * {@link Function}, {@link Consumer}, etc.
    571     *
    572     * @param stream The stream, which is being converted into a {@link FailableStream}.
    573     * @param <T> The streams element type.
    574     * @return The created {@link FailableStream}.
    575     */
    576    public static <T> FailableStream<T> stream(final Stream<T> stream) {
    577        return new FailableStream<>(stream);
    578    }
    579
    580    /**
    581     * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
    582     *
    583     * @param predicate the predicate to test
    584     * @param object1 the first input to test by {@code predicate}
    585     * @param object2 the second input to test by {@code predicate}
    586     * @param <T> the type of the first argument the predicate tests
    587     * @param <U> the type of the second argument the predicate tests
    588     * @param <E> the type of checked exception the predicate may throw
    589     * @return the boolean value returned by the predicate
    590     */
    591    public static <T, U, E extends Throwable> boolean test(final FailableBiPredicate<T, U, E> predicate,
    592        final T object1, final U object2) {
    593        return getAsBoolean(() -> predicate.test(object1, object2));
    594    }
    595
    596    /**
    597     * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
    598     *
    599     * @param predicate the predicate to test
    600     * @param object the input to test by {@code predicate}
    601     * @param <T> the type of argument the predicate tests
    602     * @param <E> the type of checked exception the predicate may throw
    603     * @return the boolean value returned by the predicate
    604     */
    605    public static <T, E extends Throwable> boolean test(final FailablePredicate<T, E> predicate, final T object) {
    606        return getAsBoolean(() -> predicate.test(object));
    607    }
    608
    609    /**
    610     * A simple try-with-resources implementation, that can be used, if your objects do not implement the
    611     * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
    612     * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
    613     * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
    614     * {@link Throwable}) is rethrown. Example use:
    615     *
    616     * <pre>{@code
    617     * final FileInputStream fis = new FileInputStream("my.file");
    618     * Functions.tryWithResources(useInputStream(fis), null, () -> fis.close());
    619     * }</pre>
    620     *
    621     * @param action The action to execute. This object <em>will</em> always be invoked.
    622     * @param errorHandler An optional error handler, which will be invoked finally, if any error occurred. The error
    623     *        handler will receive the first error, AKA {@link Throwable}.
    624     * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
    625     *        order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
    626     * @see #tryWithResources(FailableRunnable, FailableRunnable...)
    627     */
    628    @SafeVarargs
    629    public static void tryWithResources(final FailableRunnable<? extends Throwable> action,
    630        final FailableConsumer<Throwable, ? extends Throwable> errorHandler,
    631        final FailableRunnable<? extends Throwable>... resources) {
    632        final FailableConsumer<Throwable, ? extends Throwable> actualErrorHandler;
    633        if (errorHandler == null) {
    634            actualErrorHandler = Failable::rethrow;
    635        } else {
    636            actualErrorHandler = errorHandler;
    637        }
    638        Streams.of(resources).forEach(r -> Objects.requireNonNull(r, "runnable"));
    639        Throwable th = null;
    640        try {
    641            action.run();
    642        } catch (final Throwable t) {
    643            th = t;
    644        }
    645        if (resources != null) {
    646            for (final FailableRunnable<?> runnable : resources) {
    647                try {
    648                    runnable.run();
    649                } catch (final Throwable t) {
    650                    if (th == null) {
    651                        th = t;
    652                    }
    653                }
    654            }
    655        }
    656        if (th != null) {
    657            try {
    658                actualErrorHandler.accept(th);
    659            } catch (final Throwable t) {
    660                throw rethrow(t);
    661            }
    662        }
    663    }
    664
    665    /**
    666     * A simple try-with-resources implementation, that can be used, if your objects do not implement the
    667     * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
    668     * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
    669     * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
    670     * {@link Throwable}) is rethrown. Example use:
    671     *
    672     * <pre>{@code
    673     * final FileInputStream fis = new FileInputStream("my.file");
    674     * Functions.tryWithResources(useInputStream(fis), () -> fis.close());
    675     * }</pre>
    676     *
    677     * @param action The action to execute. This object <em>will</em> always be invoked.
    678     * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
    679     *        order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
    680     * @see #tryWithResources(FailableRunnable, FailableConsumer, FailableRunnable...)
    681     */
    682    @SafeVarargs
    683    public static void tryWithResources(final FailableRunnable<? extends Throwable> action, final FailableRunnable<? extends Throwable>... resources) {
    684        tryWithResources(action, null, resources);
    685    }
    686
    687    private Failable() {
    688        // empty
    689    }
    690
    691}