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 * @see #compose(IOFunction) 057 */ 058 default IOConsumer<T> andThen(final Consumer<? super R> after) { 059 Objects.requireNonNull(after, "after"); 060 return (final T t) -> after.accept(apply(t)); 061 } 062 063 /** 064 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 065 * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the 066 * caller of the composed function. 067 * 068 * @param <V> the type of output of the {@code after} function, and of the composed function 069 * @param after the function to apply after this function is applied 070 * @return a composed function that first applies this function and then applies the {@code after} function 071 * @throws NullPointerException if after is null 072 * @see #compose(IOFunction) 073 */ 074 default <V> IOFunction<T, V> andThen(final Function<? super R, ? extends V> after) { 075 Objects.requireNonNull(after, "after"); 076 return (final T t) -> after.apply(apply(t)); 077 } 078 079 /** 080 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 081 * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the 082 * caller of the composed function. 083 * 084 * @param after the consumer to apply after this function is applied 085 * @return a composed function that first applies this function and then applies the {@code after} consumer 086 * @throws NullPointerException if after is null 087 * @see #compose(IOFunction) 088 */ 089 default IOConsumer<T> andThen(final IOConsumer<? super R> after) { 090 Objects.requireNonNull(after, "after"); 091 return (final T t) -> after.accept(apply(t)); 092 } 093 094 /** 095 * Returns a composed {@link IOFunction} that first applies this function to its input, and then applies the 096 * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the 097 * caller of the composed function. 098 * 099 * @param <V> the type of output of the {@code after} function, and of the composed function 100 * @param after the function to apply after this function is applied 101 * @return a composed function that first applies this function and then applies the {@code after} function 102 * @throws NullPointerException if after is null 103 * @see #compose(IOFunction) 104 */ 105 default <V> IOFunction<T, V> andThen(final IOFunction<? super R, ? extends V> after) { 106 Objects.requireNonNull(after, "after"); 107 return (final T t) -> after.apply(apply(t)); 108 } 109 110 /** 111 * Applies this function to the given argument. 112 * 113 * @param t the function argument 114 * @return the function result 115 * @throws IOException if an I/O error occurs. 116 */ 117 R apply(T t) throws IOException; 118 119 /** 120 * Creates a {@link Function} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}. 121 * 122 * @return an UncheckedIOException Function. 123 * @since 2.12.0 124 */ 125 default Function<T, R> asFunction() { 126 return t -> Uncheck.apply(this, t); 127 } 128 129 /** 130 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 131 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 132 * composed function. 133 * 134 * @param <V> the type of input to the {@code before} function, and to the composed function 135 * @param before the function to apply before this function is applied 136 * @return a composed function that first applies the {@code before} function and then applies this function 137 * @throws NullPointerException if before is null 138 * @see #andThen(IOFunction) 139 */ 140 default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) { 141 Objects.requireNonNull(before, "before"); 142 return (final V v) -> apply(before.apply(v)); 143 } 144 145 /** 146 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 147 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 148 * composed function. 149 * 150 * @param <V> the type of input to the {@code before} function, and to the composed function 151 * @param before the function to apply before this function is applied 152 * @return a composed function that first applies the {@code before} function and then applies this function 153 * @throws NullPointerException if before is null 154 * @see #andThen(IOFunction) 155 */ 156 default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) { 157 Objects.requireNonNull(before, "before"); 158 return (final V v) -> apply(before.apply(v)); 159 } 160 161 /** 162 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 163 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 164 * composed function. 165 * 166 * @param before the supplier which feeds the application of this function 167 * @return a composed function that first applies the {@code before} function and then applies this function 168 * @throws NullPointerException if before is null 169 * @see #andThen(IOFunction) 170 */ 171 default IOSupplier<R> compose(final IOSupplier<? extends T> before) { 172 Objects.requireNonNull(before, "before"); 173 return () -> apply(before.get()); 174 } 175 176 /** 177 * Returns a composed {@link IOFunction} that first applies the {@code before} function to its input, and then applies 178 * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the 179 * composed function. 180 * 181 * @param before the supplier which feeds the application of this function 182 * @return a composed function that first applies the {@code before} function and then applies this function 183 * @throws NullPointerException if before is null 184 * @see #andThen(IOFunction) 185 */ 186 default IOSupplier<R> compose(final Supplier<? extends T> before) { 187 Objects.requireNonNull(before, "before"); 188 return () -> apply(before.get()); 189 } 190}