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