001 /* 002 * Copyright (C) 2008 Google Inc. 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 * http://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 017 package com.google.common.util.concurrent; 018 019 import com.google.common.annotations.Beta; 020 021 import java.util.concurrent.CancellationException; 022 import java.util.concurrent.ExecutionException; 023 import java.util.concurrent.Executor; 024 import java.util.concurrent.TimeUnit; 025 import java.util.concurrent.TimeoutException; 026 027 /** 028 * A delegating wrapper around a {@link ListenableFuture} that adds support for 029 * the {@link #checkedGet()} and {@link #checkedGet(long, TimeUnit)} methods. 030 * 031 * @author Sven Mawson 032 * @since 1 033 */ 034 @Beta 035 public abstract class AbstractCheckedFuture<V, E extends Exception> 036 implements CheckedFuture<V, E> { 037 038 /** The delegate, used to pass along all our methods. */ 039 protected final ListenableFuture<V> delegate; 040 041 /** 042 * Constructs an {@code AbstractCheckedFuture} that wraps a delegate. 043 */ 044 protected AbstractCheckedFuture(ListenableFuture<V> delegate) { 045 this.delegate = delegate; 046 } 047 048 /** 049 * Translate from an {@link InterruptedException}, 050 * {@link CancellationException} or {@link ExecutionException} to an exception 051 * of type {@code E}. Subclasses must implement the mapping themselves. 052 * 053 * The {@code e} parameter can be an instance of {@link InterruptedException}, 054 * {@link CancellationException}, or {@link ExecutionException}. 055 */ 056 protected abstract E mapException(Exception e); 057 058 /* 059 * Just like get but maps the exceptions into appropriate application-specific 060 * exceptions. 061 */ 062 public V checkedGet() throws E { 063 try { 064 return get(); 065 } catch (InterruptedException e) { 066 cancel(true); 067 throw mapException(e); 068 } catch (CancellationException e) { 069 throw mapException(e); 070 } catch (ExecutionException e) { 071 throw mapException(e); 072 } 073 } 074 075 /* 076 * The timed version of checkedGet maps the interrupted, cancellation or 077 * execution exceptions exactly the same as the untimed version does. 078 */ 079 public V checkedGet(long timeout, TimeUnit unit) throws TimeoutException, E { 080 try { 081 return get(timeout, unit); 082 } catch (InterruptedException e) { 083 cancel(true); 084 throw mapException(e); 085 } catch (CancellationException e) { 086 throw mapException(e); 087 } catch (ExecutionException e) { 088 throw mapException(e); 089 } 090 } 091 092 // Delegate methods for methods defined in the ListenableFuture interface. 093 094 public boolean cancel(boolean mayInterruptIfRunning) { 095 return delegate.cancel(mayInterruptIfRunning); 096 } 097 098 public boolean isCancelled() { 099 return delegate.isCancelled(); 100 } 101 102 public boolean isDone() { 103 return delegate.isDone(); 104 } 105 106 public V get() throws InterruptedException, ExecutionException { 107 return delegate.get(); 108 } 109 110 public V get(long timeout, TimeUnit unit) throws InterruptedException, 111 ExecutionException, TimeoutException { 112 return delegate.get(timeout, unit); 113 } 114 115 public void addListener(Runnable listener, Executor exec) { 116 delegate.addListener(listener, exec); 117 } 118 }