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    /**
114     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
115     *
116     * @param consumer the consumer to accept, may be null for a noop.
117     * @param value the value to consume by {@code consumer}
118     * @param <E> the type of checked exception the consumer may throw
119     */
120    public static <E extends Throwable> void accept(final FailableIntConsumer<E> consumer, final int value) {
121        run(consumer, () -> consumer.accept(value));
122    }
123
124    /**
125     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
126     *
127     * @param consumer the consumer to accept, may be null for a noop.
128     * @param value the value to consume by {@code consumer}
129     * @param <E> the type of checked exception the consumer may throw
130     */
131    public static <E extends Throwable> void accept(final FailableLongConsumer<E> consumer, final long value) {
132        run(consumer, () -> consumer.accept(value));
133    }
134
135    /**
136     * Applies a function and rethrows any exception as a {@link RuntimeException}.
137     *
138     * @param function the function to apply
139     * @param input1 the first input to apply {@code function} on
140     * @param input2 the second input to apply {@code function} on
141     * @param <T> the type of the first argument the function accepts
142     * @param <U> the type of the second argument the function accepts
143     * @param <R> the return type of the function
144     * @param <E> the type of checked exception the function may throw
145     * @return the value returned from the function
146     */
147    public static <T, U, R, E extends Throwable> R apply(final FailableBiFunction<T, U, R, E> function, final T input1,
148        final U input2) {
149        return get(() -> function.apply(input1, input2));
150    }
151
152    /**
153     * Applies a function and rethrows any exception as a {@link RuntimeException}.
154     *
155     * @param function the function to apply
156     * @param input the input to apply {@code function} on
157     * @param <T> the type of the argument the function accepts
158     * @param <R> the return type of the function
159     * @param <E> the type of checked exception the function may throw
160     * @return the value returned from the function
161     */
162    public static <T, R, E extends Throwable> R apply(final FailableFunction<T, R, E> function, final T input) {
163        return get(() -> function.apply(input));
164    }
165
166    /**
167     * Applies a function and rethrows any exception as a {@link RuntimeException}.
168     *
169     * @param function the function to apply
170     * @param left the first input to apply {@code function} on
171     * @param right the second input to apply {@code function} on
172     * @param <E> the type of checked exception the function may throw
173     * @return the value returned from the function
174     */
175    public static <E extends Throwable> double applyAsDouble(final FailableDoubleBinaryOperator<E> function,
176        final double left, final double right) {
177        return getAsDouble(() -> function.applyAsDouble(left, right));
178    }
179
180    /**
181     * 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
182     * result of the applying function.
183     *
184     * <pre>{@code
185     * Failable.applyNonNull("a", String::toUpperCase)  = "A"
186     * Failable.applyNonNull(null, String::toUpperCase) = null
187     * Failable.applyNonNull("a", s -> null)            = null
188     * }</pre>
189     * <p>
190     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
191     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
192     * </p>
193     *
194     * @param <T>    The type of the input of this method and the function.
195     * @param <R>    The type of the result of the function and this method.
196     * @param <E>    The type of thrown exception or error.
197     * @param value  The value to apply the function to, may be {@code null}.
198     * @param mapper The function to apply, must not be {@code null}.
199     * @return The result of the function (which may be {@code null}) or {@code null} if the input value is {@code null}.
200     * @throws E Thrown by the given function.
201     * @see #applyNonNull(Object, FailableFunction, FailableFunction)
202     * @see #applyNonNull(Object, FailableFunction, FailableFunction, FailableFunction)
203     * @since 3.19.0
204     */
205    public static <T, R, E extends Throwable> R applyNonNull(final T value, final FailableFunction<? super T, ? extends R, E> mapper) throws E {
206        return value != null ? Objects.requireNonNull(mapper, "mapper").apply(value) : null;
207    }
208
209    /**
210     * 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
211     * {@code null}, otherwise this method returns {@code null}.
212     *
213     * <pre>{@code
214     * Failable.applyNonNull(" a ", String::toUpperCase, String::trim) = "A"
215     * Failable.applyNonNull(null, String::toUpperCase, String::trim)  = null
216     * Failable.applyNonNull(" a ", s -> null, String::trim)           = null
217     * Failable.applyNonNull(" a ", String::toUpperCase, s -> null)    = null
218     * }</pre>
219     * <p>
220     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
221     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
222     * </p>
223     *
224     * @param <T>     The type of the input of this method and the first function.
225     * @param <U>     The type of the result of the first function and the input to the second function.
226     * @param <R>     The type of the result of the second function and this method.
227     * @param <E1>    The type of thrown exception or error by the first function.
228     * @param <E2>    The type of thrown exception or error by the second function.
229     * @param value1  The value to apply the functions to, may be {@code null}.
230     * @param mapper1 The first function to apply, must not be {@code null}.
231     * @param mapper2 The second function to apply, must not be {@code null}.
232     * @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}.
233     * @throws E1 Thrown by the first function.
234     * @throws E2 Thrown by the second function.
235     * @see #applyNonNull(Object, FailableFunction)
236     * @see #applyNonNull(Object, FailableFunction, FailableFunction, FailableFunction)
237     * @since 3.19.0
238     */
239    public static <T, U, R, E1 extends Throwable, E2 extends Throwable> R applyNonNull(final T value1,
240            final FailableFunction<? super T, ? extends U, E1> mapper1, final FailableFunction<? super U, ? extends R, E2> mapper2) throws E1, E2 {
241        return applyNonNull(applyNonNull(value1, mapper1), mapper2);
242    }
243
244    /**
245     * 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
246     * {@code null}, otherwise this method returns {@code null}.
247     *
248     * <pre>{@code
249     * Failable.applyNonNull(" abc ", String::toUpperCase, String::trim, StringUtils::reverse) = "CBA"
250     * Failable.applyNonNull(null, String::toUpperCase, String::trim, StringUtils::reverse)    = null
251     * Failable.applyNonNull(" abc ", s -> null, String::trim, StringUtils::reverse)           = null
252     * Failable.applyNonNull(" abc ", String::toUpperCase, s -> null, StringUtils::reverse)    = null
253     * Failable.applyNonNull(" abc ", String::toUpperCase, String::trim, s -> null)            = null
254     * }</pre>
255     * <p>
256     * Useful when working with expressions that may return {@code null} as it allows a single-line expression without using temporary local variables or
257     * evaluating expressions twice. Provides an alternative to using {@link Optional} that is shorter and has less allocation.
258     * </p>
259     *
260     * @param <T>     The type of the input of this method and the first function.
261     * @param <U>     The type of the result of the first function and the input to the second function.
262     * @param <V>     The type of the result of the second function and the input to the third function.
263     * @param <R>     The type of the result of the third function and this method.
264     * @param <E1>    The type of thrown exception or error by the first function.
265     * @param <E2>    The type of thrown exception or error by the second function.
266     * @param <E3>    The type of thrown exception or error by the second function.
267     * @param value1  The value to apply the first function, may be {@code null}.
268     * @param mapper1 The first function to apply, must not be {@code null}.
269     * @param mapper2 The second function to apply, must not be {@code null}.
270     * @param mapper3 The third function to apply, must not be {@code null}.
271     * @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}.
272     * @throws E1 Thrown by the first function.
273     * @throws E2 Thrown by the second function.
274     * @throws E3 Thrown by the third function.
275     * @see #applyNonNull(Object, FailableFunction)
276     * @see #applyNonNull(Object, FailableFunction, FailableFunction)
277     * @since 3.19.0
278     */
279    public static <T, U, V, R, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable> R applyNonNull(final T value1,
280            final FailableFunction<? super T, ? extends U, E1> mapper1, final FailableFunction<? super U, ? extends V, E2> mapper2,
281            final FailableFunction<? super V, ? extends R, E3> mapper3) throws E1, E2, E3 {
282        return applyNonNull(applyNonNull(applyNonNull(value1, mapper1), mapper2), mapper3);
283    }
284
285    /**
286     * Converts the given {@link FailableBiConsumer} into a standard {@link BiConsumer}.
287     *
288     * @param <T> the type of the first argument of the consumers
289     * @param <U> the type of the second argument of the consumers
290     * @param consumer a failable {@link BiConsumer}
291     * @return a standard {@link BiConsumer}
292     */
293    public static <T, U> BiConsumer<T, U> asBiConsumer(final FailableBiConsumer<T, U, ?> consumer) {
294        return (input1, input2) -> accept(consumer, input1, input2);
295    }
296
297    /**
298     * Converts the given {@link FailableBiFunction} into a standard {@link BiFunction}.
299     *
300     * @param <T> the type of the first argument of the input of the functions
301     * @param <U> the type of the second argument of the input of the functions
302     * @param <R> the type of the output of the functions
303     * @param function a {@link FailableBiFunction}
304     * @return a standard {@link BiFunction}
305     */
306    public static <T, U, R> BiFunction<T, U, R> asBiFunction(final FailableBiFunction<T, U, R, ?> function) {
307        return (input1, input2) -> apply(function, input1, input2);
308    }
309
310    /**
311     * Converts the given {@link FailableBiPredicate} into a standard {@link BiPredicate}.
312     *
313     * @param <T> the type of the first argument used by the predicates
314     * @param <U> the type of the second argument used by the predicates
315     * @param predicate a {@link FailableBiPredicate}
316     * @return a standard {@link BiPredicate}
317     */
318    public static <T, U> BiPredicate<T, U> asBiPredicate(final FailableBiPredicate<T, U, ?> predicate) {
319        return (input1, input2) -> test(predicate, input1, input2);
320    }
321
322    /**
323     * Converts the given {@link FailableCallable} into a standard {@link Callable}.
324     *
325     * @param <V> the type used by the callables
326     * @param callable a {@link FailableCallable}
327     * @return a standard {@link Callable}
328     */
329    public static <V> Callable<V> asCallable(final FailableCallable<V, ?> callable) {
330        return () -> call(callable);
331    }
332
333    /**
334     * Converts the given {@link FailableConsumer} into a standard {@link Consumer}.
335     *
336     * @param <T> the type used by the consumers
337     * @param consumer a {@link FailableConsumer}
338     * @return a standard {@link Consumer}
339     */
340    public static <T> Consumer<T> asConsumer(final FailableConsumer<T, ?> consumer) {
341        return input -> accept(consumer, input);
342    }
343
344    /**
345     * Converts the given {@link FailableFunction} into a standard {@link Function}.
346     *
347     * @param <T> the type of the input of the functions
348     * @param <R> the type of the output of the functions
349     * @param function a {code FailableFunction}
350     * @return a standard {@link Function}
351     */
352    public static <T, R> Function<T, R> asFunction(final FailableFunction<T, R, ?> function) {
353        return input -> apply(function, input);
354    }
355
356    /**
357     * Converts the given {@link FailablePredicate} into a standard {@link Predicate}.
358     *
359     * @param <T> the type used by the predicates
360     * @param predicate a {@link FailablePredicate}
361     * @return a standard {@link Predicate}
362     */
363    public static <T> Predicate<T> asPredicate(final FailablePredicate<T, ?> predicate) {
364        return input -> test(predicate, input);
365    }
366
367    /**
368     * Converts the given {@link FailableRunnable} into a standard {@link Runnable}.
369     *
370     * @param runnable a {@link FailableRunnable}
371     * @return a standard {@link Runnable}
372     */
373    public static Runnable asRunnable(final FailableRunnable<?> runnable) {
374        return () -> run(runnable);
375    }
376
377    /**
378     * Converts the given {@link FailableSupplier} into a standard {@link Supplier}.
379     *
380     * @param <T> the type supplied by the suppliers
381     * @param supplier a {@link FailableSupplier}
382     * @return a standard {@link Supplier}
383     */
384    public static <T> Supplier<T> asSupplier(final FailableSupplier<T, ?> supplier) {
385        return () -> get(supplier);
386    }
387
388    /**
389     * Calls a callable and rethrows any exception as a {@link RuntimeException}.
390     *
391     * @param callable the callable to call
392     * @param <V> the return type of the callable
393     * @param <E> the type of checked exception the callable may throw
394     * @return the value returned from the callable
395     */
396    public static <V, E extends Throwable> V call(final FailableCallable<V, E> callable) {
397        return get(callable::call);
398    }
399
400    /**
401     * Invokes a supplier, and returns the result.
402     *
403     * @param supplier The supplier to invoke.
404     * @param <T> The suppliers output type.
405     * @param <E> The type of checked exception, which the supplier can throw.
406     * @return The object, which has been created by the supplier
407     */
408    public static <T, E extends Throwable> T get(final FailableSupplier<T, E> supplier) {
409        try {
410            return supplier.get();
411        } catch (final Throwable t) {
412            throw rethrow(t);
413        }
414    }
415
416    /**
417     * Invokes a boolean supplier, and returns the result.
418     *
419     * @param supplier The boolean supplier to invoke.
420     * @param <E> The type of checked exception, which the supplier can throw.
421     * @return The boolean, which has been created by the supplier
422     */
423    public static <E extends Throwable> boolean getAsBoolean(final FailableBooleanSupplier<E> supplier) {
424        try {
425            return supplier.getAsBoolean();
426        } catch (final Throwable t) {
427            throw rethrow(t);
428        }
429    }
430
431    /**
432     * Invokes a double supplier, and returns the result.
433     *
434     * @param supplier The double supplier to invoke.
435     * @param <E> The type of checked exception, which the supplier can throw.
436     * @return The double, which has been created by the supplier
437     */
438    public static <E extends Throwable> double getAsDouble(final FailableDoubleSupplier<E> supplier) {
439        try {
440            return supplier.getAsDouble();
441        } catch (final Throwable t) {
442            throw rethrow(t);
443        }
444    }
445
446    /**
447     * Invokes an int supplier, and returns the result.
448     *
449     * @param supplier The int supplier to invoke.
450     * @param <E> The type of checked exception, which the supplier can throw.
451     * @return The int, which has been created by the supplier
452     */
453    public static <E extends Throwable> int getAsInt(final FailableIntSupplier<E> supplier) {
454        try {
455            return supplier.getAsInt();
456        } catch (final Throwable t) {
457            throw rethrow(t);
458        }
459    }
460
461    /**
462     * Invokes a long supplier, and returns the result.
463     *
464     * @param supplier The long supplier to invoke.
465     * @param <E> The type of checked exception, which the supplier can throw.
466     * @return The long, which has been created by the supplier
467     */
468    public static <E extends Throwable> long getAsLong(final FailableLongSupplier<E> supplier) {
469        try {
470            return supplier.getAsLong();
471        } catch (final Throwable t) {
472            throw rethrow(t);
473        }
474    }
475
476    /**
477     * Invokes a short supplier, and returns the result.
478     *
479     * @param supplier The short supplier to invoke.
480     * @param <E> The type of checked exception, which the supplier can throw.
481     * @return The short, which has been created by the supplier
482     */
483    public static <E extends Throwable> short getAsShort(final FailableShortSupplier<E> supplier) {
484        try {
485            return supplier.getAsShort();
486        } catch (final Throwable t) {
487            throw rethrow(t);
488        }
489    }
490
491    /**
492     * Rethrows a {@link Throwable} as an unchecked exception. If the argument is already unchecked, namely a
493     * {@link RuntimeException} or {@link Error} then the argument will be rethrown without modification. If the
494     * exception is {@link IOException} then it will be wrapped into a {@link UncheckedIOException}. In every other
495     * cases the exception will be wrapped into a {@code
496     * UndeclaredThrowableException}
497     *
498     * <p>
499     * Note that there is a declared return type for this method, even though it never returns. The reason for that is
500     * to support the usual pattern:
501     * </p>
502     *
503     * <pre>
504     * throw rethrow(myUncheckedException);
505     * </pre>
506     *
507     * <p>
508     * instead of just calling the method. This pattern may help the Java compiler to recognize that at that point an
509     * exception will be thrown and the code flow analysis will not demand otherwise mandatory commands that could
510     * follow the method call, like a {@code return} statement from a value returning method.
511     * </p>
512     *
513     * @param throwable The throwable to rethrow possibly wrapped into an unchecked exception
514     * @return Never returns anything, this method never terminates normally.
515     */
516    public static RuntimeException rethrow(final Throwable throwable) {
517        Objects.requireNonNull(throwable, "throwable");
518        ExceptionUtils.throwUnchecked(throwable);
519        if (throwable instanceof IOException) {
520            throw new UncheckedIOException((IOException) throwable);
521        }
522        throw new UndeclaredThrowableException(throwable);
523    }
524
525    /**
526     * Runs a runnable and rethrows any exception as a {@link RuntimeException}.
527     *
528     * @param runnable The runnable to run, may be null for a noop.
529     * @param <E> the type of checked exception the runnable may throw.
530     */
531    public static <E extends Throwable> void run(final FailableRunnable<E> runnable) {
532        if (runnable != null) {
533            try {
534                runnable.run();
535            } catch (final Throwable t) {
536                throw rethrow(t);
537            }
538        }
539    }
540
541    private static <E extends Throwable> void run(final Object test, final FailableRunnable<E> runnable) {
542        if (runnable != null && test != null) {
543            try {
544                runnable.run();
545            } catch (final Throwable t) {
546                throw rethrow(t);
547            }
548        }
549    }
550
551    /**
552     * Converts the given collection into a {@link FailableStream}. The {@link FailableStream} consists of the
553     * collections elements. Shortcut for
554     *
555     * <pre>
556     * Functions.stream(collection.stream());
557     * </pre>
558     *
559     * @param collection The collection, which is being converted into a {@link FailableStream}.
560     * @param <E> The collections element type. (In turn, the result streams element type.)
561     * @return The created {@link FailableStream}.
562     */
563    public static <E> FailableStream<E> stream(final Collection<E> collection) {
564        return new FailableStream<>(collection.stream());
565    }
566
567    /**
568     * Converts the given stream into a {@link FailableStream}. The {@link FailableStream} consists of the same
569     * elements, than the input stream. However, failable lambdas, like {@link FailablePredicate},
570     * {@link FailableFunction}, and {@link FailableConsumer} may be applied, rather than {@link Predicate},
571     * {@link Function}, {@link Consumer}, etc.
572     *
573     * @param stream The stream, which is being converted into a {@link FailableStream}.
574     * @param <T> The streams element type.
575     * @return The created {@link FailableStream}.
576     */
577    public static <T> FailableStream<T> stream(final Stream<T> stream) {
578        return new FailableStream<>(stream);
579    }
580
581    /**
582     * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
583     *
584     * @param predicate the predicate to test
585     * @param object1 the first input to test by {@code predicate}
586     * @param object2 the second input to test by {@code predicate}
587     * @param <T> the type of the first argument the predicate tests
588     * @param <U> the type of the second argument the predicate tests
589     * @param <E> the type of checked exception the predicate may throw
590     * @return the boolean value returned by the predicate
591     */
592    public static <T, U, E extends Throwable> boolean test(final FailableBiPredicate<T, U, E> predicate,
593        final T object1, final U object2) {
594        return getAsBoolean(() -> predicate.test(object1, object2));
595    }
596
597    /**
598     * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
599     *
600     * @param predicate the predicate to test
601     * @param object the input to test by {@code predicate}
602     * @param <T> the type of argument the predicate tests
603     * @param <E> the type of checked exception the predicate may throw
604     * @return the boolean value returned by the predicate
605     */
606    public static <T, E extends Throwable> boolean test(final FailablePredicate<T, E> predicate, final T object) {
607        return getAsBoolean(() -> predicate.test(object));
608    }
609
610    /**
611     * A simple try-with-resources implementation, that can be used, if your objects do not implement the
612     * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
613     * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
614     * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
615     * {@link Throwable}) is rethrown. Example use:
616     *
617     * <pre>{@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 = Failable::rethrow;
636        } else {
637            actualErrorHandler = errorHandler;
638        }
639        Streams.of(resources).forEach(r -> Objects.requireNonNull(r, "runnable"));
640        Throwable th = null;
641        try {
642            action.run();
643        } catch (final Throwable t) {
644            th = t;
645        }
646        if (resources != null) {
647            for (final FailableRunnable<?> runnable : resources) {
648                try {
649                    runnable.run();
650                } catch (final Throwable t) {
651                    if (th == null) {
652                        th = t;
653                    }
654                }
655            }
656        }
657        if (th != null) {
658            try {
659                actualErrorHandler.accept(th);
660            } catch (final Throwable t) {
661                throw rethrow(t);
662            }
663        }
664    }
665
666    /**
667     * A simple try-with-resources implementation, that can be used, if your objects do not implement the
668     * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
669     * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
670     * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
671     * {@link Throwable}) is rethrown. Example use:
672     *
673     * <pre>{@code
674     * final FileInputStream fis = new FileInputStream("my.file");
675     * Functions.tryWithResources(useInputStream(fis), () -> fis.close());
676     * }</pre>
677     *
678     * @param action The action to execute. This object <em>will</em> always be invoked.
679     * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
680     *        order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
681     * @see #tryWithResources(FailableRunnable, FailableConsumer, FailableRunnable...)
682     */
683    @SafeVarargs
684    public static void tryWithResources(final FailableRunnable<? extends Throwable> action, final FailableRunnable<? extends Throwable>... resources) {
685        tryWithResources(action, null, resources);
686    }
687
688    private Failable() {
689        // empty
690    }
691
692}