001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2022–2023 microBean™. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 012 * specific language governing permissions and limitations under the License. 013 */ 014package org.microbean.invoke; 015 016import java.util.NoSuchElementException; 017import java.util.Optional; 018 019import java.util.function.BiFunction; 020import java.util.function.Consumer; 021import java.util.function.Function; 022import java.util.function.Supplier; 023 024import java.util.stream.Stream; 025 026/** 027 * A {@link Supplier} with additional contractual requirements. 028 * 029 * <p><strong>An {@link OptionalSupplier} does not behave like an 030 * {@link Optional} or a {@link 031 * java.util.concurrent.CompletableFuture},</strong> despite the 032 * deliberate similarities of some method names.</p> 033 * 034 * <p>An implementation of this interface is not a <a 035 * href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/doc-files/ValueBased.html">value-based 036 * class</a>.</p> 037 * 038 * @param <T> the type of value implementations of this interface 039 * {@linkplain #get() supply} 040 * 041 * @author <a href="https://about.me/lairdnelson" 042 * target="_parent">Laird Nelson</a> 043 * 044 * @see #determinism() 045 * 046 * @see #get() 047 * 048 * @see #optional() 049 */ 050@FunctionalInterface 051public interface OptionalSupplier<T> extends Supplier<T> { 052 053 /** 054 * Returns either the result of invoking the {@link #get()} method, 055 * if a {@link RuntimeException} does not occur, or the result of 056 * invoking the {@link Function#apply(Object) apply(Object)} method 057 * on the supplied {@code handler} with any {@link RuntimeException} 058 * that does occur, including {@link NoSuchElementException} and 059 * {@link UnsupportedOperationException} instances that are used to 060 * indicate value absence. 061 * 062 * @param handler the exception handler; must not be {@code null} 063 * 064 * @return either the result of invoking the {@link #get()} method, 065 * if a {@link RuntimeException} does not occur, or the result of 066 * invoking the {@link Function#apply(Object) apply(Object)} method 067 * on the supplied {@code handler} with any {@link RuntimeException} 068 * that does occur 069 * 070 * @exception NullPointerException if {@code handler} is {@code 071 * null} 072 * 073 * @nullability This method and its (discouraged) overrides may 074 * return {@code null} 075 * 076 * @idempotency No guarantees are made about idempotency or 077 * determinism. 078 * 079 * @threadsafety This method itself is, and its (discouraged) 080 * overrides must be, safe for concurrent use by multiple threads, 081 * but the {@link Function#apply(Object) apply(Object)} method of 082 * the supplied {@code handler} may not be. 083 * 084 * @see #get() 085 */ 086 public default T exceptionally(final Function<? super RuntimeException, ? extends T> handler) { 087 try { 088 return this.get(); 089 } catch (final RuntimeException e) { 090 try { 091 return handler.apply(e); 092 } catch (final RuntimeException r) { 093 r.addSuppressed(e); 094 throw r; 095 } 096 } 097 } 098 099 /** 100 * Returns a value, which may be {@code null}. 101 * 102 * <p>This method's contract extends {@link Supplier#get()}'s 103 * contract with the following additional requirements:</p> 104 * 105 * <ul> 106 * 107 * <li><strong>It is deliberately and explicitly permitted for 108 * implementations of this method to return {@code null} for any 109 * reason.</strong> Callers of this method must be appropriately 110 * prepared.</li> 111 * 112 * <li>If an invocation of the {@link #determinism()} method, on any 113 * thread, returns any of {@link Determinism#ABSENT}, {@link 114 * Determinism#DETERMINISTIC} or {@link Determinism#PRESENT}, then 115 * additional requirements apply to the implementation of this 116 * method; see the {@link #determinism()} method documentation for 117 * details.</li> 118 * 119 * <li>An implementation of this method need not be deterministic if 120 * an invocation of the {@link #determinism()} method returns {@link 121 * Determinism#NON_DETERMINISTIC}.</li> 122 * 123 * <li>An implementation of this method may indicate the (possibly 124 * transitory) absence of a value by any of the following means: 125 * 126 * <ul> 127 * 128 * <li>Throwing a {@link NoSuchElementException}.</li> 129 * 130 * <li>Throwing an {@link UnsupportedOperationException}.</li> 131 * 132 * </ul></li> 133 * 134 * </ul> 135 * 136 * @return a value, which may be {@code null} 137 * 138 * @exception NoSuchElementException to indicate (usually 139 * transitory) absence 140 * 141 * @exception UnsupportedOperationException to indicate (usually 142 * permanent) absence 143 * 144 * @nullability Implementations of this method may, and often will, 145 * return {@code null}, even in the normal course of events. 146 * 147 * @threadsafety Implementations of this method must be safe for 148 * concurrent use by multiple threads. 149 * 150 * @idempotency No guarantees are made about idempotency or 151 * determinism. An ideal implementation should be idempotent. If 152 * the {@link #determinism() determinism()} method returns a {@link 153 * Determinism} that is not {@link Determinism#NON_DETERMINISTIC}, then any 154 * implementation of this method must be deterministic. 155 * 156 * @see #determinism() 157 */ 158 @Override 159 public T get(); 160 161 /** 162 * Returns the result of invoking the {@link 163 * BiFunction#apply(Object, Object) apply(Object, Object)} method on 164 * the supplied {@code handler}, supplying it with the result of an 165 * invocation of the {@link #get()} method, which may be {@code 166 * null}, or any {@link RuntimeException} that an invocation of the 167 * {@link #get()} method throws, including {@link 168 * NoSuchElementException} and {@link UnsupportedOperationException} 169 * instances that are used to indicate value absence. 170 * 171 * <p>The first argument to the handler will be the return value of 172 * the {@link #get()} method, which may be {@code null}. The second 173 * argument to the handler will be any {@link RuntimeException} that 174 * was thrown during the invocation of the {@link #get()} method, 175 * including {@link NoSuchElementException} and {@link 176 * UnsupportedOperationException} instances that are used to 177 * indicate value absence.</p> 178 * 179 * @param <U> the type of the value returned 180 * 181 * @param handler the handler; must not be {@code null} 182 * 183 * @return the result of invoking the {@link 184 * BiFunction#apply(Object, Object) apply(Object, Object)} method on 185 * the supplied {@code handler}, supplying it with the result of an 186 * invocation of the {@link #get()} method, which may be {@code 187 * null}, or any {@link RuntimeException} that an invocation of the 188 * {@link #get()} method throws, including {@link 189 * NoSuchElementException} and {@link UnsupportedOperationException} 190 * instances that are used to indicate value absence 191 * 192 * @exception NullPointerException if {@code handler} is {@code 193 * null} 194 * 195 * @nullability This method and its (discouraged) overrides may 196 * return {@code null}. 197 * 198 * @threadsafety This method is, and its (discouraged) overrides 199 * must be, safe for concurrent use by multiple threads. 200 * 201 * @idempotency No guarantees are made about idempotency or 202 * determinism. 203 * 204 * @see #get() 205 */ 206 public default <U> U handle(final BiFunction<? super T, ? super RuntimeException, ? extends U> handler) { 207 final T value; 208 try { 209 value = this.get(); 210 } catch (final RuntimeException e) { 211 try { 212 return handler.apply(null, e); 213 } catch (final RuntimeException r) { 214 r.addSuppressed(e); 215 throw r; 216 } 217 } 218 return handler.apply(value, null); 219 } 220 221 /** 222 * Invokes the {@link Consumer#accept(Object) accept(Object)} method 223 * on the supplied {@code action} with the return value of an 224 * invocation of the {@link #get()} method, which may be {@code 225 * null}, unless the {@link #get()} method throws either a {@link 226 * NoSuchElementException} or an {@link 227 * UnsupportedOperationException}, indicating value absence, in 228 * which case no action is taken. 229 * 230 * @param action the {@link Consumer} representing the action to 231 * take; must not be {@code null} 232 * 233 * @exception NullPointerException if {@code action} is {@code null} 234 * 235 * @idempotency No guarantees are made about idempotency or 236 * determinism. 237 * 238 * @threadsafety This method is, and its (discouraged) overrides 239 * must be, safe for concurrent use by multiple threads, but the 240 * supplied {@link Consumer}'s {@link Consumer#accept(Object) 241 * accept(Object)} method may not be 242 * 243 * @see #get() 244 */ 245 public default void ifPresent(final Consumer<? super T> action) { 246 final T value; 247 try { 248 value = this.get(); 249 } catch (final NoSuchElementException | UnsupportedOperationException e) { 250 return; 251 } 252 action.accept(value); 253 } 254 255 /** 256 * Invokes the {@link Consumer#accept(Object) accept(Object)} method 257 * on the supplied {@code presentAction} with the return value of an 258 * invocation of the {@link #get()} method, which may be {@code 259 * null}, or, if the {@link #get()} method indicates value absence 260 * by throwing either a {@link NoSuchElementException} or an {@link 261 * UnsupportedOperationException}, invokes the {@link Runnable#run() 262 * run()} method of the supplied {@code absentAction} instead. 263 * 264 * @param presentAction the {@link Consumer} representing the action 265 * to take if a value is present; must not be {@code null} 266 * 267 * @param absentAction the {@link Runnable} representing the action 268 * to take if a value is absent; must not be {@code null} 269 * 270 * @exception NullPointerException if {@code action} or {@code 271 * absentAction} is {@code null} 272 * 273 * @idempotency No guarantees are made about idempotency or 274 * determinism. 275 * 276 * @threadsafety This method is, and its (discouraged) overrides 277 * must be, safe for concurrent use by multiple threads, but the 278 * supplied {@link Consumer}'s {@link Consumer#accept(Object) 279 * accept(Object)} method may not be and the supplied {@link 280 * Runnable}'s {@link Runnable#run() run()} method may not be 281 * 282 * @see #get() 283 */ 284 public default void ifPresentOrElse(final Consumer<? super T> presentAction, final Runnable absentAction) { 285 final T value; 286 try { 287 value = this.get(); 288 } catch (final NoSuchElementException | UnsupportedOperationException e) { 289 try { 290 absentAction.run(); 291 return; 292 } catch (final RuntimeException r) { 293 r.addSuppressed(e); 294 throw r; 295 } 296 } 297 presentAction.accept(value); 298 } 299 300 /** 301 * Returns a non-{@code null} but possibly {@linkplain 302 * Optional#isEmpty() empty} {@link Optional} representing this 303 * {@link OptionalSupplier}'s {@linkplain #get() value}. 304 * 305 * <p>The default implementation of this method does not and its 306 * overrides must not return {@code null}.</p> 307 * 308 * <p>The default implementation of this method catches all {@link 309 * NoSuchElementException}s and {@link 310 * UnsupportedOperationException}s and returns an empty {@link 311 * Optional} in these cases, which may not be valid for some use 312 * cases. To detect permanent versus transitory absence, potential 313 * callers should use the {@link #get()} method directly or either 314 * the {@link #optional(Function)} or {@link #optional(BiFunction)} 315 * methods.</p> 316 * 317 * @return a non-{@code null} but possibly {@linkplain 318 * Optional#isEmpty() empty} {@link Optional} representing this 319 * {@link OptionalSupplier}'s {@linkplain #get() value} 320 * 321 * @nullability The default implementation of this method does not, 322 * and its (discouraged) overrides must not, return {@code null}. 323 * 324 * @threadsafety The default implementation of this method is, and 325 * its (discouraged) overrides must be, safe for concurrent use by 326 * multiple threads. 327 * 328 * @idempotency No guarantees are made about idempotency or 329 * determinism. 330 * 331 * @see #optional(BiFunction) 332 * 333 * @see #get() 334 */ 335 public default Optional<T> optional() { 336 return this.optional(OptionalSupplier::returnNull); 337 } 338 339 /** 340 * Invokes the {@link #handle(BiFunction)} method, supplying it with 341 * the supplied {@code handler}, supplies its return value to the 342 * {@link Optional#ofNullable(Object)} method, and returns the 343 * result. 344 * 345 * @param <U> the type of the returned {@link Optional} 346 * 347 * @param handler the handler; must not be {@code null} 348 * 349 * @return the result of invoking the {@link 350 * Optional#ofNullable(Object)} method supplied with the return 351 * value of invoking the {@link #handle(BiFunction)} method with the 352 * supplied {@code handler} 353 * 354 * @exception NullPointerException if {@code handler} is {@code 355 * null} 356 * 357 * @nullability This method does not, and its (discouraged) 358 * overrides must not, return {@code null}. 359 * 360 * @idempotency No guarantees are made about idempotency or 361 * determinism. 362 * 363 * @threadsafety This method is, and its (discouraged) overrides 364 * must be, safe for concurrent use by multiple threads. 365 * 366 * @see #handle(BiFunction) 367 * 368 * @see Optional#ofNullable(Object) 369 */ 370 public default <U> Optional<U> optional(final BiFunction<? super T, ? super RuntimeException, ? extends U> handler) { 371 return Optional.ofNullable(this.handle(handler)); 372 } 373 374 /** 375 * Invokes the {@link #exceptionally(Function)} method, supplying it 376 * with the supplied {@code handler}, supplies its return value to 377 * the {@link Optional#ofNullable(Object)} method, and returns the 378 * result. 379 * 380 * @param handler the handler; must not be {@code null} 381 * 382 * @return the result of invoking the {@link 383 * Optional#ofNullable(Object)} method supplied with the return 384 * value of invoking the {@link #exceptionally(Function)} method 385 * with the supplied {@code handler} 386 * 387 * @exception NullPointerException if {@code handler} is {@code 388 * null} 389 * 390 * @nullability This method does not, and its (discouraged) 391 * overrides must not, return {@code null}. 392 * 393 * @idempotency No guarantees are made about idempotency or 394 * determinism. 395 * 396 * @threadsafety This method is, and its (discouraged) overrides 397 * must be, safe for concurrent use by multiple threads. 398 * 399 * @see #exceptionally(Function) 400 * 401 * @see Optional#ofNullable(Object) 402 */ 403 public default Optional<T> optional(final Function<? super RuntimeException, ? extends T> handler) { 404 return Optional.ofNullable(this.exceptionally(handler)); 405 } 406 407 /** 408 * Returns the result of invoking the {@link #get()} method, which 409 * may be {@code null}, or, if the {@link #get()} method indicates 410 * value absence by throwing either a {@link NoSuchElementException} 411 * or an {@link UnsupportedOperationException}, returns the supplied 412 * alternate value, which may be {@code null}. 413 * 414 * @param other the alternate value; may be {@code null} 415 * 416 * @return the result of invoking the {@link #get()} method, which 417 * may be {@code null}, or, if the {@link #get()} method indicates 418 * value absence by throwing either a {@link NoSuchElementException} 419 * or an {@link UnsupportedOperationException}, returns the supplied 420 * alternate value, which may be {@code null} 421 * 422 * @nullability This method and its (discouraged) overrides may 423 * return {@code null}. 424 * 425 * @idempotency No guarantees are made about idempotency or 426 * determinism. 427 * 428 * @threadsafety This method is, and its (discouraged) overrides 429 * must be, safe for concurrent use by multiple threads. 430 * 431 * @see #get() 432 */ 433 public default T orElse(final T other) { 434 try { 435 return this.get(); 436 } catch (final NoSuchElementException | UnsupportedOperationException e) { 437 return other; 438 } 439 } 440 441 /** 442 * Returns the result of invoking the {@link #get()} method, which 443 * may be {@code null}, or, if the {@link #get()} method indicates 444 * value absence by throwing either a {@link NoSuchElementException} 445 * or an {@link UnsupportedOperationException}, returns the result 446 * of invoking the {@link #get()} method on the supplied {@link 447 * Supplier}, which may be {@code null}. 448 * 449 * @param supplier the alternate value {@link Supplier}; must not be 450 * {@code null} 451 * 452 * @return the result of invoking the {@link #get()} method, which 453 * may be {@code null}, or, if the {@link #get()} method indicates 454 * value absence by throwing either a {@link NoSuchElementException} 455 * or an {@link UnsupportedOperationException}, returns the result 456 * of invoking the {@link #get()} method on the supplied {@link 457 * Supplier}, which may be {@code null} 458 * 459 * @exception NullPointerException if {@code supplier} is {@code 460 * null} 461 * 462 * @nullability This method and its (discouraged) overrides may 463 * return {@code null}. 464 * 465 * @idempotency No guarantees are made about idempotency or 466 * determinism. 467 * 468 * @threadsafety This method is, and its (discouraged) overrides 469 * msut be, safe for concurrent use by multiple threads, but the 470 * {@link Supplier#get() get()} method of the supplied {@code supplier} 471 * may not be 472 * 473 * @see #get() 474 */ 475 public default T orElseGet(final Supplier<? extends T> supplier) { 476 try { 477 return this.get(); 478 } catch (final NoSuchElementException | UnsupportedOperationException e) { 479 try { 480 return supplier.get(); 481 } catch (final RuntimeException r) { 482 r.addSuppressed(e); 483 throw r; 484 } 485 } 486 } 487 488 /** 489 * Returns the result of invoking the {@link #get()} method, which 490 * may be {@code null}. 491 * 492 * @return the result of invoking the {@link #get()} method, which 493 * may be {@code null} 494 * 495 * @exception NoSuchElementException if value absence was indicated 496 * by the {@link #get()} method 497 * 498 * @nullability This method and its (discouraged) overrides may 499 * return {@code null}. 500 * 501 * @idempotency No guarantees are made about idempotency or 502 * determinism. 503 * 504 * @threadsafety This method is, and its (discouraged) overrides 505 * must be, safe for concurrent use by multiple threads. 506 * 507 * @see #orElseThrow(Supplier) 508 */ 509 public default T orElseThrow() { 510 try { 511 return this.get(); 512 } catch (final UnsupportedOperationException e) { 513 throw new NoSuchElementException(e.getMessage(), e); 514 } 515 } 516 517 /** 518 * Returns the result of invoking the {@link #get()} method, which 519 * may be {@code null}, or, if the {@link #get()} method indicates 520 * value absence by throwing either a {@link NoSuchElementException} 521 * or an {@link UnsupportedOperationException}, throws the return 522 * value of an invocation of the supplied {@link Supplier}'s {@link 523 * Supplier#get() get()} method. 524 * 525 * @param <X> the type of {@link Throwable} the supplied {@code 526 * throwableSupplier} {@linkplain Supplier#get() supplies} 527 * 528 * @param throwableSupplier the {@link Throwable} {@link Supplier}; 529 * must not be {@code null} 530 * 531 * @return the result of invoking the {@link #get()} method, which 532 * may be {@code null}, or, if the {@link #get()} method indicates 533 * value absence by throwing either a {@link NoSuchElementException} 534 * or an {@link UnsupportedOperationException}, throws the return 535 * value of an invocation of the supplied {@link Supplier}'s {@link 536 * Supplier#get() get()} method 537 * 538 * @exception NullPointerException if {@code supplier} is {@code 539 * null} 540 * 541 * @exception X (actually {@code <X>}) if the {@link #get()} method 542 * throws either a {@link NoSuchElementException} or an {@link 543 * UnsupportedOperationException} 544 * 545 * @nullability This method and its (discouraged) overrides may 546 * return {@code null}. 547 * 548 * @idempotency No guarantees are made about idempotency or 549 * determinism. 550 * 551 * @threadsafety This method itself is, and its (discouraged) 552 * overrides must be, safe for concurrent use by multiple threads. 553 * 554 * @see #get() 555 */ 556 public default <X extends Throwable> T orElseThrow(final Supplier<? extends X> throwableSupplier) throws X { 557 try { 558 return this.get(); 559 } catch (final NoSuchElementException | UnsupportedOperationException e) { 560 final X throwable = throwableSupplier.get(); 561 if (throwable.getCause() == null) { 562 throwable.initCause(e); 563 } else { 564 throwable.addSuppressed(e); 565 } 566 throw throwable; 567 } 568 } 569 570 /** 571 * Returns an {@link Determinism} denoting the presence of values 572 * returned by this {@link OptionalSupplier}'s {@link #get() get()} 573 * method. 574 * 575 * <p>Overrides of this method must be compatible with the 576 * implementation of the {@link #get()} method. Specifically:</p> 577 * 578 * <ul> 579 * 580 * <li>If an override of this method returns {@link 581 * Determinism#PRESENT}, then the implementation of the {@link #get()} 582 * method must never throw either a {@link NoSuchElementException} 583 * or an {@link UnsupportedOperationException}, and, for any two 584 * invocations, on any thread, must return either the same object, or 585 * objects that are indistinguishable from one another and that can 586 * be substituted for each other interchangeably.</li> 587 * 588 * <li>If an override of this method returns {@link 589 * Determinism#ABSENT}, then it is expected that any two invocations of 590 * the {@link #get()} method, on any thread, will each throw either 591 * a {@link NoSuchElementException} or an {@link 592 * UnsupportedOperationException}. If an implementation of the 593 * {@link #get()} method instead returns a value, contrary to these 594 * requirements, then the value must be treated as irrelevant or 595 * undefined.</li> 596 * 597 * <li>If an override of this method returns {@link 598 * Determinism#DETERMINISTIC}, then any two invocations of the {@link 599 * #get()} method implementation, on any thread, must either throw 600 * either a {@link NoSuchElementException} or an {@link 601 * UnsupportedOperationException}, or must return either the same 602 * object, or objects that are indistinguishable from one another 603 * and that can be substituted for each other interchangeably.</li> 604 * 605 * <li>If an override of this method returns {@link 606 * Determinism#NON_DETERMINISTIC}, then there are no additional requirements 607 * placed upon the implementation of the {@link #get()} method 608 * besides those defined in {@linkplain #get() its existing 609 * contract}.</li> 610 * 611 * </ul> 612 * 613 * <p>Additionally, once an override of this method returns a {@link 614 * Determinism} whose {@link Determinism#deterministic() deterministic()} 615 * method returns {@code true}, then it must forever afterwards, for 616 * all invocations, on all possible threads, return the same {@link 617 * Determinism}.</p> 618 * 619 * <p>If any of the requirements above is not met, undefined 620 * behavior may result.</p> 621 * 622 * <p>The default implementation of this method returns {@link 623 * Determinism#NON_DETERMINISTIC}. Overrides are strongly encouraged.</p> 624 * 625 * @return an {@link Determinism} denoting the presence of values 626 * returned by this {@link OptionalSupplier}'s {@link #get() get()} 627 * method 628 * 629 * @nullability This method does not, and its (encouraged) overrides 630 * must not, return {@code null}. 631 * 632 * @idempotency This method is idempotent and deterministic. Its 633 * (encouraged) overrides must be idempotent. They may not be 634 * deterministic (see above). 635 * 636 * @threadsafety This method is, and its (encouraged) overrides must 637 * be, safe for concurrent use by multiple threads. 638 */ 639 public default Determinism determinism() { 640 return Determinism.NON_DETERMINISTIC; 641 } 642 643 /** 644 * Returns the result of invoking the {@link Stream#of(Object)} 645 * method on the return value of an invocation of the {@link #get()} 646 * method, which may be {@code null}, or, if the {@link #get()} 647 * method indicates value absence by throwing either a {@link 648 * NoSuchElementException} or an {@link 649 * UnsupportedOperationException}, returns the result of invoking 650 * the {@link Stream#empty()} method. 651 * 652 * <p>Note that this means the sole element of the {@link Stream} 653 * that is returned may be {@code null}. If this is undesirable, 654 * consider invoking {@link Optional#stream() stream()} on the 655 * return value of the {@link #optional()} method instead.</p> 656 * 657 * @return the result of invoking the {@link Stream#of(Object)} 658 * method on the return value of an invocation of the {@link #get()} 659 * method, which may be {@code null}, or, if the {@link #get()} 660 * method indicates value absence by throwing either a {@link 661 * NoSuchElementException} or an {@link 662 * UnsupportedOperationException}, returns the result of invoking 663 * the {@link Stream#empty()} method 664 * 665 * @nullability This method does not, and its (discouraged) 666 * overrides must not, return {@code null}. 667 * 668 * @idempotency No guarantees are made about idempotency or 669 * determinism. 670 * 671 * @threadsafety This method is, and its (discouraged) overrides 672 * must be, safe for concurrent use by multiple threads. 673 * 674 * @see #get() 675 */ 676 public default Stream<T> stream() { 677 try { 678 return Stream.of(this.get()); 679 } catch (final NoSuchElementException | UnsupportedOperationException e) { 680 return Stream.empty(); 681 } 682 } 683 684 685 /* 686 * Static methods. 687 */ 688 689 690 private static <T> T returnNull(final RuntimeException e) { 691 if (e instanceof NoSuchElementException || e instanceof UnsupportedOperationException) { 692 return null; 693 } else { 694 throw e; 695 } 696 } 697 698 /** 699 * Returns a new {@link OptionalSupplier} whose {@link #determinism()} 700 * method will return the supplied {@link Determinism} and whose {@link 701 * #get()} method will return the result of invoking the {@link 702 * Supplier#get()} method on the supplied {@code supplier}. 703 * 704 * @param <T> the type of value the returned {@link 705 * OptionalSupplier} will {@linkplain #get() supply} 706 * 707 * @param determinism the {@link Determinism} to use; must not be {@code null} 708 * 709 * @param supplier the {@link Supplier} whose {@link #get()} method 710 * will be called; must not be {@code null} 711 * 712 * @return a new {@link OptionalSupplier} whose {@link #determinism()} 713 * method will return the supplied {@link Determinism} and whose {@link 714 * #get()} method will return the result of invoking the {@link 715 * Supplier#get()} method on the supplied {@code supplier} 716 * 717 * @exception NullPointerException if {@code determinism} or {@code 718 * supplier} is {@code null} 719 * 720 * @nullability This method never returns {@code null}. 721 * 722 * @idempotency This method is not idempotent but is deterministic. 723 * 724 * @threadsafety This method is safe for concurrent use by multiple 725 * threads. 726 */ 727 public static <T> OptionalSupplier<T> of(final Determinism determinism, final Supplier<? extends T> supplier) { 728 return new OptionalSupplierAdapter<>(determinism, supplier); 729 } 730 731 /** 732 * Invokes {@link Absence#instance()} and returns the result. 733 * 734 * @param <T> the type of the nonexistent value the returned {@link 735 * OptionalSupplier} will never {@linkplain #get() supply} 736 * 737 * @return the result of invoking {@link Absence#instance()} 738 * 739 * @nullability This method never returns {@code null}. 740 * 741 * @idempotency This method is idempotent and deterministic. 742 * 743 * @threadsafety This method is safe for concurrent use by 744 * multiple threads. 745 * 746 * @see Absence#instance() 747 */ 748 public static <T> OptionalSupplier<T> of() { 749 return Absence.instance(); 750 } 751 752 /** 753 * Returns an {@link OptionalSupplier} representing the supplied 754 * {@link Supplier}. 755 * 756 * @param <T> the type of value the returned {@link 757 * OptionalSupplier} will {@linkplain #get() supply} 758 * 759 * @param supplier the {@link Supplier}; may be {@code null} in 760 * which case the return value of an invocation of {@link 761 * Absence#instance()} will be returned 762 * 763 * @return an {@link OptionalSupplier} representing the supplied 764 * {@link Supplier} 765 * 766 * @nullability This method never returns {@code null}. 767 * 768 * @idempotency This method is not idempotent but is deterministic. 769 * 770 * @threadsafety This method is safe for concurrent use by 771 * multiple threads. 772 */ 773 @SuppressWarnings("unchecked") 774 public static <T> OptionalSupplier<T> of(final Supplier<? extends T> supplier) { 775 if (supplier == null) { 776 return Absence.instance(); 777 } else if (supplier instanceof OptionalSupplier<? extends T> os) { 778 return (OptionalSupplier<T>)os; 779 } else { 780 return new OptionalSupplierAdapter<>(supplier); 781 } 782 } 783 784 /** 785 * Returns an {@link OptionalSupplier} that will, loosely speaking, 786 * try the supplied {@code supplier} first, and, if it throws a 787 * {@link NoSuchElementException} or an {@link 788 * UnsupportedOperationException} from its {@link Supplier#get()} 789 * method, will then try the supplied {@code defaults}. 790 * 791 * <p>The supplied {@link Supplier} instances can, themselves, be 792 * {@link OptionalSupplier}s, and, if so, the resulting {@link 793 * OptionalSupplier} will have its {@link #determinism()} method 794 * appropriately implemented.</p> 795 * 796 * @param <T> the type of object the returned {@link 797 * OptionalSupplier} will {@linkplain #get() supply} 798 * 799 * @param supplier the first {@link Supplier} to try; may be {@code 800 * null} 801 * 802 * @param defaults the fallback {@link Supplier} to try; may be 803 * {@code null} 804 * 805 * @return a {@link DefaultingOptionalSupplier} 806 * 807 * @nullability This method never returns {@code null}. 808 * 809 * @idempotency This method is idempotent and deterministic. 810 * 811 * @threadsafety This method is safe for concurrent use by multiple 812 * threads. 813 */ 814 public static <T> OptionalSupplier<T> of(final Supplier<? extends T> supplier, final Supplier<? extends T> defaults) { 815 if (supplier == null) { 816 if (defaults == null) { 817 return Absence.instance(); 818 } else { 819 return of(defaults); 820 } 821 } else if (defaults == null) { 822 return of(supplier); 823 } else { 824 return DefaultingOptionalSupplier.of(supplier, defaults); 825 } 826 } 827 828 /** 829 * Returns a new {@link OptionalSupplier} whose {@link #determinism()} 830 * method will return {@link Determinism#PRESENT} and whose {@link 831 * #get()} method will return the supplied {@code value}. 832 * 833 * @param <T> the type of value the returned {@link 834 * OptionalSupplier} will {@linkplain #get() supply} 835 * 836 * @param value the value the new {@link OptionalSupplier} will 837 * return from its {@link #get()} method; may be {@code null} 838 * 839 * @return a new {@link OptionalSupplier} whose {@link #determinism()} 840 * method will return {@link Determinism#PRESENT} and whose {@link 841 * #get()} method will return the supplied {@code value} 842 * 843 * @nullability This method never returns {@code null}. 844 * 845 * @idempotency This method is not idempotent but is deterministic. 846 * 847 * @threadsafety This method is safe for concurrent use by multiple 848 * threads. 849 */ 850 public static <T> OptionalSupplier<T> of(final T value) { 851 return FixedValueSupplier.of(value); 852 } 853 854 855 /* 856 * Inner and nested classes. 857 */ 858 859 860 /** 861 * A token indicating transitory or permanent presence or absence. 862 * 863 * @author <a href="https://about.me/lairdnelson" 864 * target="_parent">Laird Nelson</a> 865 * 866 * @see #deterministic() 867 * 868 * @see OptionalSupplier#determinism() 869 */ 870 public static enum Determinism { 871 872 /** 873 * An {@link Determinism} indicating an unknown, possibly 874 * transitory, determinism or absence. 875 */ 876 NON_DETERMINISTIC(false), 877 878 /** 879 * An {@link Determinism} indicating an unknown permanent presence 880 * or absence. 881 */ 882 DETERMINISTIC(true), 883 884 /** 885 * An {@link Determinism} indicating permanent absence. 886 */ 887 ABSENT(true), 888 889 /** 890 * An {@link Determinism} indicating permanent determinism. 891 */ 892 PRESENT(true); 893 894 private final boolean deterministic; 895 896 private Determinism(final boolean deterministic) { 897 this.deterministic = deterministic; 898 } 899 900 /** 901 * Returns {@code true} if the presence or absence denoted by this 902 * {@link Determinism} is deterministic. 903 * 904 * @return {@code true} if the presence or absence denoted by this 905 * {@link Determinism} is deterministic 906 * 907 * @idempotency This method is idempotent and deterministic. 908 * 909 * @threadsafety This method is safe for concurrent use by 910 * multiple threads. 911 */ 912 public final boolean deterministic() { 913 return this.deterministic; 914 } 915 916 } 917 918}