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 */
017package org.apache.commons.lang3;
018
019import java.io.IOException;
020import java.io.UncheckedIOException;
021import java.lang.reflect.UndeclaredThrowableException;
022import java.util.Arrays;
023import java.util.Collection;
024import java.util.Objects;
025import java.util.concurrent.Callable;
026import java.util.function.BiConsumer;
027import java.util.function.BiFunction;
028import java.util.function.BiPredicate;
029import java.util.function.Consumer;
030import java.util.function.Function;
031import java.util.function.Predicate;
032import java.util.function.Supplier;
033import java.util.stream.Stream;
034
035import org.apache.commons.lang3.Streams.FailableStream;
036import org.apache.commons.lang3.exception.ExceptionUtils;
037import org.apache.commons.lang3.function.Failable;
038import org.apache.commons.lang3.function.FailableBooleanSupplier;
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, AKA instances of {@link Exception}. This enforces the use of
044 * constructs like:
045 *
046 * <pre>
047 * {@code
048 *     Consumer<java.lang.reflect.Method> consumer = m -> {
049 *         try {
050 *             m.invoke(o, args);
051 *         } catch (Throwable t) {
052 *             throw Functions.rethrow(t);
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 * {@code
064 *   Functions.accept((m) -> m.invoke(o,args));
065 * }</pre>
066 *
067 * <p>
068 * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than the second
069 * version.
070 * </p>
071 *
072 * @since 3.9
073 * @deprecated Use {@link org.apache.commons.lang3.function.Failable}.
074 */
075@Deprecated
076public class Functions {
077
078    /**
079     * A functional interface like {@link BiConsumer} that declares a {@link Throwable}.
080     *
081     * <p>TODO for 4.0: Move to org.apache.commons.lang3.function.</p>
082     *
083     * @param <O1> Consumed type 1.
084     * @param <O2> Consumed type 2.
085     * @param <T> Thrown exception.
086     * @deprecated Use {@link org.apache.commons.lang3.function.FailableBiConsumer}.
087     */
088    @Deprecated
089    @FunctionalInterface
090    public interface FailableBiConsumer<O1, O2, T extends Throwable> {
091
092        /**
093         * Accepts the consumer.
094         *
095         * @param object1 the first parameter for the consumable to accept
096         * @param object2 the second parameter for the consumable to accept
097         * @throws T Thrown when the consumer fails.
098         */
099        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}