11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.util.concurrent; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.CancellationException; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ExecutionException; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeoutException; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A delegating wrapper around a {@link ListenableFuture} that adds support for 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the {@link #checkedGet()} and {@link #checkedGet(long, TimeUnit)} methods. 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Sven Mawson 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class AbstractCheckedFuture<V, X extends Exception> 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingListenableFuture.SimpleForwardingListenableFuture<V> 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements CheckedFuture<V, X> { 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Constructs an {@code AbstractCheckedFuture} that wraps a delegate. 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected AbstractCheckedFuture(ListenableFuture<V> delegate) { 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(delegate); 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Translates from an {@link InterruptedException}, 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link CancellationException} or {@link ExecutionException} thrown by 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code get} to an exception of type {@code X} to be thrown by 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code checkedGet}. Subclasses must implement this method. 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@code e} is an {@code InterruptedException}, the calling 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code checkedGet} method has already restored the interrupt after catching 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the exception. If an implementation of {@link #mapException(Exception)} 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * wishes to swallow the interrupt, it can do so by calling 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Thread#interrupted()}. 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Subclasses may choose to throw, rather than return, a subclass of 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code RuntimeException} to allow creating a CheckedFuture that throws 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * both checked and unchecked exceptions. 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected abstract X mapException(Exception e); 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This implementation calls {@link #get()} and maps that method's standard 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * exceptions to instances of type {@code X} using {@link #mapException}. 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>In addition, if {@code get} throws an {@link InterruptedException}, this 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementation will set the current thread's interrupt status before 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * calling {@code mapException}. 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws X if {@link #get()} throws an {@link InterruptedException}, 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link CancellationException}, or {@link ExecutionException} 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V checkedGet() throws X { 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get(); 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (InterruptedException e) { 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread.currentThread().interrupt(); 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw mapException(e); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (CancellationException e) { 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw mapException(e); 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ExecutionException e) { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw mapException(e); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This implementation calls {@link #get(long, TimeUnit)} and maps that 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method's standard exceptions (excluding {@link TimeoutException}, which is 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * propagated) to instances of type {@code X} using {@link #mapException}. 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>In addition, if {@code get} throws an {@link InterruptedException}, this 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementation will set the current thread's interrupt status before 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * calling {@code mapException}. 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws X if {@link #get()} throws an {@link InterruptedException}, 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link CancellationException}, or {@link ExecutionException} 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws TimeoutException {@inheritDoc} 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V checkedGet(long timeout, TimeUnit unit) throws TimeoutException, X { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get(timeout, unit); 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (InterruptedException e) { 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread.currentThread().interrupt(); 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw mapException(e); 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (CancellationException e) { 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw mapException(e); 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ExecutionException e) { 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw mapException(e); 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 118