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