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 - 2023 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: public void run()
165: throws Exception;
166: }
167:
168: /*******************************************************************************************************************
169: *
170: * A wrapper for a {@link Function} that catches exceptions and wraps them into {@link RuntimeException}s.
171: *
172: * @param function the {@code Function} to wrap.
173: * @param <T> the type of the function argument
174: * @param <R> the type of the function return value
175: * @return the wrapped {@code Function}
176: *
177: ******************************************************************************************************************/
178: @Nonnull
179: public static <T, R> Function<T, R> _f (@Nonnull final FunctionWithException<T, R> function)
180: {
181: return t ->
182: {
183: try
184: {
185: return function.apply(t);
186: }
187: catch (Exception e)
188: {
189: throw wrappedException(e);
190: }
191: };
192: }
193:
194: /*******************************************************************************************************************
195: *
196: * A wrapper for a {@link Consumer} that catches exceptions and wraps them into {@link RuntimeException}s.
197: *
198: * @param consumer the {@code Consumer} to wrap.
199: * @param <T> the type of the {@code Consumer} argument
200: * @return the wrapped {@code Consumer}
201: *
202: ******************************************************************************************************************/
203: @Nonnull
204: public static <T> Consumer<T> _c (@Nonnull final ConsumerWithException<T> consumer)
205: {
206: return t ->
207: {
208: try
209: {
210: consumer.accept(t);
211: }
212: catch (Exception e)
213: {
214: throw wrappedException(e);
215: }
216: };
217: }
218:
219: /*******************************************************************************************************************
220: *
221: * A wrapper for a {@link Supplier} that catches exceptions and wraps them into {@link RuntimeException}s.
222: *
223: * @param supplier the {@code Supplier} to wrap.
224: * @param <T> the type of the {@code Supplier} argument
225: * @return the wrapped {@code Supplier}
226: *
227: ******************************************************************************************************************/
228: @Nonnull
229: public static <T> Supplier<T> _s (@Nonnull final SupplierWithException<T> supplier)
230: {
231: return () ->
232: {
233: try
234: {
235: return supplier.get();
236: }
237: catch (Exception e)
238: {
239: throw wrappedException(e);
240: }
241: };
242: }
243:
244: /*******************************************************************************************************************
245: *
246: * A wrapper for a {@link Predicate} that catches exceptions and wraps them into {@link RuntimeException}s.
247: *
248: * @param predicate the {@code Predicate} to wrap.
249: * @param <T> the type of the {@code Predicate} argument
250: * @return the wrapped {@code Predicate}
251: *
252: ******************************************************************************************************************/
253: @Nonnull
254: public static <T> Predicate<T> _p (@Nonnull final PredicateWithException<T> predicate)
255: {
256: return t ->
257: {
258: try
259: {
260: return predicate.test(t);
261: }
262: catch (Exception e)
263: {
264: throw wrappedException(e);
265: }
266: };
267: }
268:
269: /*******************************************************************************************************************
270: *
271: * A wrapper for an equivalent of {@link Runnable} that catches exceptions and wraps them into
272: * {@link RuntimeException}s.
273: *
274: * @param runnable the {@code Runnable} to wrap.
275: * @return the wrapped {@code Predicate}
276: * @since 3.2-ALPHA-12
277: *
278: ******************************************************************************************************************/
279: @Nonnull
280: public static Runnable _r (@Nonnull final RunnableWithException runnable)
281: {
282: return () ->
283: {
284: try
285: {
286: runnable.run();
287: }
288: catch (Exception e)
289: {
290: throw wrappedException(e);
291: }
292: };
293: }
294:
295: /*******************************************************************************************************************
296: *
297: * Wraps a throwable with a {@link RuntimeException}. Unchecked exceptions are not wrapped; {@link IOException}
298: * is wrapped with {@link UncheckedIOException}.
299: *
300: * @param e the exception to wrap
301: * @return the wrapped exception
302: *
303: ******************************************************************************************************************/
304: @Nonnull
305: public static RuntimeException wrappedException (@Nonnull final Throwable e)
306: {
307: if (e instanceof RuntimeException)
308: {
309: return (RuntimeException)e;
310: }
311:
312: if (e instanceof IOException)
313: {
314: return new UncheckedIOException((IOException)e);
315: }
316:
317: return new RuntimeException(e);
318: }
319: }