• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package org.apache.commons.io.function;
19 
20 import java.io.IOException;
21 import java.io.UncheckedIOException;
22 import java.util.Objects;
23 import java.util.function.Consumer;
24 import java.util.function.Function;
25 import java.util.function.Supplier;
26 
27 /**
28  * Like {@link Function} but throws {@link IOException}.
29  *
30  * @param <T> the type of the input to the operations.
31  * @param <R> the return type of the operations.
32  * @since 2.7
33  */
34 @FunctionalInterface
35 public interface IOFunction<T, R> {
36 
37     /**
38      * Returns a {@link IOFunction} that always returns its input argument.
39      *
40      * @param <T> the type of the input and output objects to the function
41      * @return a function that always returns its input argument
42      */
identity()43     static <T> IOFunction<T, T> identity() {
44         return Constants.IO_FUNCTION_ID;
45     }
46 
47     /**
48      * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the
49      * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the
50      * caller of the composed function.
51      *
52      * @param after the consumer to apply after this function is applied
53      * @return a composed function that first applies this function and then applies the {@code after} consumer
54      * @throws NullPointerException if after is null
55      *
56      * @see #compose(IOFunction)
57      */
andThen(final Consumer<? super R> after)58     default IOConsumer<T> andThen(final Consumer<? super R> after) {
59         Objects.requireNonNull(after, "after");
60         return (final T t) -> after.accept(apply(t));
61     }
62 
63     /**
64      * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the
65      * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the
66      * caller of the composed function.
67      *
68      * @param <V> the type of output of the {@code after} function, and of the composed function
69      * @param after the function to apply after this function is applied
70      * @return a composed function that first applies this function and then applies the {@code after} function
71      * @throws NullPointerException if after is null
72      *
73      * @see #compose(IOFunction)
74      */
andThen(final Function<? super R, ? extends V> after)75     default <V> IOFunction<T, V> andThen(final Function<? super R, ? extends V> after) {
76         Objects.requireNonNull(after, "after");
77         return (final T t) -> after.apply(apply(t));
78     }
79 
80     /**
81      * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the
82      * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the
83      * caller of the composed function.
84      *
85      * @param after the consumer to apply after this function is applied
86      * @return a composed function that first applies this function and then applies the {@code after} consumer
87      * @throws NullPointerException if after is null
88      *
89      * @see #compose(IOFunction)
90      */
andThen(final IOConsumer<? super R> after)91     default IOConsumer<T> andThen(final IOConsumer<? super R> after) {
92         Objects.requireNonNull(after, "after");
93         return (final T t) -> after.accept(apply(t));
94     }
95 
96     /**
97      * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the
98      * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the
99      * caller of the composed function.
100      *
101      * @param <V> the type of output of the {@code after} function, and of the composed function
102      * @param after the function to apply after this function is applied
103      * @return a composed function that first applies this function and then applies the {@code after} function
104      * @throws NullPointerException if after is null
105      *
106      * @see #compose(IOFunction)
107      */
andThen(final IOFunction<? super R, ? extends V> after)108     default <V> IOFunction<T, V> andThen(final IOFunction<? super R, ? extends V> after) {
109         Objects.requireNonNull(after, "after");
110         return (final T t) -> after.apply(apply(t));
111     }
112 
113     /**
114      * Applies this function to the given argument.
115      *
116      * @param t the function argument
117      * @return the function result
118      * @throws IOException if an I/O error occurs.
119      */
apply(final T t)120     R apply(final T t) throws IOException;
121 
122     /**
123      * Creates a {@link Function} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}.
124      *
125      * @return an UncheckedIOException Function.
126      * @since 2.12.0
127      */
asFunction()128     default Function<T, R> asFunction() {
129         return t -> Uncheck.apply(this, t);
130     }
131 
132     /**
133      * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies
134      * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
135      * composed function.
136      *
137      * @param <V> the type of input to the {@code before} function, and to the composed function
138      * @param before the function to apply before this function is applied
139      * @return a composed function that first applies the {@code before} function and then applies this function
140      * @throws NullPointerException if before is null
141      *
142      * @see #andThen(IOFunction)
143      */
compose(final Function<? super V, ? extends T> before)144     default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) {
145         Objects.requireNonNull(before, "before");
146         return (final V v) -> apply(before.apply(v));
147     }
148 
149     /**
150      * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies
151      * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
152      * composed function.
153      *
154      * @param <V> the type of input to the {@code before} function, and to the composed function
155      * @param before the function to apply before this function is applied
156      * @return a composed function that first applies the {@code before} function and then applies this function
157      * @throws NullPointerException if before is null
158      *
159      * @see #andThen(IOFunction)
160      */
compose(final IOFunction<? super V, ? extends T> before)161     default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) {
162         Objects.requireNonNull(before, "before");
163         return (final V v) -> apply(before.apply(v));
164     }
165 
166     /**
167      * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies
168      * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
169      * composed function.
170      *
171      * @param before the supplier which feeds the application of this function
172      * @return a composed function that first applies the {@code before} function and then applies this function
173      * @throws NullPointerException if before is null
174      *
175      * @see #andThen(IOFunction)
176      */
compose(final IOSupplier<? extends T> before)177     default IOSupplier<R> compose(final IOSupplier<? extends T> before) {
178         Objects.requireNonNull(before, "before");
179         return () -> apply(before.get());
180     }
181 
182     /**
183      * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies
184      * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
185      * composed function.
186      *
187      * @param before the supplier which feeds the application of this function
188      * @return a composed function that first applies the {@code before} function and then applies this function
189      * @throws NullPointerException if before is null
190      *
191      * @see #andThen(IOFunction)
192      */
compose(final Supplier<? extends T> before)193     default IOSupplier<R> compose(final Supplier<? extends T> before) {
194         Objects.requireNonNull(before, "before");
195         return () -> apply(before.get());
196     }
197 }
198