    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.input;
    019
    020import java.io.BufferedReader;
    021import java.io.IOException;
    022import java.io.Reader;
    023import java.io.UncheckedIOException;
    024import java.nio.CharBuffer;
    025
    026import org.apache.commons.io.build.AbstractStreamBuilder;
    027import org.apache.commons.io.function.Uncheck;
    028
    029/**
    030 * A {@link BufferedReader} that throws {@link UncheckedIOException} instead of {@link IOException}.
    031 *
    032 * @see BufferedReader
    033 * @see IOException
    034 * @see UncheckedIOException
    035 * @since 2.12.0
    036 */
    037public final class UncheckedBufferedReader extends BufferedReader {
    038
    039    /**
    040     * Builds a new {@link UncheckedBufferedReader} instance.
    041     * <p>
    042     * Using File IO:
    043     * </p>
    044     * <pre>{@code
    045     * UncheckedBufferedReader s = UncheckedBufferedReader.builder()
    046     *   .setFile(file)
    047     *   .setBufferSize(8192)
    048     *   .setCharset(Charset.defaultCharset())
    049     *   .get()}
    050     * </pre>
    051     * <p>
    052     * Using NIO Path:
    053     * </p>
    054     * <pre>{@code
    055     * UncheckedBufferedReader s = UncheckedBufferedReader.builder()
    056     *   .setPath(path)
    057     *   .setBufferSize(8192)
    058     *   .setCharset(Charset.defaultCharset())
    059     *   .get()}
    060     * </pre>
    061     */
    062    public static class Builder extends AbstractStreamBuilder<UncheckedBufferedReader, Builder> {
    063
    064        /**
    065         * Constructs a new instance.
    066         *
    067         * @throws UnsupportedOperationException if the origin cannot be converted to a Reader.
    068         */
    069        @Override
    070        public UncheckedBufferedReader get() {
    071            // This an unchecked class, so this method is as well.
    072            return Uncheck.get(() -> new UncheckedBufferedReader(getOrigin().getReader(getCharset()), getBufferSize()));
    073        }
    074
    075    }
    076
    077    /**
    078     * Constructs a new {@link Builder}.
    079     *
    080     * @return a new {@link Builder}.
    081     */
    082    public static Builder builder() {
    083        return new Builder();
    084    }
    085
    086    /**
    087     * Creates a buffering character-input stream that uses an input buffer of the specified size.
    088     *
    089     * @param reader     A Reader
    090     * @param bufferSize Input-buffer size
    091     *
    092     * @throws IllegalArgumentException If {@code bufferSize <= 0}
    093     */
    094    private UncheckedBufferedReader(final Reader reader, final int bufferSize) {
    095        super(reader, bufferSize);
    096    }
    097
    098    /**
    099     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    100     */
    101    @Override
    102    public void close() throws UncheckedIOException {
    103        Uncheck.run(super::close);
    104    }
    105
    106    /**
    107     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    108     */
    109    @Override
    110    public void mark(final int readAheadLimit) throws UncheckedIOException {
    111        Uncheck.accept(super::mark, readAheadLimit);
    112    }
    113
    114    /**
    115     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    116     */
    117    @Override
    118    public int read() throws UncheckedIOException {
    119        return Uncheck.get(super::read);
    120    }
    121
    122    /**
    123     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    124     */
    125    @Override
    126    public int read(final char[] cbuf) throws UncheckedIOException {
    127        return Uncheck.apply(super::read, cbuf);
    128    }
    129
    130    /**
    131     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    132     */
    133    @Override
    134    public int read(final char[] cbuf, final int off, final int len) throws UncheckedIOException {
    135        return Uncheck.apply(super::read, cbuf, off, len);
    136    }
    137
    138    /**
    139     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    140     */
    141    @Override
    142    public int read(final CharBuffer target) throws UncheckedIOException {
    143        return Uncheck.apply(super::read, target);
    144    }
    145
    146    /**
    147     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    148     */
    149    @Override
    150    public String readLine() throws UncheckedIOException {
    151        return Uncheck.get(super::readLine);
    152    }
    153
    154    /**
    155     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    156     */
    157    @Override
    158    public boolean ready() throws UncheckedIOException {
    159        return Uncheck.get(super::ready);
    160    }
    161
    162    /**
    163     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    164     */
    165    @Override
    166    public void reset() throws UncheckedIOException {
    167        Uncheck.run(super::reset);
    168    }
    169
    170    /**
    171     * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
    172     */
    173    @Override
    174    public long skip(final long n) throws UncheckedIOException {
    175        return Uncheck.apply(super::skip, n);
    176    }
    177
    178}