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 * https://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 package org.apache.commons.lang3;
18
19 import java.io.IOException;
20 import java.io.UncheckedIOException;
21 import java.lang.reflect.UndeclaredThrowableException;
22 import java.util.Arrays;
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.Streams.FailableStream;
36 import org.apache.commons.lang3.exception.ExceptionUtils;
37 import org.apache.commons.lang3.function.Failable;
38 import org.apache.commons.lang3.function.FailableBooleanSupplier;
39
40 /**
41 * This class provides utility functions, and classes for working with the {@code java.util.function} package, or more
42 * generally, with Java 8 lambdas. More specifically, it attempts to address the fact that lambdas are supposed not to
43 * throw Exceptions, at least not checked Exceptions, AKA instances of {@link Exception}. This enforces the use of
44 * constructs like:
45 *
46 * <pre>
47 * {@code
48 * Consumer<java.lang.reflect.Method> consumer = m -> {
49 * try {
50 * m.invoke(o, args);
51 * } catch (Throwable t) {
52 * throw Functions.rethrow(t);
53 * }
54 * };
55 * }</pre>
56 *
57 * <p>
58 * By replacing a {@link java.util.function.Consumer Consumer<O>} with a {@link FailableConsumer
59 * FailableConsumer<O,? extends Throwable>}, this can be written like follows:
60 * </p>
61 *
62 * <pre>
63 * {@code
64 * Functions.accept((m) -> m.invoke(o,args));
65 * }</pre>
66 *
67 * <p>
68 * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than the second
69 * version.
70 * </p>
71 *
72 * @since 3.9
73 * @deprecated Use {@link org.apache.commons.lang3.function.Failable}.
74 */
75 @Deprecated
76 public class Functions {
77
78 /**
79 * A functional interface like {@link BiConsumer} that declares a {@link Throwable}.
80 *
81 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
82 *
83 * @param <O1> Consumed type 1.
84 * @param <O2> Consumed type 2.
85 * @param <T> Thrown exception.
86 * @deprecated Use {@link org.apache.commons.lang3.function.FailableBiConsumer}.
87 */
88 @Deprecated
89 @FunctionalInterface
90 public interface FailableBiConsumer<O1, O2, T extends Throwable> {
91
92 /**
93 * Accepts the consumer.
94 *
95 * @param object1 the first parameter for the consumable to accept
96 * @param object2 the second parameter for the consumable to accept
97 * @throws T Thrown when the consumer fails.
98 */
99 void accept(O1 object1, O2 object2) throws T;
100 }
101
102 /**
103 * A functional interface like {@link BiFunction} that declares a {@link Throwable}.
104 *
105 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
106 *
107 * @param <O1> Input type 1.
108 * @param <O2> Input type 2.
109 * @param <R> Return type.
110 * @param <T> Thrown exception.
111 * @deprecated Use {@link org.apache.commons.lang3.function.FailableBiFunction}.
112 */
113 @Deprecated
114 @FunctionalInterface
115 public interface FailableBiFunction<O1, O2, R, T extends Throwable> {
116
117 /**
118 * Applies this function.
119 *
120 * @param input1 the first input for the function
121 * @param input2 the second input for the function
122 * @return the result of the function
123 * @throws T Thrown when the function fails.
124 */
125 R apply(O1 input1, O2 input2) throws T;
126 }
127
128 /**
129 * A functional interface like {@link BiPredicate} that declares a {@link Throwable}.
130 *
131 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
132 *
133 * @param <O1> Predicate type 1.
134 * @param <O2> Predicate type 2.
135 * @param <T> Thrown exception.
136 * @deprecated Use {@link org.apache.commons.lang3.function.FailableBiPredicate}.
137 */
138 @Deprecated
139 @FunctionalInterface
140 public interface FailableBiPredicate<O1, O2, T extends Throwable> {
141
142 /**
143 * Tests the predicate.
144 *
145 * @param object1 the first object to test the predicate on
146 * @param object2 the second object to test the predicate on
147 * @return the predicate's evaluation
148 * @throws T if the predicate fails
149 */
150 boolean test(O1 object1, O2 object2) throws T;
151 }
152
153 /**
154 * A functional interface like {@link java.util.concurrent.Callable} that declares a {@link Throwable}.
155 *
156 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
157 *
158 * @param <R> Return type.
159 * @param <T> Thrown exception.
160 * @deprecated Use {@link org.apache.commons.lang3.function.FailableCallable}.
161 */
162 @Deprecated
163 @FunctionalInterface
164 public interface FailableCallable<R, T extends Throwable> {
165
166 /**
167 * Calls the callable.
168 *
169 * @return The value returned from the callable
170 * @throws T if the callable fails
171 */
172 R call() throws T;
173 }
174
175 /**
176 * A functional interface like {@link Consumer} that declares a {@link Throwable}.
177 *
178 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
179 *
180 * @param <O> Consumed type 1.
181 * @param <T> Thrown exception.
182 * @deprecated Use {@link org.apache.commons.lang3.function.FailableConsumer}.
183 */
184 @Deprecated
185 @FunctionalInterface
186 public interface FailableConsumer<O, T extends Throwable> {
187
188 /**
189 * Accepts the consumer.
190 *
191 * @param object the parameter for the consumable to accept
192 * @throws T Thrown when the consumer fails.
193 */
194 void accept(O object) throws T;
195 }
196
197 /**
198 * A functional interface like {@link Function} that declares a {@link Throwable}.
199 *
200 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
201 *
202 * @param <I> Input type 1.
203 * @param <R> Return type.
204 * @param <T> Thrown exception.
205 * @deprecated Use {@link org.apache.commons.lang3.function.FailableFunction}.
206 */
207 @Deprecated
208 @FunctionalInterface
209 public interface FailableFunction<I, R, T extends Throwable> {
210
211 /**
212 * Applies this function.
213 *
214 * @param input the input for the function
215 * @return the result of the function
216 * @throws T Thrown when the function fails.
217 */
218 R apply(I input) throws T;
219 }
220
221 /**
222 * A functional interface like {@link Predicate} that declares a {@link Throwable}.
223 *
224 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
225 *
226 * @param <I> Predicate type 1.
227 * @param <T> Thrown exception.
228 * @deprecated Use {@link org.apache.commons.lang3.function.FailablePredicate}.
229 */
230 @Deprecated
231 @FunctionalInterface
232 public interface FailablePredicate<I, T extends Throwable> {
233
234 /**
235 * Tests the predicate.
236 *
237 * @param object the object to test the predicate on
238 * @return the predicate's evaluation
239 * @throws T if the predicate fails
240 */
241 boolean test(I object) throws T;
242 }
243
244 /**
245 * A functional interface like {@link Runnable} that declares a {@link Throwable}.
246 *
247 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
248 *
249 * @param <T> Thrown exception.
250 * @deprecated Use {@link org.apache.commons.lang3.function.FailableRunnable}.
251 */
252 @Deprecated
253 @FunctionalInterface
254 public interface FailableRunnable<T extends Throwable> {
255
256 /**
257 * Runs the function.
258 *
259 * @throws T Thrown when the function fails.
260 */
261 void run() throws T;
262 }
263
264 /**
265 * A functional interface like {@link Supplier} that declares a {@link Throwable}.
266 *
267 * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
268 *
269 * @param <R> Return type.
270 * @param <T> Thrown exception.
271 * @deprecated Use {@link org.apache.commons.lang3.function.FailableSupplier}.
272 */
273 @Deprecated
274 @FunctionalInterface
275 public interface FailableSupplier<R, T extends Throwable> {
276
277 /**
278 * Supplies an object
279 *
280 * @return a result
281 * @throws T if the supplier fails
282 */
283 R get() throws T;
284 }
285
286 /**
287 * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
288 *
289 * @param consumer the consumer to consume
290 * @param object1 the first object to consume by {@code consumer}
291 * @param object2 the second object to consume by {@code consumer}
292 * @param <O1> the type of the first argument the consumer accepts
293 * @param <O2> the type of the second argument the consumer accepts
294 * @param <T> the type of checked exception the consumer may throw
295 */
296 public static <O1, O2, T extends Throwable> void accept(final FailableBiConsumer<O1, O2, T> consumer,
297 final O1 object1, final O2 object2) {
298 run(() -> consumer.accept(object1, object2));
299 }
300
301 /**
302 * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
303 *
304 * @param consumer the consumer to consume
305 * @param object the object to consume by {@code consumer}
306 * @param <O> the type the consumer accepts
307 * @param <T> the type of checked exception the consumer may throw
308 */
309 public static <O, T extends Throwable> void accept(final FailableConsumer<O, T> consumer, final O object) {
310 run(() -> consumer.accept(object));
311 }
312
313 /**
314 * Applies a function and rethrows any exception as a {@link RuntimeException}.
315 *
316 * @param function the function to apply
317 * @param input1 the first input to apply {@code function} on
318 * @param input2 the second input to apply {@code function} on
319 * @param <O1> the type of the first argument the function accepts
320 * @param <O2> the type of the second argument the function accepts
321 * @param <O> the return type of the function
322 * @param <T> the type of checked exception the function may throw
323 * @return the value returned from the function
324 */
325 public static <O1, O2, O, T extends Throwable> O apply(final FailableBiFunction<O1, O2, O, T> function,
326 final O1 input1, final O2 input2) {
327 return get(() -> function.apply(input1, input2));
328 }
329
330 /**
331 * Applies a function and rethrows any exception as a {@link RuntimeException}.
332 *
333 * @param function the function to apply
334 * @param input the input to apply {@code function} on
335 * @param <I> the type of the argument the function accepts
336 * @param <O> the return type of the function
337 * @param <T> the type of checked exception the function may throw
338 * @return the value returned from the function
339 */
340 public static <I, O, T extends Throwable> O apply(final FailableFunction<I, O, T> function, final I input) {
341 return get(() -> function.apply(input));
342 }
343
344 /**
345 * Converts the given {@link FailableBiConsumer} into a standard {@link BiConsumer}.
346 *
347 * @param <O1> the type of the first argument of the consumers
348 * @param <O2> the type of the second argument of the consumers
349 * @param consumer a failable {@link BiConsumer}
350 * @return a standard {@link BiConsumer}
351 * @since 3.10
352 */
353 public static <O1, O2> BiConsumer<O1, O2> asBiConsumer(final FailableBiConsumer<O1, O2, ?> consumer) {
354 return (input1, input2) -> accept(consumer, input1, input2);
355 }
356
357 /**
358 * Converts the given {@link FailableBiFunction} into a standard {@link BiFunction}.
359 *
360 * @param <O1> the type of the first argument of the input of the functions
361 * @param <O2> the type of the second argument of the input of the functions
362 * @param <O> the type of the output of the functions
363 * @param function a {@link FailableBiFunction}
364 * @return a standard {@link BiFunction}
365 * @since 3.10
366 */
367 public static <O1, O2, O> BiFunction<O1, O2, O> asBiFunction(final FailableBiFunction<O1, O2, O, ?> function) {
368 return (input1, input2) -> apply(function, input1, input2);
369 }
370
371 /**
372 * Converts the given {@link FailableBiPredicate} into a standard {@link BiPredicate}.
373 *
374 * @param <O1> the type of the first argument used by the predicates
375 * @param <O2> the type of the second argument used by the predicates
376 * @param predicate a {@link FailableBiPredicate}
377 * @return a standard {@link BiPredicate}
378 * @since 3.10
379 */
380 public static <O1, O2> BiPredicate<O1, O2> asBiPredicate(final FailableBiPredicate<O1, O2, ?> predicate) {
381 return (input1, input2) -> test(predicate, input1, input2);
382 }
383
384 /**
385 * Converts the given {@link FailableCallable} into a standard {@link Callable}.
386 *
387 * @param <O> the type used by the callables
388 * @param callable a {@link FailableCallable}
389 * @return a standard {@link Callable}
390 * @since 3.10
391 */
392 public static <O> Callable<O> asCallable(final FailableCallable<O, ?> callable) {
393 return () -> call(callable);
394 }
395
396 /**
397 * Converts the given {@link FailableConsumer} into a standard {@link Consumer}.
398 *
399 * @param <I> the type used by the consumers
400 * @param consumer a {@link FailableConsumer}
401 * @return a standard {@link Consumer}
402 * @since 3.10
403 */
404 public static <I> Consumer<I> asConsumer(final FailableConsumer<I, ?> consumer) {
405 return input -> accept(consumer, input);
406 }
407
408 /**
409 * Converts the given {@link FailableFunction} into a standard {@link Function}.
410 *
411 * @param <I> the type of the input of the functions
412 * @param <O> the type of the output of the functions
413 * @param function a {code FailableFunction}
414 * @return a standard {@link Function}
415 * @since 3.10
416 */
417 public static <I, O> Function<I, O> asFunction(final FailableFunction<I, O, ?> function) {
418 return input -> apply(function, input);
419 }
420
421 /**
422 * Converts the given {@link FailablePredicate} into a standard {@link Predicate}.
423 *
424 * @param <I> the type used by the predicates
425 * @param predicate a {@link FailablePredicate}
426 * @return a standard {@link Predicate}
427 * @since 3.10
428 */
429 public static <I> Predicate<I> asPredicate(final FailablePredicate<I, ?> predicate) {
430 return input -> test(predicate, input);
431 }
432
433 /**
434 * Converts the given {@link FailableRunnable} into a standard {@link Runnable}.
435 *
436 * @param runnable a {@link FailableRunnable}
437 * @return a standard {@link Runnable}
438 * @since 3.10
439 */
440 public static Runnable asRunnable(final FailableRunnable<?> runnable) {
441 return () -> run(runnable);
442 }
443
444 /**
445 * Converts the given {@link FailableSupplier} into a standard {@link Supplier}.
446 *
447 * @param <O> the type supplied by the suppliers
448 * @param supplier a {@link FailableSupplier}
449 * @return a standard {@link Supplier}
450 * @since 3.10
451 */
452 public static <O> Supplier<O> asSupplier(final FailableSupplier<O, ?> supplier) {
453 return () -> get(supplier);
454 }
455
456 /**
457 * Calls a callable and rethrows any exception as a {@link RuntimeException}.
458 *
459 * @param callable the callable to call
460 * @param <O> the return type of the callable
461 * @param <T> the type of checked exception the callable may throw
462 * @return the value returned from the callable
463 */
464 public static <O, T extends Throwable> O call(final FailableCallable<O, T> callable) {
465 return get(callable::call);
466 }
467
468 /**
469 * Invokes a supplier, and returns the result.
470 *
471 * @param supplier The supplier to invoke.
472 * @param <O> The suppliers output type.
473 * @param <T> The type of checked exception, which the supplier can throw.
474 * @return The object, which has been created by the supplier
475 * @since 3.10
476 */
477 public static <O, T extends Throwable> O get(final FailableSupplier<O, T> supplier) {
478 try {
479 return supplier.get();
480 } catch (final Throwable t) {
481 throw rethrow(t);
482 }
483 }
484
485 /**
486 * Invokes a boolean supplier, and returns the result.
487 *
488 * @param supplier The boolean supplier to invoke.
489 * @param <T> The type of checked exception, which the supplier can throw.
490 * @return The boolean, which has been created by the supplier
491 */
492 private static <T extends Throwable> boolean getAsBoolean(final FailableBooleanSupplier<T> supplier) {
493 try {
494 return supplier.getAsBoolean();
495 } catch (final Throwable t) {
496 throw rethrow(t);
497 }
498 }
499
500 /**
501 * Rethrows a {@link Throwable} as an unchecked exception. If the argument is already unchecked, namely a
502 * {@link RuntimeException} or {@link Error} then the argument will be rethrown without modification. If the
503 * exception is {@link IOException} then it will be wrapped into a {@link UncheckedIOException}. In every other
504 * cases the exception will be wrapped into a {@code
505 * UndeclaredThrowableException}
506 *
507 * <p>
508 * Note that there is a declared return type for this method, even though it never returns. The reason for that is
509 * to support the usual pattern:
510 * </p>
511 *
512 * <pre>
513 * throw rethrow(myUncheckedException);</pre>
514 *
515 * <p>
516 * instead of just calling the method. This pattern may help the Java compiler to recognize that at that point an
517 * exception will be thrown and the code flow analysis will not demand otherwise mandatory commands that could
518 * follow the method call, like a {@code return} statement from a value returning method.
519 * </p>
520 *
521 * @param throwable The throwable to rethrow possibly wrapped into an unchecked exception
522 * @return Never returns anything, this method never terminates normally.
523 */
524 public static RuntimeException rethrow(final Throwable throwable) {
525 Objects.requireNonNull(throwable, "throwable");
526 ExceptionUtils.throwUnchecked(throwable);
527 if (throwable instanceof IOException) {
528 throw new UncheckedIOException((IOException) throwable);
529 }
530 throw new UndeclaredThrowableException(throwable);
531 }
532
533 /**
534 * Runs a runnable and rethrows any exception as a {@link RuntimeException}.
535 *
536 * @param runnable The runnable to run
537 * @param <T> the type of checked exception the runnable may throw
538 */
539 public static <T extends Throwable> void run(final FailableRunnable<T> runnable) {
540 try {
541 runnable.run();
542 } catch (final Throwable t) {
543 throw rethrow(t);
544 }
545 }
546
547 /**
548 * Converts the given collection into a {@link FailableStream}. The {@link FailableStream} consists of the
549 * collections elements. Shortcut for
550 *
551 * <pre>
552 * Functions.stream(collection.stream());</pre>
553 *
554 * @param collection The collection, which is being converted into a {@link FailableStream}.
555 * @param <O> The collections element type. (In turn, the result streams element type.)
556 * @return The created {@link FailableStream}.
557 * @since 3.10
558 */
559 public static <O> FailableStream<O> stream(final Collection<O> collection) {
560 return new FailableStream<>(collection.stream());
561 }
562
563 /**
564 * Converts the given stream into a {@link FailableStream}. The {@link FailableStream} consists of the same
565 * elements, than the input stream. However, failable lambdas, like {@link FailablePredicate},
566 * {@link FailableFunction}, and {@link FailableConsumer} may be applied, rather than {@link Predicate},
567 * {@link Function}, {@link Consumer}, etc.
568 *
569 * @param stream The stream, which is being converted into a {@link FailableStream}.
570 * @param <O> The streams element type.
571 * @return The created {@link FailableStream}.
572 * @since 3.10
573 */
574 public static <O> FailableStream<O> stream(final Stream<O> stream) {
575 return new FailableStream<>(stream);
576 }
577
578 /**
579 * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
580 *
581 * @param predicate the predicate to test
582 * @param object1 the first input to test by {@code predicate}
583 * @param object2 the second input to test by {@code predicate}
584 * @param <O1> the type of the first argument the predicate tests
585 * @param <O2> the type of the second argument the predicate tests
586 * @param <T> the type of checked exception the predicate may throw
587 * @return the boolean value returned by the predicate
588 */
589 public static <O1, O2, T extends Throwable> boolean test(final FailableBiPredicate<O1, O2, T> predicate,
590 final O1 object1, final O2 object2) {
591 return getAsBoolean(() -> predicate.test(object1, object2));
592 }
593
594 /**
595 * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
596 *
597 * @param predicate the predicate to test
598 * @param object the input to test by {@code predicate}
599 * @param <O> the type of argument the predicate tests
600 * @param <T> the type of checked exception the predicate may throw
601 * @return the boolean value returned by the predicate
602 */
603 public static <O, T extends Throwable> boolean test(final FailablePredicate<O, T> predicate, final O object) {
604 return getAsBoolean(() -> predicate.test(object));
605 }
606
607 /**
608 * A simple try-with-resources implementation, that can be used, if your objects do not implement the
609 * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
610 * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
611 * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
612 * {@link Throwable}) is rethrown. Example use:
613 *
614 * <pre>
615 * {@code
616 * final FileInputStream fis = new FileInputStream("my.file");
617 * Functions.tryWithResources(useInputStream(fis), null, () -> fis.close());
618 * }</pre>
619 *
620 * @param action The action to execute. This object <em>will</em> always be invoked.
621 * @param errorHandler An optional error handler, which will be invoked finally, if any error occurred. The error
622 * handler will receive the first error, AKA {@link Throwable}.
623 * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
624 * order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
625 * @see #tryWithResources(FailableRunnable, FailableRunnable...)
626 */
627 @SafeVarargs
628 public static void tryWithResources(final FailableRunnable<? extends Throwable> action,
629 final FailableConsumer<Throwable, ? extends Throwable> errorHandler,
630 final FailableRunnable<? extends Throwable>... resources) {
631 final org.apache.commons.lang3.function.FailableRunnable<?>[] fr = new org.apache.commons.lang3.function.FailableRunnable[resources.length];
632 Arrays.setAll(fr, i -> () -> resources[i].run());
633 Failable.tryWithResources(action::run, errorHandler != null ? errorHandler::accept : null, fr);
634 }
635
636 /**
637 * A simple try-with-resources implementation, that can be used, if your objects do not implement the
638 * {@link AutoCloseable} interface. The method executes the {@code action}. The method guarantees, that <em>all</em>
639 * the {@code resources} are being executed, in the given order, afterwards, and regardless of success, or failure.
640 * If either the original action, or any of the resource action fails, then the <em>first</em> failure (AKA
641 * {@link Throwable}) is rethrown. Example use:
642 *
643 * <pre>
644 * {@code
645 * final FileInputStream fis = new FileInputStream("my.file");
646 * Functions.tryWithResources(useInputStream(fis), () -> fis.close());
647 * }</pre>
648 *
649 * @param action The action to execute. This object <em>will</em> always be invoked.
650 * @param resources The resource actions to execute. <em>All</em> resource actions will be invoked, in the given
651 * order. A resource action is an instance of {@link FailableRunnable}, which will be executed.
652 * @see #tryWithResources(FailableRunnable, FailableConsumer, FailableRunnable...)
653 */
654 @SafeVarargs
655 public static void tryWithResources(final FailableRunnable<? extends Throwable> action,
656 final FailableRunnable<? extends Throwable>... resources) {
657 tryWithResources(action, null, resources);
658 }
659
660 /**
661 * Constructs a new instance.
662 */
663 public Functions() {
664 // empty
665 }
666 }