    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 *      http://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.Collection;
    023import java.util.Objects;
    024import java.util.concurrent.Callable;
    025import java.util.function.BiConsumer;
    026import java.util.function.BiFunction;
    027import java.util.function.BiPredicate;
    028import java.util.function.Consumer;
    029import java.util.function.Function;
    030import java.util.function.Predicate;
    031import java.util.function.Supplier;
    032import java.util.stream.Stream;
    033
    034import org.apache.commons.lang3.Streams.FailableStream;
    035
    036
    037/** This class provides utility functions, and classes for working with the
    038 * {@code java.util.function} package, or more generally, with Java 8
    039 * lambdas.
    040 * More specifically, it attempts to address the fact that lambdas are supposed
    041 * not to throw Exceptions, at least not checked Exceptions, aka instances of
    042 * {@link Exception}. This enforces the use of constructs like
    043 * <pre>{@code
    044 *   Consumer<java.lang.reflect.Method> consumer = (m) -> {
    045 *       try {
    046 *           m.invoke(o, args);
    047 *       } catch (Throwable t) {
    048 *           throw Functions.rethrow(t);
    049 *       }
    050 *   };
    051 * }</pre>
    052 * By replacing a {@link java.util.function.Consumer Consumer&lt;O&gt;} with a
    053 * {@link FailableConsumer FailableConsumer&lt;O,? extends Throwable&gt;}, this can be
    054 * written like follows:
    055 * <pre>{@code
    056 *   Functions.accept((m) -> m.invoke(o,args));
    057 * }</pre>
    058 * Obviously, the second version is much more concise and the spirit of
    059 * Lambda expressions is met better than the second version.
    060 */
    061public class Functions {
    062
    063    @FunctionalInterface
    064    public interface FailableRunnable<T extends Throwable> {
    065        /**
    066         * Runs the function.
    067         * @throws T if the function fails
    068         */
    069        void run() throws T;
    070    }
    071
    072    @FunctionalInterface
    073    public interface FailableCallable<O, T extends Throwable> {
    074        /**
    075         * Calls the callable.
    076         * @return The value returned from the callable
    077         * @throws T if the callable fails
    078         */
    079        O call() throws T;
    080    }
    081
    082    @FunctionalInterface
    083    public interface FailableConsumer<O, T extends Throwable> {
    084        /**
    085         * Accepts the consumer.
    086         * @param object the parameter for the consumable to accept
    087         * @throws T if the consumer fails
    088         */
    089        void accept(O object) throws T;
    090    }
    091
    092    @FunctionalInterface
    093    public interface FailableBiConsumer<O1, O2, T extends Throwable> {
    094        /**
    095         * Accepts the consumer.
    096         * @param object1 the first parameter for the consumable to accept
    097         * @param object2 the second parameter for the consumable to accept
    098         * @throws T if the consumer fails
    099         */
    100        void accept(O1 object1, O2 object2) throws T;
    101    }
    102
    103    @FunctionalInterface
    104    public interface FailableFunction<I, O, T extends Throwable> {
    105        /**
    106         * Apply the function.
    107         * @param input the input for the function
    108         * @return the result of the function
    109         * @throws T if the function fails
    110         */
    111        O apply(I input) throws T;
    112    }
    113
    114    @FunctionalInterface
    115    public interface FailableBiFunction<I1, I2, O, T extends Throwable> {
    116        /**
    117         * Apply the function.
    118         * @param input1 the first input for the function
    119         * @param input2 the second input for the function
    120         * @return the result of the function
    121         * @throws T if the function fails
    122         */
    123        O apply(I1 input1, I2 input2) throws T;
    124    }
    125
    126    @FunctionalInterface
    127    public interface FailablePredicate<O, T extends Throwable> {
    128        /**
    129         * Test the predicate.
    130         * @param object the object to test the predicate on
    131         * @return the predicate's evaluation
    132         * @throws T if the predicate fails
    133         */
    134        boolean test(O object) throws T;
    135    }
    136
    137    @FunctionalInterface
    138    public interface FailableBiPredicate<O1, O2, T extends Throwable> {
    139        /**
    140         * Test the predicate.
    141         * @param object1 the first object to test the predicate on
    142         * @param object2 the second object to test the predicate on
    143         * @return the predicate's evaluation
    144         * @throws T if the predicate fails
    145         */
    146        boolean test(O1 object1, O2 object2) throws T;
    147    }
    148
    149    @FunctionalInterface
    150    public interface FailableSupplier<O, T extends Throwable> {
    151        /**
    152         * Supplies an object
    153         * @return the suppliers result
    154         * @throws T if the supplier fails
    155         */
    156        O get() throws T;
    157    }
    158
    159    /**
    160     * Converts the given {@link FailableRunnable} into a standard {@link Runnable}.
    161     *
    162     * @param runnable a {@code FailableRunnable}
    163     * @return a standard {@code Runnable}
    164     */
    165    public static Runnable asRunnable(final FailableRunnable<?> runnable) {
    166        return () -> run(runnable);
    167    }
    168
    169    /**
    170     * Converts the given {@link FailableConsumer} into a standard {@link Consumer}.
    171     *
    172     * @param <I> the type used by the consumers
    173     * @param consumer a {@code FailableConsumer}
    174     * @return a standard {@code Consumer}
    175     */
    176    public static <I> Consumer<I> asConsumer(final FailableConsumer<I, ?> consumer) {
    177        return input -> accept(consumer, input);
    178    }
    179
    180    /**
    181     * Converts the given {@link FailableCallable} into a standard {@link Callable}.
    182     *
    183     * @param <O> the type used by the callables
    184     * @param callable a {@code FailableCallable}
    185     * @return a standard {@code Callable}
    186     */
    187    public static <O> Callable<O> asCallable(final FailableCallable<O, ?> callable) {
    188        return () -> call(callable);
    189    }
    190
    191    /**
    192     * Converts the given {@link FailableBiConsumer} into a standard {@link BiConsumer}.
    193     *
    194     * @param <I1> the type of the first argument of the consumers
    195     * @param <I2> the type of the second argument of the consumers
    196     * @param consumer a failable {@code BiConsumer}
    197     * @return a standard {@code BiConsumer}
    198     */
    199    public static <I1, I2> BiConsumer<I1, I2> asBiConsumer(final FailableBiConsumer<I1, I2, ?> consumer) {
    200        return (input1, input2) -> accept(consumer, input1, input2);
    201    }
    202
    203    /**
    204     * Converts the given {@link FailableFunction} into a standard {@link Function}.
    205     *
    206     * @param <I> the type of the input of the functions
    207     * @param <O> the type of the output of the functions
    208     * @param function a {code FailableFunction}
    209     * @return a standard {@code Function}
    210     */
    211    public static <I, O> Function<I, O> asFunction(final FailableFunction<I, O, ?> function) {
    212        return input -> apply(function, input);
    213    }
    214
    215    /**
    216     * Converts the given {@link FailableBiFunction} into a standard {@link BiFunction}.
    217     *
    218     * @param <I1> the type of the first argument of the input of the functions
    219     * @param <I2> the type of the second argument of the input of the functions
    220     * @param <O> the type of the output of the functions
    221     * @param function a {@code FailableBiFunction}
    222     * @return a standard {@code BiFunction}
    223     */
    224    public static <I1, I2, O> BiFunction<I1, I2, O> asBiFunction(final FailableBiFunction<I1, I2, O, ?> function) {
    225        return (input1, input2) -> apply(function, input1, input2);
    226    }
    227
    228    /**
    229     * Converts the given {@link FailablePredicate} into a standard {@link Predicate}.
    230     *
    231     * @param <I> the type used by the predicates
    232     * @param predicate a {@code FailablePredicate}
    233     * @return a standard {@code Predicate}
    234     */
    235    public static <I> Predicate<I> asPredicate(final FailablePredicate<I, ?> predicate) {
    236        return input -> test(predicate, input);
    237    }
    238
    239    /**
    240     * Converts the given {@link FailableBiPredicate} into a standard {@link BiPredicate}.
    241     *
    242     * @param <I1> the type of the first argument used by the predicates
    243     * @param <I2> the type of the second argument used by the predicates
    244     * @param predicate a {@code FailableBiPredicate}
    245     * @return a standard {@code BiPredicate}
    246     */
    247    public static <I1, I2> BiPredicate<I1, I2> asBiPredicate(final FailableBiPredicate<I1, I2, ?> predicate) {
    248        return (input1, input2) -> test(predicate, input1, input2);
    249    }
    250
    251    /**
    252     * Converts the given {@link FailableSupplier} into a standard {@link Supplier}.
    253     *
    254     * @param <O> the type supplied by the suppliers
    255     * @param supplier a {@code FailableSupplier}
    256     * @return a standard {@code Supplier}
    257     */
    258    public static <O> Supplier<O> asSupplier(final FailableSupplier<O, ?> supplier) {
    259        return () -> get(supplier);
    260    }
    261
    262    /**
    263     * Runs a runnable and rethrows any exception as a {@link RuntimeException}.
    264     * @param runnable The runnable to run
    265     * @param <T> the type of checked exception the runnable may throw
    266     */
    267    public static <T extends Throwable> void run(final FailableRunnable<T> runnable) {
    268        try {
    269            runnable.run();
    270        } catch (final Throwable t) {
    271            throw rethrow(t);
    272        }
    273    }
    274
    275    /**
    276     * Calls a callable and rethrows any exception as a {@link RuntimeException}.
    277     * @param callable the callable to call
    278     * @param <O> the return type of the callable
    279     * @param <T> the type of checked exception the callable may throw
    280     * @return the value returned from the callable
    281     */
    282    public static <O, T extends Throwable> O call(final FailableCallable<O, T> callable) {
    283        return get(callable::call);
    284    }
    285
    286    /**
    287     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    288     * @param consumer the consumer to consume
    289     * @param object the object to consume by {@code consumer}
    290     * @param <O> the type the consumer accepts
    291     * @param <T> the type of checked exception the consumer may throw
    292     */
    293    public static <O, T extends Throwable> void accept(final FailableConsumer<O, T> consumer, final O object) {
    294        run(() -> consumer.accept(object));
    295    }
    296
    297    /**
    298     * Consumes a consumer and rethrows any exception as a {@link RuntimeException}.
    299     * @param consumer the consumer to consume
    300     * @param object1 the first object to consume by {@code consumer}
    301     * @param object2 the second object to consume by {@code consumer}
    302     * @param <O1> the type of the first argument the consumer accepts
    303     * @param <O2> the type of the second argument the consumer accepts
    304     * @param <T> the type of checked exception the consumer may throw
    305     */
    306    public static <O1, O2, T extends Throwable> void accept(final FailableBiConsumer<O1, O2, T> consumer, final O1 object1, final O2 object2) {
    307        run(() -> consumer.accept(object1, object2));
    308    }
    309
    310    /**
    311     * Applies a function and rethrows any exception as a {@link RuntimeException}.
    312     * @param function the function to apply
    313     * @param input the input to apply {@code function} on
    314     * @param <I> the type of the argument the function accepts
    315     * @param <O> the return type of the function
    316     * @param <T> the type of checked exception the function may throw
    317     * @return the value returned from the function
    318     */
    319    public static <I, O, T extends Throwable> O apply(final FailableFunction<I, O, T> function, final I input) {
    320        return get(() -> function.apply(input));
    321    }
    322
    323    /**
    324     * Applies a function and rethrows any exception as a {@link RuntimeException}.
    325     * @param function the function to apply
    326     * @param input1 the first input to apply {@code function} on
    327     * @param input2 the second input to apply {@code function} on
    328     * @param <I1> the type of the first argument the function accepts
    329     * @param <I2> the type of the second argument the function accepts
    330     * @param <O> the return type of the function
    331     * @param <T> the type of checked exception the function may throw
    332     * @return the value returned from the function
    333     */
    334    public static <I1, I2, O, T extends Throwable> O apply(final FailableBiFunction<I1, I2, O, T> function, final I1 input1, final I2 input2) {
    335        return get(() -> function.apply(input1, input2));
    336    }
    337
    338    /**
    339     * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
    340     * @param predicate the predicate to test
    341     * @param object the input to test by {@code predicate}
    342     * @param <O> the type of argument the predicate tests
    343     * @param <T> the type of checked exception the predicate may throw
    344     * @return the boolean value returned by the predicate
    345     */
    346    public static <O, T extends Throwable> boolean test(final FailablePredicate<O, T> predicate, final O object) {
    347        return get(() -> predicate.test(object));
    348    }
    349
    350    /**
    351     * Tests a predicate and rethrows any exception as a {@link RuntimeException}.
    352     * @param predicate the predicate to test
    353     * @param object1 the first input to test by {@code predicate}
    354     * @param object2 the second input to test by {@code predicate}
    355     * @param <O1> the type of the first argument the predicate tests
    356     * @param <O2> the type of the second argument the predicate tests
    357     * @param <T> the type of checked exception the predicate may throw
    358     * @return the boolean value returned by the predicate
    359     */
    360    public static <O1, O2, T extends Throwable> boolean test(final FailableBiPredicate<O1, O2, T> predicate, final O1 object1, final O2 object2) {
    361        return get(() -> predicate.test(object1, object2));
    362    }
    363
    364    /**
    365     * Invokes the supplier, and returns the result.
    366     * @param supplier The supplier to invoke.
    367     * @param <O> The suppliers output type.
    368     * @param <T> The type of checked exception, which the supplier can throw.
    369     * @return The object, which has been created by the supplier
    370     */
    371    public static <O, T extends Throwable> O get(final FailableSupplier<O, T> supplier) {
    372        try {
    373            return supplier.get();
    374        } catch (final Throwable t) {
    375            throw rethrow(t);
    376        }
    377    }
    378
    379    /**
    380     * Converts the given stream into a {@link FailableStream}. The
    381     * {@link FailableStream} consists of the same elements, than the
    382     * input stream. However, failable lambdas, like
    383     * {@link FailablePredicate}, {@link FailableFunction}, and
    384     * {@link FailableConsumer} may be applied, rather than
    385     * {@link Predicate}, {@link Function}, {@link Consumer}, etc.
    386     * @param stream The stream, which is being converted into a
    387     *   {@link FailableStream}.
    388     * @param <O> The streams element type.
    389     * @return The created {@link FailableStream}.
    390     */
    391    public static <O> FailableStream<O> stream(final Stream<O> stream) {
    392        return new FailableStream<>(stream);
    393    }
    394
    395    /**
    396     * Converts the given collection into a {@link FailableStream}.
    397     * The {@link FailableStream} consists of the collections
    398     * elements. Shortcut for
    399     * <pre>
    400     *   Functions.stream(collection.stream());
    401     * </pre>
    402     * @param collection The collection, which is being converted into a
    403     *   {@link FailableStream}.
    404     * @param <O> The collections element type. (In turn, the result
    405     *   streams element type.)
    406     * @return The created {@link FailableStream}.
    407     */
    408    public static <O> FailableStream<O> stream(final Collection<O> collection) {
    409        return new FailableStream<>(collection.stream());
    410    }
    411
    412
    413    /**
    414     * A simple try-with-resources implementation, that can be used, if your
    415     * objects do not implement the {@link AutoCloseable} interface. The method
    416     * executes the {@code action}. The method guarantees, that <em>all</em>
    417     * the {@code resources} are being executed, in the given order, afterwards,
    418     * and regardless of success, or failure. If either the original action, or
    419     * any of the resource action fails, then the <em>first</em> failure (aka
    420     * {@link Throwable} is rethrown. Example use:
    421     * <pre>{@code
    422     *   final FileInputStream fis = new FileInputStream("my.file");
    423     *   Functions.tryWithResources(useInputStream(fis), null, () -> fis.close());
    424     * }</pre>
    425     * @param action The action to execute. This object <em>will</em> always
    426     *   be invoked.
    427     * @param errorHandler An optional error handler, which will be invoked finally,
    428     *   if any error occurred. The error handler will receive the first
    429     *   error, aka {@link Throwable}.
    430     * @param resources The resource actions to execute. <em>All</em> resource
    431     *   actions will be invoked, in the given order. A resource action is an
    432     *   instance of {@link FailableRunnable}, which will be executed.
    433     * @see #tryWithResources(FailableRunnable, FailableRunnable...)
    434     */
    435    @SafeVarargs
    436    public static void tryWithResources(final FailableRunnable<? extends Throwable> action,
    437                                            final FailableConsumer<Throwable, ? extends Throwable> errorHandler,
    438                                            final FailableRunnable<? extends Throwable>... resources) {
    439        final FailableConsumer<Throwable, ? extends Throwable> actualErrorHandler;
    440        if (errorHandler == null) {
    441            actualErrorHandler = Functions::rethrow;
    442        } else {
    443            actualErrorHandler = errorHandler;
    444        }
    445        if (resources != null) {
    446            for (final FailableRunnable<? extends Throwable> failableRunnable : resources) {
    447                Objects.requireNonNull(failableRunnable, "runnable");
    448            }
    449        }
    450        Throwable th = null;
    451        try {
    452            action.run();
    453        } catch (final Throwable t) {
    454            th = t;
    455        }
    456        if (resources != null) {
    457            for (final FailableRunnable<?> runnable : resources) {
    458                try {
    459                    runnable.run();
    460                } catch (final Throwable t) {
    461                    if (th == null) {
    462                        th = t;
    463                    }
    464                }
    465            }
    466        }
    467        if (th != null) {
    468            try {
    469                actualErrorHandler.accept(th);
    470            } catch (final Throwable t) {
    471                throw rethrow(t);
    472            }
    473        }
    474    }
    475
    476    /**
    477     * A simple try-with-resources implementation, that can be used, if your
    478     * objects do not implement the {@link AutoCloseable} interface. The method
    479     * executes the {@code action}. The method guarantees, that <em>all</em>
    480     * the {@code resources} are being executed, in the given order, afterwards,
    481     * and regardless of success, or failure. If either the original action, or
    482     * any of the resource action fails, then the <em>first</em> failure (aka
    483     * {@link Throwable} is rethrown. Example use:
    484     * <pre>{@code
    485     *   final FileInputStream fis = new FileInputStream("my.file");
    486     *   Functions.tryWithResources(useInputStream(fis), () -> fis.close());
    487     * }</pre>
    488     * @param action The action to execute. This object <em>will</em> always
    489     *   be invoked.
    490     * @param resources The resource actions to execute. <em>All</em> resource
    491     *   actions will be invoked, in the given order. A resource action is an
    492     *   instance of {@link FailableRunnable}, which will be executed.
    493     * @see #tryWithResources(FailableRunnable, FailableConsumer, FailableRunnable...)
    494     */
    495    @SafeVarargs
    496    public static void tryWithResources(final FailableRunnable<? extends Throwable> action,
    497                                            final FailableRunnable<? extends Throwable>... resources) {
    498        tryWithResources(action, null, resources);
    499    }
    500
    501    /**
    502     * <p>Rethrows a {@link Throwable} as an unchecked exception. If the argument is
    503     * already unchecked, namely a {@code RuntimeException} or {@code Error} then
    504     * the argument will be rethrown without modification. If the exception is
    505     * {@code IOException} then it will be wrapped into a {@code UncheckedIOException}.
    506     * In every other cases the exception will be wrapped into a {@code
    507     * UndeclaredThrowableException}</p>
    508     *
    509     * <p>Note that there is a declared return type for this method, even though it
    510     * never returns. The reason for that is to support the usual pattern:</p>
    511     *
    512     * <pre>
    513     *      throw rethrow(myUncheckedException);
    514     * </pre>
    515     *
    516     * <p>instead of just calling the method. This pattern may help the Java compiler to
    517     * recognize that at that point an exception will be thrown and the code flow
    518     * analysis will not demand otherwise mandatory commands that could follow the
    519     * method call, like a {@code return} statement from a value returning method.</p>
    520     *
    521     * @param throwable The throwable to rethrow ossibly 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        if (throwable instanceof RuntimeException) {
    527            throw (RuntimeException) throwable;
    528        } else if (throwable instanceof Error) {
    529            throw (Error) throwable;
    530        } else if (throwable instanceof IOException) {
    531            throw new UncheckedIOException((IOException) throwable);
    532        } else {
    533            throw new UndeclaredThrowableException(throwable);
    534        }
    535    }
    536}