    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.stream.Stream;
    025
    026import org.apache.commons.io.IOExceptionList;
    027import org.apache.commons.io.IOIndexedException;
    028
    029/**
    030 * Like {@link Consumer} but throws {@link IOException}.
    031 *
    032 * @param <T> the type of the input to the operations.
    033 * @since 2.7
    034 */
    035@FunctionalInterface
    036public interface IOConsumer<T> {
    037
    038    /**
    039     * Consider private.
    040     */
    041    IOConsumer<?> NOOP_IO_CONSUMER = t -> {/* noop */};
    042
    043    /**
    044     * Performs an action for each element of the collection gathering any exceptions.
    045     *
    046     * @param action The action to apply to each input element.
    047     * @param iterable The input to stream.
    048     * @param <T> The element type.
    049     * @throws IOExceptionList if any I/O errors occur.
    050     * @since 2.12.0
    051     */
    052    static <T> void forAll(final IOConsumer<T> action, final Iterable<T> iterable) throws IOExceptionList {
    053        IOStreams.forAll(IOStreams.of(iterable), action);
    054    }
    055
    056    /**
    057     * Performs an action for each element of the collection gathering any exceptions.
    058     *
    059     * @param action The action to apply to each input element.
    060     * @param stream The input to stream.
    061     * @param <T> The element type.
    062     * @throws IOExceptionList if any I/O errors occur.
    063     * @since 2.12.0
    064     */
    065    static <T> void forAll(final IOConsumer<T> action, final Stream<T> stream) throws IOExceptionList {
    066        IOStreams.forAll(stream, action, IOIndexedException::new);
    067    }
    068
    069    /**
    070     * Performs an action for each element of the array gathering any exceptions.
    071     *
    072     * @param action The action to apply to each input element.
    073     * @param array The input to stream.
    074     * @param <T> The element type.
    075     * @throws IOExceptionList if any I/O errors occur.
    076     * @since 2.12.0
    077     */
    078    @SafeVarargs
    079    static <T> void forAll(final IOConsumer<T> action, final T... array) throws IOExceptionList {
    080        IOStreams.forAll(IOStreams.of(array), action);
    081    }
    082
    083    /**
    084     * Performs an action for each element of the collection, stopping at the first exception.
    085     *
    086     * @param <T> The element type.
    087     * @param iterable The input to stream.
    088     * @param action The action to apply to each input element.
    089     * @throws IOException if an I/O error occurs.
    090     * @since 2.12.0
    091     */
    092    static <T> void forEach(final Iterable<T> iterable, final IOConsumer<T> action) throws IOException {
    093        IOStreams.forEach(IOStreams.of(iterable), action);
    094    }
    095
    096    /**
    097     * Performs an action for each element of the stream, stopping at the first exception.
    098     *
    099     * @param <T> The element type.
    100     * @param stream The input to stream.
    101     * @param action The action to apply to each input element.
    102     * @throws IOException if an I/O error occurs.
    103     * @since 2.12.0
    104     */
    105    static <T> void forEach(final Stream<T> stream, final IOConsumer<T> action) throws IOException {
    106        IOStreams.forEach(stream, action);
    107    }
    108
    109    /**
    110     * Performs an action for each element of this array, stopping at the first exception.
    111     *
    112     * @param <T> The element type.
    113     * @param array The input to stream.
    114     * @param action The action to apply to each input element.
    115     * @throws IOException if an I/O error occurs.
    116     * @since 2.12.0
    117     */
    118    static <T> void forEach(final T[] array, final IOConsumer<T> action) throws IOException {
    119        IOStreams.forEach(IOStreams.of(array), action);
    120    }
    121
    122    /**
    123     * Returns the constant no-op consumer.
    124     *
    125     * @param <T> Type consumer type.
    126     * @return a constant no-op consumer.
    127     * @since 2.9.0
    128     */
    129    @SuppressWarnings("unchecked")
    130    static <T> IOConsumer<T> noop() {
    131        return (IOConsumer<T>) NOOP_IO_CONSUMER;
    132    }
    133
    134    /**
    135     * Performs this operation on the given argument.
    136     *
    137     * @param t the input argument
    138     * @throws IOException if an I/O error occurs.
    139     */
    140    void accept(T t) throws IOException;
    141
    142    /**
    143     * Returns a composed {@link IOConsumer} that performs, in sequence, this operation followed by the {@code after}
    144     * operation. If performing either operation throws an exception, it is relayed to the caller of the composed operation.
    145     * If performing this operation throws an exception, the {@code after} operation will not be performed.
    146     *
    147     * @param after the operation to perform after this operation
    148     * @return a composed {@link Consumer} that performs in sequence this operation followed by the {@code after} operation
    149     * @throws NullPointerException if {@code after} is null
    150     */
    151    default IOConsumer<T> andThen(final IOConsumer<? super T> after) {
    152        Objects.requireNonNull(after, "after");
    153        return (final T t) -> {
    154            accept(t);
    155            after.accept(t);
    156        };
    157    }
    158
    159    /**
    160     * Creates a {@link Consumer} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}.
    161     *
    162     * @return an UncheckedIOException Consumer.
    163     * @since 2.12.0
    164     */
    165    default Consumer<T> asConsumer() {
    166        return t -> Uncheck.accept(this, t);
    167    }
    168
    169}