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.io.UncheckedIOException; 022import java.util.Objects; 023import java.util.function.Consumer; 024import java.util.function.Function; 025import java.util.function.Supplier; 026 027/** 028 * Like {@link Function} but throws {@link IOException}. 029 * 030 * @param <T> the type of the input to the operations. 031 * @param <R> the return type of the operations. 032 * @since 2.7 033 */ 034@FunctionalInterface 035public interface IOFunction<T, R> { 036 037 /** 038 * Returns a {@link IOFunction} that always returns its input argument. 039 * 040 * @param <T> the type of the input and output objects to the function 041 * @return a function that always returns its input argument 042 */ 043 @SuppressWarnings("unchecked") 044 static <T> IOFunction<T, T> identity() { 045 return Constants.IO_FUNCTION_ID; 046 } 047 048 /** 049 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 050 * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the 051 * caller of the composed function. 052 * 053 * @param after the consumer to apply after this function is applied 054 * @return a composed function that first applies this function and then applies the {@code after} consumer 055 * @throws NullPointerException if after is null 056 * 057 * @see #compose(IOFunction) 058 */ 059 default IOConsumer<T> andThen(final Consumer<? super R> after) { 060 Objects.requireNonNull(after, "after"); 061 return (final T t) -> after.accept(apply(t)); 062 } 063 064 /** 065 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 066 * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the 067 * caller of the composed function. 068 * 069 * @param <V> the type of output of the {@code after} function, and of the composed function 070 * @param after the function to apply after this function is applied 071 * @return a composed function that first applies this function and then applies the {@code after} function 072 * @throws NullPointerException if after is null 073 * 074 * @see #compose(IOFunction) 075 */ 076 default <V> IOFunction<T, V> andThen(final Function<? super R, ? extends V> after) { 077 Objects.requireNonNull(after, "after"); 078 return (final T t) -> after.apply(apply(t)); 079 } 080 081 /** 082 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 083 * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the 084 * caller of the composed function. 085 * 086 * @param after the consumer to apply after this function is applied 087 * @return a composed function that first applies this function and then applies the {@code after} consumer 088 * @throws NullPointerException if after is null 089 * 090 * @see #compose(IOFunction) 091 */ 092 default IOConsumer<T> andThen(final IOConsumer<? super R> after) { 093 Objects.requireNonNull(after, "after"); 094 return (final T t) -> after.accept(apply(t)); 095 } 096 097 /** 098 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 099 * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the 100 * caller of the composed function. 101 * 102 * @param <V> the type of output of the {@code after} function, and of the composed function 103 * @param after the function to apply after this function is applied 104 * @return a composed function that first applies this function and then applies the {@code after} function 105 * @throws NullPointerException if after is null 106 * 107 * @see #compose(IOFunction) 108 */ 109 default <V> IOFunction<T, V> andThen(final IOFunction<? super R, ? extends V> after) { 110 Objects.requireNonNull(after, "after"); 111 return (final T t) -> after.apply(apply(t)); 112 } 113 114 /** 115 * Applies this function to the given argument. 116 * 117 * @param t the function argument 118 * @return the function result 119 * @throws IOException if an I/O error occurs. 120 */ 121 R apply(final T t) throws IOException; 122 123 /** 124 * Creates a {@link Function} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}. 125 * 126 * @return an UncheckedIOException Function. 127 * @since 2.12.0 128 */ 129 default Function<T, R> asFunction() { 130 return t -> Uncheck.apply(this, t); 131 } 132 133 /** 134 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 135 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 136 * composed function. 137 * 138 * @param <V> the type of input to the {@code before} function, and to the composed function 139 * @param before the function to apply before this function is applied 140 * @return a composed function that first applies the {@code before} function and then applies this function 141 * @throws NullPointerException if before is null 142 * 143 * @see #andThen(IOFunction) 144 */ 145 default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) { 146 Objects.requireNonNull(before, "before"); 147 return (final V v) -> apply(before.apply(v)); 148 } 149 150 /** 151 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 152 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 153 * composed function. 154 * 155 * @param <V> the type of input to the {@code before} function, and to the composed function 156 * @param before the function to apply before this function is applied 157 * @return a composed function that first applies the {@code before} function and then applies this function 158 * @throws NullPointerException if before is null 159 * 160 * @see #andThen(IOFunction) 161 */ 162 default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) { 163 Objects.requireNonNull(before, "before"); 164 return (final V v) -> apply(before.apply(v)); 165 } 166 167 /** 168 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 169 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 170 * composed function. 171 * 172 * @param before the supplier which feeds the application of this function 173 * @return a composed function that first applies the {@code before} function and then applies this function 174 * @throws NullPointerException if before is null 175 * 176 * @see #andThen(IOFunction) 177 */ 178 default IOSupplier<R> compose(final IOSupplier<? extends T> before) { 179 Objects.requireNonNull(before, "before"); 180 return () -> apply(before.get()); 181 } 182 183 /** 184 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 185 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 186 * composed function. 187 * 188 * @param before the supplier which feeds the application of this function 189 * @return a composed function that first applies the {@code before} function and then applies this function 190 * @throws NullPointerException if before is null 191 * 192 * @see #andThen(IOFunction) 193 */ 194 default IOSupplier<R> compose(final Supplier<? extends T> before) { 195 Objects.requireNonNull(before, "before"); 196 return () -> apply(before.get()); 197 } 198}