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 -&gt; {
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>
063 * Functions.accept((m) -&gt; 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}