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.ExecutionException; 020 021import org.springframework.lang.Nullable; 022 023/** 024 * Abstract class that adapts a {@link ListenableFuture} parameterized over S into a 025 * {@code ListenableFuture} parameterized over T. All methods are delegated to the 026 * adaptee, where {@link #get()}, {@link #get(long, java.util.concurrent.TimeUnit)}, 027 * and {@link ListenableFutureCallback#onSuccess(Object)} call {@link #adapt(Object)} 028 * on the adaptee's result. 029 * 030 * @author Arjen Poutsma 031 * @since 4.0 032 * @param <T> the type of this {@code Future} 033 * @param <S> the type of the adaptee's {@code Future} 034 */ 035public abstract class ListenableFutureAdapter<T, S> extends FutureAdapter<T, S> implements ListenableFuture<T> { 036 037 /** 038 * Construct a new {@code ListenableFutureAdapter} with the given adaptee. 039 * @param adaptee the future to adapt to 040 */ 041 protected ListenableFutureAdapter(ListenableFuture<S> adaptee) { 042 super(adaptee); 043 } 044 045 046 @Override 047 public void addCallback(final ListenableFutureCallback<? super T> callback) { 048 addCallback(callback, callback); 049 } 050 051 @Override 052 public void addCallback(final SuccessCallback<? super T> successCallback, final FailureCallback failureCallback) { 053 ListenableFuture<S> listenableAdaptee = (ListenableFuture<S>) getAdaptee(); 054 listenableAdaptee.addCallback(new ListenableFutureCallback<S>() { 055 @Override 056 public void onSuccess(@Nullable S result) { 057 T adapted = null; 058 if (result != null) { 059 try { 060 adapted = adaptInternal(result); 061 } 062 catch (ExecutionException ex) { 063 Throwable cause = ex.getCause(); 064 onFailure(cause != null ? cause : ex); 065 return; 066 } 067 catch (Throwable ex) { 068 onFailure(ex); 069 return; 070 } 071 } 072 successCallback.onSuccess(adapted); 073 } 074 @Override 075 public void onFailure(Throwable ex) { 076 failureCallback.onFailure(ex); 077 } 078 }); 079 } 080 081}