001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.io.function; 019 020import java.io.IOException; 021import java.util.Objects; 022import java.util.function.Consumer; 023import java.util.function.Function; 024import java.util.function.Supplier; 025 026/** 027 * Like {@link Function} but throws {@link IOException}. 028 * 029 * @param <T> the type of the input to the operations. 030 * @param <R> the return type of the operations. 031 * @since 2.7 032 */ 033@FunctionalInterface 034public interface IOFunction<T, R> { 035 036 /** 037 * Applies this function to the given argument. 038 * 039 * @param t the function argument 040 * @return the function result 041 * 042 * @throws IOException if the function throws an IOException 043 */ 044 R apply(final T t) throws IOException; 045 046 /** 047 * Returns a composed {@link IOFunction} that first applies the {@code before} 048 * function to its input, and then applies this function to the result. 049 * If evaluation of either function throws an exception, it is relayed to 050 * the caller of the composed function. 051 * 052 * @param <V> the type of input to the {@code before} function, and to the 053 * composed function 054 * @param before the function to apply before this function is applied 055 * @return a composed function that first applies the {@code before} 056 * function and then applies this function 057 * @throws NullPointerException if before is null 058 * 059 * @see #andThen(IOFunction) 060 */ 061 default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) { 062 Objects.requireNonNull(before); 063 return (V v) -> apply(before.apply(v)); 064 } 065 066 /** 067 * Returns a composed {@link IOFunction} that first applies the {@code before} 068 * function to its input, and then applies this function to the result. 069 * If evaluation of either function throws an exception, it is relayed to 070 * the caller of the composed function. 071 * 072 * @param <V> the type of input to the {@code before} function, and to the 073 * composed function 074 * @param before the function to apply before this function is applied 075 * @return a composed function that first applies the {@code before} 076 * function and then applies this function 077 * @throws NullPointerException if before is null 078 * 079 * @see #andThen(IOFunction) 080 */ 081 default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) { 082 Objects.requireNonNull(before); 083 return (V v) -> apply(before.apply(v)); 084 } 085 086 /** 087 * Returns a composed {@link IOFunction} that first applies the {@code before} 088 * function to its input, and then applies this function to the result. 089 * If evaluation of either function throws an exception, it is relayed to 090 * the caller of the composed function. 091 * 092 * @param before the supplier which feeds the application of this function 093 * @return a composed function that first applies the {@code before} 094 * function and then applies this function 095 * @throws NullPointerException if before is null 096 * 097 * @see #andThen(IOFunction) 098 */ 099 default IOSupplier<R> compose(final IOSupplier<? extends T> before) { 100 Objects.requireNonNull(before); 101 return () -> apply(before.get()); 102 } 103 104 /** 105 * Returns a composed {@link IOFunction} that first applies the {@code before} 106 * function to its input, and then applies this function to the result. 107 * If evaluation of either function throws an exception, it is relayed to 108 * the caller of the composed function. 109 * 110 * @param before the supplier which feeds the application of this function 111 * @return a composed function that first applies the {@code before} 112 * function and then applies this function 113 * @throws NullPointerException if before is null 114 * 115 * @see #andThen(IOFunction) 116 */ 117 default IOSupplier<R> compose(final Supplier<? extends T> before) { 118 Objects.requireNonNull(before); 119 return () -> apply(before.get()); 120 } 121 122 /** 123 * Returns a composed {@link IOFunction} that first applies this function to 124 * its input, and then applies the {@code after} function to the result. 125 * If evaluation of either function throws an exception, it is relayed to 126 * the caller of the composed function. 127 * 128 * @param <V> the type of output of the {@code after} function, and of the 129 * composed function 130 * @param after the function to apply after this function is applied 131 * @return a composed function that first applies this function and then 132 * applies the {@code after} function 133 * @throws NullPointerException if after is null 134 * 135 * @see #compose(IOFunction) 136 */ 137 default <V> IOFunction<T, V> andThen(IOFunction<? super R, ? extends V> after) { 138 Objects.requireNonNull(after); 139 return (T t) -> after.apply(apply(t)); 140 } 141 142 /** 143 * Returns a composed {@link IOFunction} that first applies this function to 144 * its input, and then applies the {@code after} function to the result. 145 * If evaluation of either function throws an exception, it is relayed to 146 * the caller of the composed function. 147 * 148 * @param <V> the type of output of the {@code after} function, and of the 149 * composed function 150 * @param after the function to apply after this function is applied 151 * @return a composed function that first applies this function and then 152 * applies the {@code after} function 153 * @throws NullPointerException if after is null 154 * 155 * @see #compose(IOFunction) 156 */ 157 default <V> IOFunction<T, V> andThen(Function<? super R, ? extends V> after) { 158 Objects.requireNonNull(after); 159 return (T t) -> after.apply(apply(t)); 160 } 161 162 /** 163 * Returns a composed {@link IOFunction} that first applies this function to 164 * its input, and then applies the {@code after} consumer to the result. 165 * If evaluation of either function throws an exception, it is relayed to 166 * the caller of the composed function. 167 * 168 * @param after the consumer to apply after this function is applied 169 * @return a composed function that first applies this function and then 170 * applies the {@code after} consumer 171 * @throws NullPointerException if after is null 172 * 173 * @see #compose(IOFunction) 174 */ 175 default IOConsumer<T> andThen(IOConsumer<? super R> after) { 176 Objects.requireNonNull(after); 177 return (T t) -> after.accept(apply(t)); 178 } 179 180 /** 181 * Returns a composed {@link IOFunction} that first applies this function to 182 * its input, and then applies the {@code after} consumer to the result. 183 * If evaluation of either function throws an exception, it is relayed to 184 * the caller of the composed function. 185 * 186 * @param after the consumer to apply after this function is applied 187 * @return a composed function that first applies this function and then 188 * applies the {@code after} consumer 189 * @throws NullPointerException if after is null 190 * 191 * @see #compose(IOFunction) 192 */ 193 default IOConsumer<T> andThen(Consumer<? super R> after) { 194 Objects.requireNonNull(after); 195 return (T t) -> after.accept(apply(t)); 196 } 197 198 /** 199 * Returns a {@link IOFunction} that always returns its input argument. 200 * 201 * @param <T> the type of the input and output objects to the function 202 * @return a function that always returns its input argument 203 */ 204 static <T> IOFunction<T, T> identity() { 205 return t -> t; 206 } 207}