1 /*
2  * Copyright (C) 2011 The Guava Authors
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 static com.google.common.base.Preconditions.checkNotNull;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.Future;
24 import java.util.concurrent.TimeUnit;
25 import java.util.concurrent.TimeoutException;
26 
27 /**
28  * A {@link Future} implementation which always throws directly from calls to {@code get()} (i.e.
29  * not wrapped in {@code ExecutionException}. For just a normal failure, use {@link
30  * SettableFuture}).
31  *
32  * <p>Useful for testing the behavior of Future utilities against odd futures.
33  *
34  * @author Anthony Zana
35  */
36 @GwtCompatible
37 final class UncheckedThrowingFuture<V> extends AbstractFuture<V> {
38 
throwingError(Error error)39   public static <V> ListenableFuture<V> throwingError(Error error) {
40     UncheckedThrowingFuture<V> future = new UncheckedThrowingFuture<V>();
41     future.complete(checkNotNull(error));
42     return future;
43   }
44 
throwingRuntimeException(RuntimeException e)45   public static <V> ListenableFuture<V> throwingRuntimeException(RuntimeException e) {
46     UncheckedThrowingFuture<V> future = new UncheckedThrowingFuture<V>();
47     future.complete(checkNotNull(e));
48     return future;
49   }
50 
incomplete()51   public static <V> UncheckedThrowingFuture<V> incomplete() {
52     return new UncheckedThrowingFuture<V>();
53   }
54 
complete(RuntimeException e)55   public void complete(RuntimeException e) {
56     if (!super.setException(new WrapperException(checkNotNull(e)))) {
57       throw new IllegalStateException("Future was already complete: " + this);
58     }
59   }
60 
complete(Error e)61   public void complete(Error e) {
62     if (!super.setException(new WrapperException(checkNotNull(e)))) {
63       throw new IllegalStateException("Future was already complete: " + this);
64     }
65   }
66 
67   private static final class WrapperException extends Exception {
WrapperException(Throwable t)68     WrapperException(Throwable t) {
69       super(t);
70     }
71   }
72 
rethrow(ExecutionException e)73   private static void rethrow(ExecutionException e) throws ExecutionException {
74     Throwable wrapper = e.getCause();
75     if (wrapper instanceof WrapperException) {
76       Throwable cause = wrapper.getCause();
77       if (cause instanceof RuntimeException) {
78         throw (RuntimeException) cause;
79       } else if (cause instanceof Error) {
80         throw (Error) cause;
81       }
82     }
83     throw e;
84   }
85 
86   @Override
get()87   public V get() throws ExecutionException, InterruptedException {
88     try {
89       super.get();
90     } catch (ExecutionException e) {
91       rethrow(e);
92     }
93     throw new AssertionError("Unreachable");
94   }
95 
96   @Override
get(long timeout, TimeUnit unit)97   public V get(long timeout, TimeUnit unit)
98       throws InterruptedException, ExecutionException, TimeoutException {
99     try {
100       super.get(timeout, unit);
101     } catch (ExecutionException e) {
102       rethrow(e);
103     }
104     throw new AssertionError("Unreachable");
105   }
106 }
107