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<MyRuntimeException>() {
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 }