View Javadoc

1   /*
2      Copyright 2011 Atlassian
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  package io.atlassian.fugue.deprecated;
17  
18  import java.lang.reflect.Constructor;
19  import java.lang.reflect.InvocationTargetException;
20  import java.util.function.Function;
21  
22  import static com.google.common.base.Throwables.propagateIfPossible;
23  import static java.util.Objects.requireNonNull;
24  
25  /**
26   * Static utility methods pertaining to instances of {@link java.lang.Throwable}
27   * not provided by Guava.
28   *
29   * @since 1.2
30   * @deprecated since 2.4, no need in Java7 with closeWithResources and
31   * multi-catch
32   */
33  @Deprecated public final class Throwables {
34    /**
35     * Propagates {@code throwable} as-is if it is an instance of
36     * {@link java.lang.RuntimeException} or {@link java.lang.Error}, or else as a
37     * last resort, wraps it in a {@code RuntimeException} provided by the
38     * function and then propagates.
39     * <p>
40     * This method always throws an exception. The {@code RuntimeException} return
41     * type is only for client code to make Java type system happy in case a
42     * return value is required by the enclosing method. Example usage:
43     *
44     * <pre>
45     * T doSomething() {
46     *   try {
47     *     return someMethodThatCouldThrowAnything();
48     *   } catch (IKnowWhatToDoWithThisException e) {
49     *     return handle(e);
50     *   } catch (Throwable t) {
51     *     throw Throwables.propagate(t, new Function&lt;MyRuntimeException&gt;() {
52     *       public MyRuntimeException apply(Throwable t) {
53     *         return new MyRuntimeException(t);
54     *       }
55     *     });
56     *   }
57     * }
58     * </pre>
59     *
60     * @param throwable the Throwable to propagate
61     * @param function the function to transform the throwable into a runtime
62     * exception
63     * @return nothing will ever be returned; this return type is only for your
64     * convenience, as illustrated in the example above
65     * @deprecated since 2.4, no need in Java7 with closeWithResources and
66     * multi-catch
67     * @param <R> exception type
68     */
69    @Deprecated public static <R extends RuntimeException> R propagate(Throwable throwable, Function<Throwable, R> function) {
70      propagateIfPossible(requireNonNull(throwable));
71      throw function.apply(throwable);
72    }
73  
74    /**
75     * Propagates {@code throwable} as-is if it is an instance of
76     * {@link java.lang.RuntimeException} or {@link java.lang.Error}, or else as a
77     * last resort, wraps it in the {@code RuntimeException} specified by the
78     * {@code runtimeType} parameter provided and then propagates.
79     * <p>
80     * This method always throws an exception. The {@code RuntimeException} return
81     * type is only for client code to make Java type system happy in case a
82     * return value is required by the enclosing method.
83     * <p>
84     * The runtime type passed as a parameter must be a runtime exception with a
85     * constructor taking a single {@code Throwable} as an argument accessible via
86     * reflection. If this is not the case an appropriate exception (
87     * {@code NoSuchMethodException}, {@code InstantiationException},
88     * {@code IllegalAccessException}, {@code InvocationTargetException}) will be
89     * thrown wrapped in a simple {@code RuntimeException}. If you can't make your
90     * exception match those criteria, you might want to look at using
91     * {@link #propagate(Throwable, Function)}.
92     * <p>
93     *
94     * Example usage:
95     *
96     * <pre>
97     * T doSomething() {
98     *   try {
99     *     return someMethodThatCouldThrowAnything();
100    *   } catch (IKnowWhatToDoWithThisException e) {
101    *     return handle(e);
102    *   } catch (Throwable t) {
103    *     throw Throwables.propagate(t, MyRuntimeException.class);
104    *   }
105    * }
106    * </pre>
107    *
108    * @param throwable the Throwable to propagate
109    * @param runtimeType the type of exception to use.
110    * @return nothing will ever be returned; this return type is only for your
111    * convenience, as illustrated in the example above
112    * @see #propagate(Throwable, Function)
113    * @deprecated since 2.4, no need in Java7 with closeWithResources and
114    * multi-catch
115    * @param <R> exception type
116    */
117   @Deprecated public static <R extends RuntimeException> R propagate(Throwable throwable, Class<R> runtimeType) {
118     return propagate(throwable, new ExceptionFunction<>(requireNonNull(runtimeType)));
119   }
120 
121   private final static class ExceptionFunction<E extends Exception> implements Function<Throwable, E> {
122     private final Class<E> type;
123 
124     private ExceptionFunction(Class<E> type) {
125       this.type = requireNonNull(type);
126     }
127 
128     @Override public E apply(Throwable throwable) {
129       return newInstance(getConstructor(type, Throwable.class), throwable);
130     }
131 
132     private static <T> Constructor<T> getConstructor(Class<T> type, Class<?>... argTypes) {
133       try {
134         return type.getConstructor(argTypes);
135       } catch (NoSuchMethodException e) {
136         throw com.google.common.base.Throwables.propagate(e);
137       }
138     }
139 
140     private static <T> T newInstance(Constructor<T> constructor, Object... args) {
141       try {
142         return constructor.newInstance(args);
143       } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
144         throw com.google.common.base.Throwables.propagate(e);
145       }
146     }
147   }
148 }