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