All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.activej.promise.CompletePromise Maven / Gradle / Ivy

Go to download

A convenient way to organize asynchronous code. Promises are a faster and more efficient version of JavaScript's Promise and Java's CompletionStage's.

There is a newer version: 6.0-rc2
Show newest version
/*
 * Copyright (C) 2020 ActiveJ LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.activej.promise;

import io.activej.async.callback.Callback;
import io.activej.async.function.*;
import io.activej.common.collection.Try;
import io.activej.common.function.*;
import io.activej.common.recycle.Recyclers;
import org.jetbrains.annotations.Nullable;

import java.util.concurrent.CompletableFuture;

import static io.activej.common.exception.FatalErrorHandler.handleError;
import static io.activej.reactor.Reactor.getCurrentReactor;

/**
 * Represents a completed {@code Promise} with a result of unspecified type.
 */
@SuppressWarnings("unchecked")
public abstract class CompletePromise implements Promise {
	static {
		Recyclers.register(CompletePromise.class, promise -> Recyclers.recycle(promise.getResult()));
	}

	@Override
	public final boolean isComplete() {
		return true;
	}

	@Override
	public final boolean isResult() {
		return true;
	}

	@Override
	public final boolean isException() {
		return false;
	}

	@Override
	public final Exception getException() {
		return null;
	}

	@Override
	public Try getTry() {
		return Try.of(getResult());
	}

	@Override
	public final  Promise map(FunctionEx fn) {
		try {
			return Promise.of(fn.apply(getResult()));
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public final  Promise map(BiFunctionEx fn) {
		try {
			return Promise.of(fn.apply(getResult(), null));
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise map(FunctionEx fn, FunctionEx exceptionFn) {
		try {
			return Promise.of(fn.apply(getResult()));
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise mapException(FunctionEx exceptionFn) {
		return this;
	}

	@Override
	public  Promise mapException(
		Class clazz, FunctionEx exceptionFn
	) {
		return this;
	}

	@Override
	public final  Promise then(AsyncFunctionEx fn) {
		try {
			return fn.apply(getResult());
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise thenCallback(CallbackFunctionEx fn) {
		try {
			return Promise.ofCallback(getResult(), fn);
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise then(AsyncSupplierEx fn) {
		try {
			return fn.get();
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise thenCallback(CallbackSupplierEx fn) {
		try {
			return Promise.ofCallback(fn);
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public final  Promise then(AsyncBiFunctionEx fn) {
		try {
			return fn.apply(getResult(), null);
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise thenCallback(CallbackBiFunctionEx fn) {
		try {
			return Promise.ofCallback(getResult(), null, fn);
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise then(AsyncFunctionEx fn, AsyncFunctionEx exceptionFn) {
		try {
			return fn.apply(getResult());
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public  Promise thenCallback(CallbackFunctionEx fn, CallbackFunctionEx exceptionFn) {
		try {
			return Promise.ofCallback(getResult(), null, fn, exceptionFn);
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise whenComplete(BiConsumerEx fn) {
		try {
			fn.accept(getResult(), null);
			return this;
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise whenComplete(ConsumerEx fn, ConsumerEx exceptionFn) {
		try {
			fn.accept(getResult());
			return this;
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise whenComplete(RunnableEx action) {
		try {
			action.run();
			return this;
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise whenResult(ConsumerEx fn) {
		try {
			fn.accept(getResult());
			return this;
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise whenResult(RunnableEx action) {
		try {
			action.run();
			return this;
		} catch (Exception ex) {
			handleError(ex, this);
			return Promise.ofException(ex);
		}
	}

	@Override
	public Promise whenException(ConsumerEx fn) {
		return this;
	}

	@Override
	public  Promise whenException(Class clazz, ConsumerEx fn) {
		return this;
	}

	@Override
	public Promise whenException(RunnableEx action) {
		return this;
	}

	@Override
	public Promise whenException(Class clazz, RunnableEx action) {
		return this;
	}

	@Override
	public final  Promise combine(Promise other, BiFunctionEx fn) {
		return (Promise) other
			.map(otherResult -> fn.apply(this.getResult(), otherResult))
			.whenException(() -> Recyclers.recycle(this.getResult()));
	}

	@Override
	public final Promise both(Promise other) {
		Recyclers.recycle(getResult());
		return other.map(AbstractPromise::recycleToVoid);
	}

	@Override
	public final Promise either(Promise other) {
		other.whenResult(Recyclers::recycle);
		return this;
	}

	@Override
	public final Promise async() {
		SettablePromise result = new SettablePromise<>();
		getCurrentReactor().post(() -> result.set(getResult()));
		return result;
	}

	@Override
	public final Promise> toTry() {
		return Promise.of(Try.of(getResult()));
	}

	@Override
	public final Promise toVoid() {
		return Promise.complete();
	}

	@Override
	public void next(NextPromise cb) {
		cb.acceptNext(getResult(), null);
	}

	@Override
	public Promise subscribe(Callback cb) {
		cb.accept(getResult(), null);
		return this;
	}

	@Override
	public final CompletableFuture toCompletableFuture() {
		return CompletableFuture.completedFuture(getResult());
	}
}