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<O>} with a 053 * {@link FailableConsumer FailableConsumer<O,? extends Throwable>}, 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}