    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.Closeable;
    021import java.io.IOException;
    022import java.io.UncheckedIOException;
    023import java.util.stream.BaseStream;
    024import java.util.stream.Stream;
    025
    026/**
    027 * Like {@link BaseStream} but throws {@link IOException}.
    028 *
    029 * @param <T> the type of the stream elements.
    030 * @param <S> the type of the IO stream extending {@code IOBaseStream}.
    031 * @param <B> the type of the stream extending {@code BaseStream}.
    032 * @since 2.12.0
    033 */
    034public interface IOBaseStream<T, S extends IOBaseStream<T, S, B>, B extends BaseStream<T, B>> extends Closeable {
    035
    036    /**
    037     * Creates a {@link BaseStream} for this instance that throws {@link UncheckedIOException} instead of
    038     * {@link IOException}.
    039     *
    040     * @return an {@link UncheckedIOException} {@link BaseStream}.
    041     */
    042    @SuppressWarnings("unchecked")
    043    default BaseStream<T, B> asBaseStream() {
    044        return new UncheckedIOBaseStream<>((S) this);
    045    }
    046
    047    /**
    048     * Like {@link BaseStream#close()}.
    049     *
    050     * @see BaseStream#close()
    051     */
    052    @Override
    053    default void close() {
    054        unwrap().close();
    055    }
    056
    057    /**
    058     * Like {@link BaseStream#isParallel()}.
    059     *
    060     * @return See {@link BaseStream#isParallel() delegate}.
    061     * @see BaseStream#isParallel()
    062     */
    063    @SuppressWarnings("resource") // for unwrap()
    064    default boolean isParallel() {
    065        return unwrap().isParallel();
    066    }
    067
    068    /**
    069     * Like {@link BaseStream#iterator()}.
    070     *
    071     * @return See {@link BaseStream#iterator() delegate}.
    072     * @see BaseStream#iterator()
    073     */
    074    @SuppressWarnings("resource") // for unwrap()
    075    default IOIterator<T> iterator() {
    076        return IOIteratorAdapter.adapt(unwrap().iterator());
    077    }
    078
    079    /**
    080     * Like {@link BaseStream#onClose(Runnable)}.
    081     *
    082     * @param closeHandler See {@link BaseStream#onClose(Runnable) delegate}.
    083     * @return See {@link BaseStream#onClose(Runnable) delegate}.
    084     * @throws IOException if an I/O error occurs.
    085     * @see BaseStream#onClose(Runnable)
    086     */
    087    @SuppressWarnings({"unused", "resource"}) // throws IOException, unwrap()
    088    default S onClose(final IORunnable closeHandler) throws IOException {
    089        return wrap(unwrap().onClose(() -> Erase.run(closeHandler)));
    090    }
    091
    092    /**
    093     * Like {@link BaseStream#parallel()}.
    094     *
    095     * @return See {@link BaseStream#parallel() delegate}.
    096     * @see BaseStream#parallel()
    097     */
    098    @SuppressWarnings({"resource", "unchecked"}) // for unwrap(), this
    099    default S parallel() {
    100        return isParallel() ? (S) this : wrap(unwrap().parallel());
    101    }
    102
    103    /**
    104     * Like {@link BaseStream#sequential()}.
    105     *
    106     * @return See {@link BaseStream#sequential() delegate}.
    107     * @see BaseStream#sequential()
    108     */
    109    @SuppressWarnings({"resource", "unchecked"}) // for unwrap(), this
    110    default S sequential() {
    111        return isParallel() ? wrap(unwrap().sequential()) : (S) this;
    112    }
    113
    114    /**
    115     * Like {@link BaseStream#spliterator()}.
    116     *
    117     * @return See {@link BaseStream#spliterator() delegate}.
    118     * @see BaseStream#spliterator()
    119     */
    120    @SuppressWarnings("resource") // for unwrap()
    121    default IOSpliterator<T> spliterator() {
    122        return IOSpliteratorAdapter.adapt(unwrap().spliterator());
    123    }
    124
    125    /**
    126     * Like {@link BaseStream#unordered()}.
    127     *
    128     * @return See {@link BaseStream#unordered() delegate}.
    129     * @see java.util.stream.BaseStream#unordered()
    130     */
    131    @SuppressWarnings("resource") // for unwrap()
    132    default S unordered() {
    133        return wrap(unwrap().unordered());
    134    }
    135
    136    /**
    137     * Unwraps this instance and returns the underlying {@link Stream}.
    138     * <p>
    139     * Implementations may not have anything to unwrap and that behavior is undefined for now.
    140     * </p>
    141     *
    142     * @return the underlying stream.
    143     */
    144    B unwrap();
    145
    146    /**
    147     * Wraps a {@link Stream}.
    148     *
    149     * @param delegate The delegate.
    150     * @return An IO stream.
    151     */
    152    S wrap(B delegate);
    153
    154}