Skip to content

Method: _s(FunctionalCheckedExceptionWrappers.SupplierWithException)

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