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