View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3.function;
19  
20  import java.io.IOException;
21  import java.io.UncheckedIOException;
22  import java.lang.reflect.UndeclaredThrowableException;
23  import java.util.Collection;
24  import java.util.Objects;
25  import java.util.concurrent.Callable;
26  import java.util.function.BiConsumer;
27  import java.util.function.BiFunction;
28  import java.util.function.BiPredicate;
29  import java.util.function.Consumer;
30  import java.util.function.Function;
31  import java.util.function.Predicate;
32  import java.util.function.Supplier;
33  import java.util.stream.Stream;
34  
35  import org.apache.commons.lang3.exception.ExceptionUtils;
36  import org.apache.commons.lang3.stream.Streams;
37  import org.apache.commons.lang3.stream.Streams.FailableStream;
38  
39  /**
40   * This class provides utility functions, and classes for working with the {@code java.util.function} package, or more
41   * generally, with Java 8 lambdas. More specifically, it attempts to address the fact that lambdas are supposed not to
42   * throw Exceptions, at least not checked Exceptions, AKA instances of {@link Exception}. This enforces the use of
43   * constructs like:
44   *
45   * <pre>{@code
46   * Consumer<java.lang.reflect.Method> consumer = m -&gt; {
47   *     try {
48   *         m.invoke(o, args);
49   *     } catch (Throwable t) {
50   *         throw Failable.rethrow(t);
51   *     }
52   * };
53   * }
54   * </pre>
55   *
56   * <p>
57   * By replacing a {@link java.util.function.Consumer Consumer&lt;O&gt;} with a {@link FailableConsumer
58   * FailableConsumer&lt;O,? extends Throwable&gt;}, this can be written like follows:
59   * </p>
60   *
61   * <pre>
62   * Functions.accept((m) -&gt; m.invoke(o, args));
63   * </pre>
64   *
65   * <p>
66   * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than the second
67   * version.
68   * </p>
69   *
70   * @since 3.11
71   */
72  public class Failable {
73  
74      /**
75       * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
76       *
77       * @param consumer the consumer to consume
78       * @param object1 the first object to consume by {@code consumer}
79       * @param object2 the second object to consume by {@code consumer}
80       * @param <T> the type of the first argument the consumer accepts
81       * @param <U> the type of the second argument the consumer accepts
82       * @param <E> the type of checked exception the consumer may throw
83       */
84      public static <T, U, E extends Throwable> void accept(final FailableBiConsumer<T, U, E> consumer, final T object1,
85          final U object2) {
86          run(() -> consumer.accept(object1, object2));
87      }
88  
89      /**
90       * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
91       *
92       * @param consumer the consumer to consume
93       * @param object the object to consume by {@code consumer}
94       * @param <T> the type the consumer accepts
95       * @param <E> the type of checked exception the consumer may throw
96       */
97      public static <T, E extends Throwable> void accept(final FailableConsumer<T, E> consumer, final T object) {
98          run(() -> consumer.accept(object));
99      }
100 
101     /**
102      * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
103      *
104      * @param consumer the consumer to consume
105      * @param value the value to consume by {@code consumer}
106      * @param <E> the type of checked exception the consumer may throw
107      */
108     public static <E extends Throwable> void accept(final FailableDoubleConsumer<E> consumer, final double value) {
109         run(() -> consumer.accept(value));
110     }
111 
112     /**
113      * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
114      *
115      * @param consumer the consumer to consume
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.accept(value));
121     }
122 
123     /**
124      * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
125      *
126      * @param consumer the consumer to consume
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.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      * Converts the given {@link FailableBiConsumer} into a standard {@link BiConsumer}.
181      *
182      * @param <T> the type of the first argument of the consumers
183      * @param <U> the type of the second argument of the consumers
184      * @param consumer a failable {@link BiConsumer}
185      * @return a standard {@link BiConsumer}
186      */
187     public static <T, U> BiConsumer<T, U> asBiConsumer(final FailableBiConsumer<T, U, ?> consumer) {
188         return (input1, input2) -> accept(consumer, input1, input2);
189     }
190 
191     /**
192      * Converts the given {@link FailableBiFunction} into a standard {@link BiFunction}.
193      *
194      * @param <T> the type of the first argument of the input of the functions
195      * @param <U> the type of the second argument of the input of the functions
196      * @param <R> the type of the output of the functions
197      * @param function a {@link FailableBiFunction}
198      * @return a standard {@link BiFunction}
199      */
200     public static <T, U, R> BiFunction<T, U, R> asBiFunction(final FailableBiFunction<T, U, R, ?> function) {
201         return (input1, input2) -> apply(function, input1, input2);
202     }
203 
204     /**
205      * Converts the given {@link FailableBiPredicate} into a standard {@link BiPredicate}.
206      *
207      * @param <T> the type of the first argument used by the predicates
208      * @param <U> the type of the second argument used by the predicates
209      * @param predicate a {@link FailableBiPredicate}
210      * @return a standard {@link BiPredicate}
211      */
212     public static <T, U> BiPredicate<T, U> asBiPredicate(final FailableBiPredicate<T, U, ?> predicate) {
213         return (input1, input2) -> test(predicate, input1, input2);
214     }
215 
216     /**
217      * Converts the given {@link FailableCallable} into a standard {@link Callable}.
218      *
219      * @param <V> the type used by the callables
220      * @param callable a {@link FailableCallable}
221      * @return a standard {@link Callable}
222      */
223     public static <V> Callable<V> asCallable(final FailableCallable<V, ?> callable) {
224         return () -> call(callable);
225     }
226 
227     /**
228      * Converts the given {@link FailableConsumer} into a standard {@link Consumer}.
229      *
230      * @param <T> the type used by the consumers
231      * @param consumer a {@link FailableConsumer}
232      * @return a standard {@link Consumer}
233      */
234     public static <T> Consumer<T> asConsumer(final FailableConsumer<T, ?> consumer) {
235         return input -> accept(consumer, input);
236     }
237 
238     /**
239      * Converts the given {@link FailableFunction} into a standard {@link Function}.
240      *
241      * @param <T> the type of the input of the functions
242      * @param <R> the type of the output of the functions
243      * @param function a {code FailableFunction}
244      * @return a standard {@link Function}
245      */
246     public static <T, R> Function<T, R> asFunction(final FailableFunction<T, R, ?> function) {
247         return input -> apply(function, input);
248     }
249 
250     /**
251      * Converts the given {@link FailablePredicate} into a standard {@link Predicate}.
252      *
253      * @param <T> the type used by the predicates
254      * @param predicate a {@link FailablePredicate}
255      * @return a standard {@link Predicate}
256      */
257     public static <T> Predicate<T> asPredicate(final FailablePredicate<T, ?> predicate) {
258         return input -> test(predicate, input);
259     }
260 
261     /**
262      * Converts the given {@link FailableRunnable} into a standard {@link Runnable}.
263      *
264      * @param runnable a {@link FailableRunnable}
265      * @return a standard {@link Runnable}
266      */
267     public static Runnable asRunnable(final FailableRunnable<?> runnable) {
268         return () -> run(runnable);
269     }
270 
271     /**
272      * Converts the given {@link FailableSupplier} into a standard {@link Supplier}.
273      *
274      * @param <T> the type supplied by the suppliers
275      * @param supplier a {@link FailableSupplier}
276      * @return a standard {@link Supplier}
277      */
278     public static <T> Supplier<T> asSupplier(final FailableSupplier<T, ?> supplier) {
279         return () -> get(supplier);
280     }
281 
282     /**
283      * Calls a callable and rethrows any exception as a {@link RuntimeException}.
284      *
285      * @param callable the callable to call
286      * @param <V> the return type of the callable
287      * @param <E> the type of checked exception the callable may throw
288      * @return the value returned from the callable
289      */
290     public static <V, E extends Throwable> V call(final FailableCallable<V, E> callable) {
291         return get(callable::call);
292     }
293 
294     /**
295      * Invokes a supplier, and returns the result.
296      *
297      * @param supplier The supplier to invoke.
298      * @param <T> The suppliers output type.
299      * @param <E> The type of checked exception, which the supplier can throw.
300      * @return The object, which has been created by the supplier
301      */
302     public static <T, E extends Throwable> T get(final FailableSupplier<T, E> supplier) {
303         try {
304             return supplier.get();
305         } catch (final Throwable t) {
306             throw rethrow(t);
307         }
308     }
309 
310     /**
311      * Invokes a boolean supplier, and returns the result.
312      *
313      * @param supplier The boolean supplier to invoke.
314      * @param <E> The type of checked exception, which the supplier can throw.
315      * @return The boolean, which has been created by the supplier
316      */
317     public static <E extends Throwable> boolean getAsBoolean(final FailableBooleanSupplier<E> supplier) {
318         try {
319             return supplier.getAsBoolean();
320         } catch (final Throwable t) {
321             throw rethrow(t);
322         }
323     }
324 
325     /**
326      * Invokes a double supplier, and returns the result.
327      *
328      * @param supplier The double supplier to invoke.
329      * @param <E> The type of checked exception, which the supplier can throw.
330      * @return The double, which has been created by the supplier
331      */
332     public static <E extends Throwable> double getAsDouble(final FailableDoubleSupplier<E> supplier) {
333         try {
334             return supplier.getAsDouble();
335         } catch (final Throwable t) {
336             throw rethrow(t);
337         }
338     }
339 
340     /**
341      * Invokes an int supplier, and returns the result.
342      *
343      * @param supplier The int supplier to invoke.
344      * @param <E> The type of checked exception, which the supplier can throw.
345      * @return The int, which has been created by the supplier
346      */
347     public static <E extends Throwable> int getAsInt(final FailableIntSupplier<E> supplier) {
348         try {
349             return supplier.getAsInt();
350         } catch (final Throwable t) {
351             throw rethrow(t);
352         }
353     }
354 
355     /**
356      * Invokes a long supplier, and returns the result.
357      *
358      * @param supplier The long supplier to invoke.
359      * @param <E> The type of checked exception, which the supplier can throw.
360      * @return The long, which has been created by the supplier
361      */
362     public static <E extends Throwable> long getAsLong(final FailableLongSupplier<E> supplier) {
363         try {
364             return supplier.getAsLong();
365         } catch (final Throwable t) {
366             throw rethrow(t);
367         }
368     }
369 
370     /**
371      * Invokes a short supplier, and returns the result.
372      *
373      * @param supplier The short supplier to invoke.
374      * @param <E> The type of checked exception, which the supplier can throw.
375      * @return The short, which has been created by the supplier
376      */
377     public static <E extends Throwable> short getAsShort(final FailableShortSupplier<E> supplier) {
378         try {
379             return supplier.getAsShort();
380         } catch (final Throwable t) {
381             throw rethrow(t);
382         }
383     }
384 
385     /**
386      * Rethrows a {@link Throwable} as an unchecked exception. If the argument is already unchecked, namely a
387      * {@link RuntimeException} or {@link Error} then the argument will be rethrown without modification. If the
388      * exception is {@link IOException} then it will be wrapped into a {@link UncheckedIOException}. In every other
389      * cases the exception will be wrapped into a {@code
390      * UndeclaredThrowableException}
391      *
392      * <p>
393      * Note that there is a declared return type for this method, even though it never returns. The reason for that is
394      * to support the usual pattern:
395      * </p>
396      *
397      * <pre>
398      * throw rethrow(myUncheckedException);
399      * </pre>
400      *
401      * <p>
402      * instead of just calling the method. This pattern may help the Java compiler to recognize that at that point an
403      * exception will be thrown and the code flow analysis will not demand otherwise mandatory commands that could
404      * follow the method call, like a {@code return} statement from a value returning method.
405      * </p>
406      *
407      * @param throwable The throwable to rethrow possibly wrapped into an unchecked exception
408      * @return Never returns anything, this method never terminates normally.
409      */
410     public static RuntimeException rethrow(final Throwable throwable) {
411         Objects.requireNonNull(throwable, "throwable");
412         ExceptionUtils.throwUnchecked(throwable);
413         if (throwable instanceof IOException) {
414             throw new UncheckedIOException((IOException) throwable);
415         }
416         throw new UndeclaredThrowableException(throwable);
417     }
418 
419     /**
420      * Runs a runnable and rethrows any exception as a {@link RuntimeException}.
421      *
422      * @param runnable The runnable to run
423      * @param <E> the type of checked exception the runnable may throw
424      */
425     public static <E extends Throwable> void run(final FailableRunnable<E> runnable) {
426         try {
427             runnable.run();
428         } catch (final Throwable t) {
429             throw rethrow(t);
430         }
431     }
432 
433     /**
434      * Converts the given collection into a {@link FailableStream}. The {@link FailableStream} consists of the
435      * collections elements. Shortcut for
436      *
437      * <pre>
438      * Functions.stream(collection.stream());
439      * </pre>
440      *
441      * @param collection The collection, which is being converted into a {@link FailableStream}.
442      * @param <E> The collections element type. (In turn, the result streams element type.)
443      * @return The created {@link FailableStream}.
444      */
445     public static <E> FailableStream<E> stream(final Collection<E> collection) {
446         return new FailableStream<>(collection.stream());
447     }
448 
449     /**
450      * Converts the given stream into a {@link FailableStream}. The {@link FailableStream} consists of the same
451      * elements, than the input stream. However, failable lambdas, like {@link FailablePredicate},
452      * {@link FailableFunction}, and {@link FailableConsumer} may be applied, rather than {@link Predicate},
453      * {@link Function}, {@link Consumer}, etc.
454      *
455      * @param stream The stream, which is being converted into a {@link FailableStream}.
456      * @param <T> The streams element type.
457      * @return The created {@link FailableStream}.
458      */
459     public static <T> FailableStream<T> stream(final Stream<T> stream) {
460         return new FailableStream<>(stream);
461     }
462 
463     /**
464      * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
465      *
466      * @param predicate the predicate to test
467      * @param object1 the first input to test by {@code predicate}
468      * @param object2 the second input to test by {@code predicate}
469      * @param <T> the type of the first argument the predicate tests
470      * @param <U> the type of the second argument the predicate tests
471      * @param <E> the type of checked exception the predicate may throw
472      * @return the boolean value returned by the predicate
473      */
474     public static <T, U, E extends Throwable> boolean test(final FailableBiPredicate<T, U, E> predicate,
475         final T object1, final U object2) {
476         return getAsBoolean(() -> predicate.test(object1, object2));
477     }
478 
479     /**
480      * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
481      *
482      * @param predicate the predicate to test
483      * @param object the input to test by {@code predicate}
484      * @param <T> the type of argument the predicate tests
485      * @param <E> the type of checked exception the predicate may throw
486      * @return the boolean value returned by the predicate
487      */
488     public static <T, E extends Throwable> boolean test(final FailablePredicate<T, E> predicate, final T object) {
489         return getAsBoolean(() -> predicate.test(object));
490     }
491 
492     /**
493      * A simple try-with-resources implementation, that can be used, if your objects do not implement the
494      * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
495      * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
496      * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
497      * {@link Throwable}) is rethrown. Example use:
498      *
499      * <pre>{@code
500      * final FileInputStream fis = new FileInputStream("my.file");
501      * Functions.tryWithResources(useInputStream(fis), null, () -> fis.close());
502      * }</pre>
503      *
504      * @param action The action to execute. This object <em>will</em> always be invoked.
505      * @param errorHandler An optional error handler, which will be invoked finally, if any error occurred. The error
506      *        handler will receive the first error, AKA {@link Throwable}.
507      * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
508      *        order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
509      * @see #tryWithResources(FailableRunnable, FailableRunnable...)
510      */
511     @SafeVarargs
512     public static void tryWithResources(final FailableRunnable<? extends Throwable> action,
513         final FailableConsumer<Throwable, ? extends Throwable> errorHandler,
514         final FailableRunnable<? extends Throwable>... resources) {
515         final FailableConsumer<Throwable, ? extends Throwable> actualErrorHandler;
516         if (errorHandler == null) {
517             actualErrorHandler = Failable::rethrow;
518         } else {
519             actualErrorHandler = errorHandler;
520         }
521         Streams.of(resources).forEach(r -> Objects.requireNonNull(r, "runnable"));
522         Throwable th = null;
523         try {
524             action.run();
525         } catch (final Throwable t) {
526             th = t;
527         }
528         if (resources != null) {
529             for (final FailableRunnable<?> runnable : resources) {
530                 try {
531                     runnable.run();
532                 } catch (final Throwable t) {
533                     if (th == null) {
534                         th = t;
535                     }
536                 }
537             }
538         }
539         if (th != null) {
540             try {
541                 actualErrorHandler.accept(th);
542             } catch (final Throwable t) {
543                 throw rethrow(t);
544             }
545         }
546     }
547 
548     /**
549      * A simple try-with-resources implementation, that can be used, if your objects do not implement the
550      * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
551      * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
552      * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
553      * {@link Throwable}) is rethrown. Example use:
554      *
555      * <pre>{@code
556      * final FileInputStream fis = new FileInputStream("my.file");
557      * Functions.tryWithResources(useInputStream(fis), () -> fis.close());
558      * }</pre>
559      *
560      * @param action The action to execute. This object <em>will</em> always be invoked.
561      * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
562      *        order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
563      * @see #tryWithResources(FailableRunnable, FailableConsumer, FailableRunnable...)
564      */
565     @SafeVarargs
566     public static void tryWithResources(final FailableRunnable<? extends Throwable> action, final FailableRunnable<? extends Throwable>... resources) {
567         tryWithResources(action, null, resources);
568     }
569 
570     private Failable() {
571         // empty
572     }
573 
574 }