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