functionalj.promise.DeferValue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionalj-core Show documentation
Show all versions of functionalj-core Show documentation
The module for FunctionalJ Core.
// ============================================================================
// Copyright (c) 2017-2021 Nawapunth Manusitthipol (NawaMan - http://nawaman.net).
// ----------------------------------------------------------------------------
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ============================================================================
package functionalj.promise;
import static functionalj.function.Func.itself;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import functionalj.function.Func0;
import functionalj.function.Func1;
import functionalj.function.Func2;
import functionalj.function.FuncUnit1;
import functionalj.function.FuncUnit2;
import functionalj.list.FuncList;
import functionalj.result.Result;
import functionalj.result.ResultStatus;
import functionalj.result.ValidationException;
import functionalj.tuple.Tuple2;
import functionalj.validator.Validator;
import lombok.NonNull;
import lombok.val;
/**
* This special class of promise can have its value assigned later.
* Once assigned, the value is set.
**/
@SuppressWarnings({"unchecked", "rawtypes"})
public class DeferValue extends Promise {
public static DeferValue of(Class clazz) {
return new DeferValue();
}
public static DeferValue ofValue(DATA data) {
val deferValue = new DeferValue();
deferValue.assign(data);
return deferValue;
}
public static DeferValue ofFailure(@NonNull Exception cause) {
val deferValue = new DeferValue();
deferValue.fail(cause);
return deferValue;
}
public static DeferValue ofResult(Result result) {
val deferValue = new DeferValue();
deferValue.complete(result);
return deferValue;
}
public static DeferValue deferValueOf(Class clazz) {
return new DeferValue();
}
public static DeferValue deferValue() {
return new DeferValue();
}
public static DeferValue deferString() {
return new DeferValue();
}
public static DeferValue deferInt() {
return new DeferValue();
}
public static DeferValue deferLong() {
return new DeferValue();
}
public static DeferValue deferDouble() {
return new DeferValue();
}
public static DeferValue of(String name, Class clazz) {
return new DeferValue().named(name);
}
public static DeferValue deferValue(String name, Class clazz) {
return new DeferValue().named(name);
}
public static DeferValue deferValue(String name) {
return new DeferValue().named(name);
}
public static DeferValue deferString(String name) {
return new DeferValue().named(name);
}
public static DeferValue deferInt(String name) {
return new DeferValue().named(name);
}
public static DeferValue deferLong(String name) {
return new DeferValue().named(name);
}
public static DeferValue deferDouble(String name) {
return new DeferValue().named(name);
}
public DeferValue() {
super((OnStart)()->{});
start();
}
DeferValue(Promise parent) {
super(parent);
}
DeferValue parent() {
return (DeferValue)super.parent();
}
public NamedDeferValue named(String name) {
return new NamedDeferValue(this, name);
}
@Override
public Promise getPromise() {
return map(itself());
}
public Func0 asSupplier() {
return ()->get();
}
public String toString() {
return "Later#" + id;
}
private boolean complete(boolean shouldThrowException,
Predicate> parentAction,
BooleanSupplier superAction) {
val parent = parent();
if (parent != null) {
return parentAction.test(parent);
} else {
if (!isComplete()) {
synchronized (this) {
if (!isComplete()) {
return superAction.getAsBoolean();
}
}
}
return handleAlreadyCompleted(shouldThrowException);
}
}
private boolean handleAlreadyCompleted(boolean shouldThrowException) {
if (shouldThrowException) {
throw new RuntimeException();
} else {
return false;
}
}
boolean abort(boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> parent.abort(),
() -> super.abort());
}
boolean abort(String message, boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> parent.abort(message),
() -> super.abort(message));
}
boolean abort(Exception cause, boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> parent.abort(cause),
() -> super.abort(cause));
}
boolean abort(String message, Exception cause, boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> parent.abort(message, cause),
() -> super.abort(message, cause));
}
boolean assign(DATA data, boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> parent.assign(data),
() -> super.makeComplete(data));
}
boolean fail(Exception exception, boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> parent.fail(exception),
() -> super.makeFail(exception));
}
boolean complete(Result result, boolean shouldThrowException) {
return complete(shouldThrowException,
parent -> makeDone(parent, result),
() -> makeDone(this, result));
}
//== Complete ==
public boolean abort() {
return abort(false);
}
public boolean abort(String message) {
return abort(message, false);
}
public boolean abort(Exception cause) {
return abort(cause, false);
}
public boolean abort(String message, Exception cause) {
return abort(message, cause, false);
}
public boolean assign(DATA data) {
return assign(data, false);
}
public boolean fail(Exception exception) {
return fail(exception, false);
}
public boolean complete(Result result) {
return complete(result, false);
}
//== When not complete ==
public boolean abortOrThrow() {
return abort(true);
}
public boolean abortOrThrow(String message) {
return abort(message, true);
}
public boolean abortOrThrow(Exception cause) {
return abort(cause, true);
}
public boolean abortOrThrow(String message, Exception cause) {
return abort(message, cause, true);
}
public boolean assignOrThrow(DATA data) {
return assign(data, true);
}
public boolean failOrThrow(Exception exception) {
return fail(exception, true);
}
public boolean completeOrThrow(Result result) {
return complete(result, true);
}
// TODO - Do the same here to Ref
//== Functional ==
public final DeferValue filter(Predicate super DATA> predicate) {
return DeferValueHelper.mapResult(this, result -> result.filter((Predicate)predicate));
}
//== Validation ==
public DeferValue validateNotNull() {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateNotNull());
}
public DeferValue validateNotNull(String message) {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateNotNull(message));
}
public DeferValue validateUnavailable() {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateUnavailable());
}
public DeferValue validateNotReady() {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateNotReady());
}
public DeferValue validateResultCancelled() {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateResultCancelled());
}
public DeferValue validateResultNotExist() {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateResultNotExist());
}
public DeferValue validateNoMoreResult() {
return DeferValueHelper.mapResult(this, result -> (Result)result.validateNoMoreResult());
}
public DeferValue validate(String stringFormat, Predicate super DATA> validChecker) {
return DeferValueHelper.mapResult(this, result -> (Result)result.validate(stringFormat, (Predicate)validChecker));
}
public DeferValue validate(String stringFormat, Func1 super DATA, T> mapper, Predicate super T> validChecker) {
return DeferValueHelper.mapResult(this, result -> (Result)result.validate(stringFormat, (Func1)mapper, (Predicate)validChecker));
}
public DeferValue validate(Validator validator) {
return DeferValueHelper.mapResult(this, result -> (Result)result.validate((Validator)validator));
}
public DeferValue>> validate(Validator super DATA> ... validators) {
return DeferValueHelper.mapResult(this, result -> (Result)result.validate((Validator[])validators));
}
public DeferValue>> validate(List> validators) {
return DeferValueHelper.mapResult(this, result -> (Result)result.validate((List)validators));
}
public DeferValue ensureNotNull() {
return DeferValueHelper.mapResult(this, result -> (Result)result.ensureNotNull());
}
// Alias of whenNotPresentUse
public DeferValue otherwise(DATA elseValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.otherwise(elseValue));
}
// Alias of whenNotPresentGet
public DeferValue otherwiseGet(Supplier extends DATA> elseSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.otherwiseGet(elseSupplier));
}
public DeferValue printException() {
return DeferValueHelper.mapResult(this, result -> (Result)result.printException());
}
public DeferValue printException(PrintStream printStream) {
return DeferValueHelper.mapResult(this, result -> (Result)result.printException(printStream));
}
public DeferValue printException(PrintWriter printWriter) {
return DeferValueHelper.mapResult(this, result -> (Result)result.printException(printWriter));
}
//== Peek ==
public DeferValue peek(Class clzz, Consumer super T> theConsumer) {
return DeferValueHelper.mapResult(this, result -> result.peek(clzz, (Consumer)theConsumer));
}
public DeferValue peek(Predicate super DATA> selector, Consumer super DATA> theConsumer) {
return DeferValueHelper.mapResult(this, result -> result.peek((Predicate)selector, (Consumer)theConsumer));
}
public DeferValue peek(Function super DATA, T> mapper, Consumer super T> theConsumer) {
return DeferValueHelper.mapResult(this, result -> result.peek((Function)mapper, (Consumer)theConsumer));
}
public DeferValue peek(Function super DATA, T> mapper, Predicate super T> selector, Consumer super T> theConsumer) {
return DeferValueHelper.mapResult(this, result -> result.peek((Function)mapper, (Predicate) selector, (Consumer)theConsumer));
}
//== If+When ==
public DeferValue useData(FuncUnit2 processor) {
return DeferValueHelper.mapResult(this, result -> result.useData((FuncUnit2)processor));
}
public DeferValue whenComplete(FuncUnit2 processor) {
return DeferValueHelper.mapResult(this, result -> result.useData((FuncUnit2)processor));
}
public DeferValue whenComplete(FuncUnit1> processor) {
return DeferValueHelper.mapResult(this, result -> {
processor.accept((Result)result);
return null;
});
}
//== Status ==
public DeferValue ifStatusRun(ResultStatus status, Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifStatusRun(status, runnable));
}
public DeferValue ifStatusAccept(ResultStatus status, Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifStatusAccept(status, (Consumer)consumer));
}
public DeferValue whenStatusUse(ResultStatus status, DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenStatusUse(status, fallbackValue));
}
public DeferValue whenStatusGet(ResultStatus status, Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenStatusGet(status, fallbackSupplier));
}
public DeferValue whenStatusApply(ResultStatus status, BiFunction recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenStatusApply(status, (BiFunction)recoverFunction));
}
//== Present ==
public DeferValue ifPresent(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifPresent(runnable));
}
public DeferValue ifPresent(Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifPresent((Consumer)consumer));
}
//== Absent ==
public DeferValue ifAbsent(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifAbsent(runnable));
}
public DeferValue ifAbsent(Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifAbsent((Consumer)consumer));
}
public DeferValue ifAbsent(BiConsumer super DATA, ? super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifAbsent((BiConsumer)consumer));
}
public DeferValue whenAbsentUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result ->
(Result)result.whenAbsentUse(fallbackValue));
}
public DeferValue whenAbsentGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenAbsentGet(fallbackSupplier));
}
public DeferValue whenAbsentApply(BiFunction recoverFunction) {
return DeferValueHelper.mapResult(this, result -> result.whenAbsentApply((Func2)recoverFunction));
}
//== Null ==
public DeferValue ifNull(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifNull(runnable));
}
public DeferValue whenNullUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNullUse(fallbackValue));
}
public DeferValue whenNullGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNullGet(fallbackSupplier));
}
//== Value ==
public DeferValue ifValue(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifValue(runnable));
}
public DeferValue ifValue(Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifValue((Consumer)consumer));
}
//== NotValue ==
public DeferValue ifNotValue(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifNotValue(runnable));
}
public DeferValue ifNotValue(Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifNotValue((Consumer)consumer));
}
public DeferValue ifNotValue(BiConsumer super DATA, ? super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifNotValue((BiConsumer)consumer));
}
public DeferValue whenNotValueUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotValueUse(fallbackValue));
}
public DeferValue whenNotValueGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotValueGet(fallbackSupplier));
}
public DeferValue whenNotValueApply(BiFunction recoverFunction) {
return DeferValueHelper.mapResult(this, result -> result.whenNotValueApply((Func2)recoverFunction));
}
//== Valid ==
public DeferValue ifValid(Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifValid((Consumer)consumer));
}
//== Invalid ==
public DeferValue ifInvalid(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifInvalid(runnable));
}
public DeferValue ifInvalid(Consumer super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifInvalid((Consumer)consumer));
}
public DeferValue whenInvalidUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenInvalidUse(fallbackValue));
}
public DeferValue whenInvalidGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> result.whenInvalidGet((Supplier)fallbackSupplier));
}
public DeferValue whenInvalidApply(Function super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> result.whenInvalidApply((Func1)recoverFunction));
}
//== NotExist ==
public DeferValue ifNotExist(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifNotExist(runnable));
}
public DeferValue ifNotExist(Consumer super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifNotExist((Consumer)consumer));
}
public DeferValue whenNotExistUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotExistUse(fallbackValue));
}
public DeferValue whenNotExistGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotExistGet(fallbackSupplier));
}
public DeferValue whenNotExistApply(Function super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotExistApply(recoverFunction));
}
//== Exception ==
public DeferValue ifException(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifException(runnable));
}
public DeferValue ifException(Consumer super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifException(consumer));
}
public DeferValue ifExceptionThenPrint() {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifExceptionThenPrint());
}
public DeferValue ifExceptionThenPrint(PrintStream printStream) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifExceptionThenPrint(printStream));
}
public DeferValue ifExceptionThenPrint(PrintWriter printWriter) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifExceptionThenPrint(printWriter));
}
public DeferValue whenExceptionUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenExceptionUse(fallbackValue));
}
public DeferValue whenExceptionGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenExceptionGet(fallbackSupplier));
}
public DeferValue whenExceptionApply(Function super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenExceptionApply(recoverFunction));
}
public DeferValue recover(Class extends Throwable> problemClass, DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.recover(problemClass, fallbackValue));
}
public DeferValue recover(Class extends Throwable> problemClass, Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.recover(problemClass, fallbackSupplier));
}
public DeferValue recover(Class extends Throwable> problemClass, Func1 super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.recover(problemClass, recoverFunction));
}
//== Cancelled ==
public DeferValue ifCancelled(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifCancelled(runnable));
}
public DeferValue whenCancelledUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenCancelledUse(fallbackValue));
}
public DeferValue whenCancelledGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenCancelledGet(fallbackSupplier));
}
public DeferValue whenCancelledApply(Function super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenCancelledApply(recoverFunction));
}
//== Ready ==
public DeferValue ifReady(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifReady(runnable));
}
public DeferValue ifReady(Consumer super DATA> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifReady((Consumer)consumer));
}
public DeferValue ifReady(BiConsumer super DATA, ? super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifReady((BiConsumer)consumer));
}
public DeferValue whenReadyUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenReadyUse(fallbackValue));
}
public DeferValue whenReadyGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenReadyGet(fallbackSupplier));
}
public DeferValue whenNotReadyApply(BiFunction recoverFunction) {
return DeferValueHelper.mapResult(this, result -> result.whenNotReadyApply((Func2)recoverFunction));
}
//== Not Ready ==
public DeferValue ifNotReady(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifNotReady(runnable));
}
public DeferValue ifNotReady(Consumer super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> result.ifNotReady((Consumer)consumer));
}
public DeferValue whenNotReadyUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotReadyUse(fallbackValue));
}
public DeferValue whenNotReadyGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotReadyGet(fallbackSupplier));
}
public DeferValue whenNotReadyApply(Function super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNotReadyApply(recoverFunction));
}
//== No More Result ==
public DeferValue ifNoMore(Runnable runnable) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifNoMore(runnable));
}
public DeferValue ifNoMore(Consumer super Exception> consumer) {
return DeferValueHelper.mapResult(this, result -> (Result)result.ifNoMore(consumer));
}
public DeferValue whenNoMoreUse(DATA fallbackValue) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNoMoreUse(fallbackValue));
}
public DeferValue whenNoMoreGet(Supplier extends DATA> fallbackSupplier) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNoMoreGet(fallbackSupplier));
}
public DeferValue whenNoMoreApply(Function super Exception,? extends DATA> recoverFunction) {
return DeferValueHelper.mapResult(this, result -> (Result)result.whenNoMoreApply(recoverFunction));
}
}