Skip to contentPackage: FunctionalCheckedExceptionWrappers$FunctionWithException
FunctionalCheckedExceptionWrappers$FunctionWithException
Coverage
1: /*
2: * *********************************************************************************************************************
3: *
4: * TheseFoolishThings: Miscellaneous utilities
5: * http://tidalwave.it/projects/thesefoolishthings
6: *
7: * Copyright (C) 2009 - 2024 by Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *********************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
12: * the License. You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
17: * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
18: * specific language governing permissions and limitations under the License.
19: *
20: * *********************************************************************************************************************
21: *
22: * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
23: * git clone https://github.com/tidalwave-it/thesefoolishthings-src
24: *
25: * *********************************************************************************************************************
26: */
27: package it.tidalwave.util;
28:
29: import javax.annotation.Nonnull;
30: import java.util.function.Consumer;
31: import java.util.function.Function;
32: import java.util.function.Predicate;
33: import java.util.function.Supplier;
34: import java.io.IOException;
35: import java.io.UncheckedIOException;
36: import lombok.NoArgsConstructor;
37: import static lombok.AccessLevel.PRIVATE;
38:
39: /***********************************************************************************************************************
40: *
41: * A collections of utility methods for simplifying the syntax of lambda expressions with APIs that don't accept
42: * checked exceptions (such as {@link java.util.stream.Stream}): they provide wrapped functions that have no checked
43: * exception in the signature and whose implementation delegates to the original function wrapping an eventual checked
44: * exception into a {@link RuntimeException}. For instance, given the following method that could not be used as a
45: * {@link java.util.stream.Stream#filter(Predicate)} argument:
46: *
47: * <pre>
48: * private boolean matchEven (final int number)
49: * throws Exception
50: * {
51: * if (number == 13)
52: * {
53: * throw new Exception("13!");
54: * }
55: *
56: * return number % 2 == 0;
57: * }
58: * </pre>
59: *
60: * working code can be written as:
61: *
62: * <pre>
63: * try
64: * {
65: * List<Integer> numbers = IntStream.rangeClosed(1, 20)
66: * .mapToObj(Integer::valueOf)
67: * .filter(_p(this::matchEven)) // note the wrapper here
68: * .collect(Collectors.toList());
69: * ...
70: * }
71: * catch (RuntimeException e)
72: * {
73: * ...
74: * }
75: * </pre>
76: *
77: * Any checked exception is wrapped by a {@code RuntimeException}, but {@link IOException} is wrapped by a
78: * {@link UncheckedIOException}.
79: *
80: * @author Fabrizio Giudici
81: * @it.tidalwave.javadoc.draft
82: * @since 3.2-ALPHA-1
83: *
84: **********************************************************************************************************************/
85: @NoArgsConstructor(access = PRIVATE)
86: public final class FunctionalCheckedExceptionWrappers
87: {
88: /*******************************************************************************************************************
89: *
90: * A variant of {@link Function} that might throw an {@link Exception}. This interface must not be directly used,
91: * it's defined to let the compiler infer functional equivalence.
92: *
93: * @param <T> the type of the function argument
94: * @param <R> the type of the function return value
95: * @hidden
96: *
97: ******************************************************************************************************************/
98: @FunctionalInterface
99: public static interface FunctionWithException<T, R>
100: {
101: public R apply (T t)
102: throws Exception;
103: }
104:
105: /*******************************************************************************************************************
106: *
107: * A variant of {@link Consumer} that might throw an {@link Exception}. This interface must not be directly used,
108: * it's defined to let the compiler infer functional equivalence.
109: *
110: * @param <T> the type of the {@code Consumer} argument
111: * @hidden
112: *
113: ******************************************************************************************************************/
114: @FunctionalInterface
115: public static interface ConsumerWithException<T>
116: {
117: public void accept (T t)
118: throws Exception;
119: }
120:
121: /*******************************************************************************************************************
122: *
123: * A variant of {@link Supplier} that might throw an {@link Exception}. This interface must not be directly used,
124: * it's defined to let the compiler infer functional equivalence.
125: *
126: * @param <T> the type of the {@code Supplier} argument
127: * @hidden
128: *
129: ******************************************************************************************************************/
130: @FunctionalInterface
131: public static interface SupplierWithException<T>
132: {
133: public T get ()
134: throws Exception;
135: }
136:
137: /*******************************************************************************************************************
138: *
139: * A variant of {@link Predicate} that might throw an {@link Exception}. This interface must not be directly used,
140: * it's defined to let the compiler infer functional equivalence.
141: *
142: * @param <T> the type of the {@code Predicate} argument
143: * @hidden
144: *
145: ******************************************************************************************************************/
146: @FunctionalInterface
147: public static interface PredicateWithException<T>
148: {
149: public boolean test (T t)
150: throws Exception;
151: }
152:
153: /*******************************************************************************************************************
154: *
155: * A variant of {@link Runnable} that might throw an {@link Exception}. This interface must not be directly used,
156: * it's defined to let the compiler infer functional equivalence.
157: *
158: * @hidden
159: *
160: ******************************************************************************************************************/
161: @FunctionalInterface
162: public static interface RunnableWithException
163: {
164: @SuppressWarnings("RedundantThrows")
165: public void run()
166: throws Exception;
167: }
168:
169: /*******************************************************************************************************************
170: *
171: * A wrapper for a {@link Function} that catches exceptions and wraps them into {@link RuntimeException}s.
172: *
173: * @param function the {@code Function} to wrap.
174: * @param <T> the type of the function argument
175: * @param <R> the type of the function return value
176: * @return the wrapped {@code Function}
177: *
178: ******************************************************************************************************************/
179: @Nonnull
180: public static <T, R> Function<T, R> _f (@Nonnull final FunctionWithException<? super T, ? extends R> function)
181: {
182: return t ->
183: {
184: try
185: {
186: return function.apply(t);
187: }
188: catch (Exception e)
189: {
190: throw wrappedException(e);
191: }
192: };
193: }
194:
195: /*******************************************************************************************************************
196: *
197: * A wrapper for a {@link Consumer} that catches exceptions and wraps them into {@link RuntimeException}s.
198: *
199: * @param consumer the {@code Consumer} to wrap.
200: * @param <T> the type of the {@code Consumer} argument
201: * @return the wrapped {@code Consumer}
202: *
203: ******************************************************************************************************************/
204: @Nonnull
205: public static <T> Consumer<T> _c (@Nonnull final ConsumerWithException<? super T> consumer)
206: {
207: return t ->
208: {
209: try
210: {
211: consumer.accept(t);
212: }
213: catch (Exception e)
214: {
215: throw wrappedException(e);
216: }
217: };
218: }
219:
220: /*******************************************************************************************************************
221: *
222: * A wrapper for a {@link Supplier} that catches exceptions and wraps them into {@link RuntimeException}s.
223: *
224: * @param supplier the {@code Supplier} to wrap.
225: * @param <T> the type of the {@code Supplier} argument
226: * @return the wrapped {@code Supplier}
227: *
228: ******************************************************************************************************************/
229: @Nonnull
230: public static <T> Supplier<T> _s (@Nonnull final SupplierWithException<? extends T> supplier)
231: {
232: return () ->
233: {
234: try
235: {
236: return supplier.get();
237: }
238: catch (Exception e)
239: {
240: throw wrappedException(e);
241: }
242: };
243: }
244:
245: /*******************************************************************************************************************
246: *
247: * A wrapper for a {@link Predicate} that catches exceptions and wraps them into {@link RuntimeException}s.
248: *
249: * @param predicate the {@code Predicate} to wrap.
250: * @param <T> the type of the {@code Predicate} argument
251: * @return the wrapped {@code Predicate}
252: *
253: ******************************************************************************************************************/
254: @Nonnull
255: public static <T> Predicate<T> _p (@Nonnull final PredicateWithException<? super T> predicate)
256: {
257: return t ->
258: {
259: try
260: {
261: return predicate.test(t);
262: }
263: catch (Exception e)
264: {
265: throw wrappedException(e);
266: }
267: };
268: }
269:
270: /*******************************************************************************************************************
271: *
272: * A wrapper for an equivalent of {@link Runnable} that catches exceptions and wraps them into
273: * {@link RuntimeException}s.
274: *
275: * @param runnable the {@code Runnable} to wrap.
276: * @return the wrapped {@code Predicate}
277: * @since 3.2-ALPHA-12
278: *
279: ******************************************************************************************************************/
280: @Nonnull
281: public static Runnable _r (@Nonnull final RunnableWithException runnable)
282: {
283: return () ->
284: {
285: try
286: {
287: runnable.run();
288: }
289: catch (Exception e)
290: {
291: throw wrappedException(e);
292: }
293: };
294: }
295:
296: /*******************************************************************************************************************
297: *
298: * Wraps a throwable with a {@link RuntimeException}. Unchecked exceptions are not wrapped; {@link IOException}
299: * is wrapped with {@link UncheckedIOException}.
300: *
301: * @param e the exception to wrap
302: * @return the wrapped exception
303: *
304: ******************************************************************************************************************/
305: @Nonnull
306: public static RuntimeException wrappedException (@Nonnull final Throwable e)
307: {
308: if (e instanceof RuntimeException)
309: {
310: return (RuntimeException)e;
311: }
312:
313: if (e instanceof IOException)
314: {
315: return new UncheckedIOException((IOException)e);
316: }
317:
318: return new RuntimeException(e);
319: }
320: }