Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import com.google.common.base.MoreObjects;
- import com.google.common.base.Preconditions;
- import com.google.common.util.concurrent.*;
- import java.util.Optional;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.Executor;
- import java.util.concurrent.Future;
- import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.function.Supplier;
- @SuppressWarnings("unchecked")
- public class FutureHelper {
- public static <T, V> ListenableFuture<T> getOrCreateAsync(Function<V, ListenableFuture<Optional<T>>> getter, Function<V, ListenableFuture<T>> factory, V dto) {
- return getOrCreateAsync(getter, factory, dto, MoreExecutors.directExecutor());
- }
- public static <T, V> ListenableFuture<T> getOrCreateAsync(Function<V, ListenableFuture<Optional<T>>> getter, Function<V, ListenableFuture<T>> factory, V dto, Executor executor) {
- ListenableFuture<Optional<T>> future = getter.apply(dto);
- AsyncFunction<Optional<T>, T> asyncFunction = optional -> optional.map(Futures::immediateFuture).orElseGet(() -> factory.apply(dto));
- return Futures.transformAsync(future, asyncFunction, executor);
- }
- public static <T, V> ListenableFuture<T> getOrCreate(Function<V, ListenableFuture<Optional<T>>> getter, Function<V, T> factory, V dto) {
- return getOrCreate(getter, factory, dto, MoreExecutors.directExecutor());
- }
- public static <T, V> ListenableFuture<T> getOrCreate(Function<V, ListenableFuture<Optional<T>>> getter, Function<V, T> factory, V dto, Executor executor) {
- ListenableFuture<Optional<T>> future = getter.apply(dto);
- Function<Optional<T>, T> function = optional -> optional.orElseGet(() -> factory.apply(dto));
- return Futures.transform(future, function::apply, executor);
- }
- public static <T, V> ListenableFuture<T> getOrCreateAsync(Supplier<ListenableFuture<Optional<T>>> getter,
- Supplier<ListenableFuture<T>> factory) {
- return getOrCreateAsync(getter, factory, MoreExecutors.directExecutor());
- }
- public static <T, V> ListenableFuture<T> getOrCreateAsync(Supplier<ListenableFuture<Optional<T>>> getter,
- Supplier<ListenableFuture<T>> factory, Executor executor) {
- Preconditions.checkNotNull(getter, "Null getter");
- Preconditions.checkNotNull(factory, "Null factory");
- Preconditions.checkNotNull(executor, "Null executor");
- ListenableFuture<Optional<T>> future = getter.get();
- AsyncFunction<Optional<T>, T> asyncFunction = optional -> optional.map(Futures::immediateFuture).orElseGet(factory);
- return Futures.transformAsync(future, asyncFunction, executor);
- }
- public static <V> void addCallback(ListenableFuture<V> future, Consumer<V> onSuccess, Consumer<Throwable> onFailure) {
- Preconditions.checkNotNull(future, "future");
- Preconditions.checkNotNull(onSuccess, "onSuccess");
- Preconditions.checkNotNull(onFailure, "onFailure");
- future.addListener(new FunctionalCallbackListener<>(future, onSuccess, onFailure), MoreExecutors.directExecutor());
- }
- private static final class FunctionalCallbackListener<V> implements Runnable {
- final Future<V> future;
- final Consumer<V> onSuccess;
- final Consumer<Throwable> onFailure;
- FunctionalCallbackListener(Future<V> future, Consumer<V> onSuccess, Consumer<Throwable> onFailure) {
- this.future = future;
- this.onSuccess = onSuccess;
- this.onFailure = onFailure;
- }
- @Override
- public void run() {
- final V value;
- try {
- value = Futures.getDone(future);
- } catch (ExecutionException e) {
- onFailure.accept(e.getCause());
- return;
- } catch (RuntimeException | Error e) {
- onFailure.accept(e);
- return;
- }
- onSuccess.accept(value);
- }
- @Override
- public String toString() {
- return "FunctionalCallbackListener{" +
- "future=" + future +
- ", onSuccess=" + onSuccess +
- ", onFailure=" + onFailure +
- '}';
- }
- }
- }
Add Comment
Please, Sign In to add comment