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