1 /* 2 * Copyright (C) 2008 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.util.concurrent; 18 19 import java.util.concurrent.CancellationException; 20 import java.util.concurrent.ExecutionException; 21 import java.util.concurrent.Executor; 22 import java.util.concurrent.TimeUnit; 23 import java.util.concurrent.TimeoutException; 24 25 /** 26 * A delegating wrapper around a {@link ListenableFuture} that adds support for 27 * the {@link #checkedGet()} and {@link #checkedGet(long, TimeUnit)} methods. 28 * 29 * @author Sven Mawson 30 * @since 2009.09.15 <b>tentative</b> 31 */ 32 public abstract class AbstractCheckedFuture<V, E extends Exception> 33 implements CheckedFuture<V, E> { 34 35 /** The delegate, used to pass along all our methods. */ 36 protected final ListenableFuture<V> delegate; 37 38 /** 39 * Constructs an {@code AbstractCheckedFuture} that wraps a delegate. 40 */ AbstractCheckedFuture(ListenableFuture<V> delegate)41 protected AbstractCheckedFuture(ListenableFuture<V> delegate) { 42 this.delegate = delegate; 43 } 44 45 /** 46 * Translate from an {@link InterruptedException}, 47 * {@link CancellationException} or {@link ExecutionException} to an exception 48 * of type {@code E}. Subclasses must implement the mapping themselves. 49 * 50 * The {@code e} parameter can be an instance of {@link InterruptedException}, 51 * {@link CancellationException}, or {@link ExecutionException}. 52 */ mapException(Exception e)53 protected abstract E mapException(Exception e); 54 55 /* 56 * Just like get but maps the exceptions into appropriate application-specific 57 * exceptions. 58 */ checkedGet()59 public V checkedGet() throws E { 60 try { 61 return get(); 62 } catch (InterruptedException e) { 63 cancel(true); 64 throw mapException(e); 65 } catch (CancellationException e) { 66 throw mapException(e); 67 } catch (ExecutionException e) { 68 throw mapException(e); 69 } 70 } 71 72 /* 73 * The timed version of checkedGet maps the interrupted, cancellation or 74 * execution exceptions exactly the same as the untimed version does. 75 */ checkedGet(long timeout, TimeUnit unit)76 public V checkedGet(long timeout, TimeUnit unit) throws TimeoutException, E { 77 try { 78 return get(timeout, unit); 79 } catch (InterruptedException e) { 80 cancel(true); 81 throw mapException(e); 82 } catch (CancellationException e) { 83 throw mapException(e); 84 } catch (ExecutionException e) { 85 throw mapException(e); 86 } 87 } 88 89 // Delegate methods for methods defined in the ListenableFuture interface. 90 cancel(boolean mayInterruptIfRunning)91 public boolean cancel(boolean mayInterruptIfRunning) { 92 return delegate.cancel(mayInterruptIfRunning); 93 } 94 isCancelled()95 public boolean isCancelled() { 96 return delegate.isCancelled(); 97 } 98 isDone()99 public boolean isDone() { 100 return delegate.isDone(); 101 } 102 get()103 public V get() throws InterruptedException, ExecutionException { 104 return delegate.get(); 105 } 106 get(long timeout, TimeUnit unit)107 public V get(long timeout, TimeUnit unit) throws InterruptedException, 108 ExecutionException, TimeoutException { 109 return delegate.get(timeout, unit); 110 } 111 addListener(Runnable listener, Executor exec)112 public void addListener(Runnable listener, Executor exec) { 113 delegate.addListener(listener, exec); 114 } 115 } 116