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