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