001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.util.concurrent;
018
019import java.util.concurrent.CompletableFuture;
020import java.util.concurrent.CompletionStage;
021import java.util.concurrent.ExecutionException;
022import java.util.concurrent.TimeUnit;
023import java.util.concurrent.TimeoutException;
024import java.util.function.BiFunction;
025
026import org.springframework.lang.UsesJava8;
027
028/**
029 * Adapts a {@link CompletableFuture} or {@link CompletionStage} into a
030 * Spring {@link ListenableFuture}.
031 *
032 * @author Sebastien Deleuze
033 * @author Juergen Hoeller
034 * @since 4.2
035 */
036@UsesJava8
037public class CompletableToListenableFutureAdapter<T> implements ListenableFuture<T> {
038
039        private final CompletableFuture<T> completableFuture;
040
041        private final ListenableFutureCallbackRegistry<T> callbacks = new ListenableFutureCallbackRegistry<T>();
042
043
044        /**
045         * Create a new adapter for the given {@link CompletionStage}.
046         * @since 4.3.7
047         */
048        public CompletableToListenableFutureAdapter(CompletionStage<T> completionStage) {
049                this(completionStage.toCompletableFuture());
050        }
051
052        /**
053         * Create a new adapter for the given {@link CompletableFuture}.
054         */
055        public CompletableToListenableFutureAdapter(CompletableFuture<T> completableFuture) {
056                this.completableFuture = completableFuture;
057                this.completableFuture.handle(new BiFunction<T, Throwable, Object>() {
058                        @Override
059                        public Object apply(T result, Throwable ex) {
060                                if (ex != null) {
061                                        callbacks.failure(ex);
062                                }
063                                else {
064                                        callbacks.success(result);
065                                }
066                                return null;
067                        }
068                });
069        }
070
071
072        @Override
073        public void addCallback(ListenableFutureCallback<? super T> callback) {
074                this.callbacks.addCallback(callback);
075        }
076
077        @Override
078        public void addCallback(SuccessCallback<? super T> successCallback, FailureCallback failureCallback) {
079                this.callbacks.addSuccessCallback(successCallback);
080                this.callbacks.addFailureCallback(failureCallback);
081        }
082
083        @Override
084        public boolean cancel(boolean mayInterruptIfRunning) {
085                return this.completableFuture.cancel(mayInterruptIfRunning);
086        }
087
088        @Override
089        public boolean isCancelled() {
090                return this.completableFuture.isCancelled();
091        }
092
093        @Override
094        public boolean isDone() {
095                return this.completableFuture.isDone();
096        }
097
098        @Override
099        public T get() throws InterruptedException, ExecutionException {
100                return this.completableFuture.get();
101        }
102
103        @Override
104        public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
105                return this.completableFuture.get(timeout, unit);
106        }
107
108}