View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.io.input;
19  
20  import java.io.BufferedReader;
21  import java.io.IOException;
22  import java.io.Reader;
23  import java.io.UncheckedIOException;
24  import java.nio.CharBuffer;
25  
26  import org.apache.commons.io.build.AbstractStreamBuilder;
27  import org.apache.commons.io.function.Uncheck;
28  
29  /**
30   * A {@link BufferedReader} that throws {@link UncheckedIOException} instead of {@link IOException}.
31   * <p>
32   * To build an instance, use {@link Builder}.
33   * </p>
34   *
35   * @see Builder
36   * @see BufferedReader
37   * @see IOException
38   * @see UncheckedIOException
39   * @since 2.12.0
40   */
41  public final class UncheckedBufferedReader extends BufferedReader {
42  
43      // @formatter:off
44      /**
45       * Builds a new {@link UncheckedBufferedReader}.
46       *
47       * <p>
48       * Using File IO:
49       * </p>
50       * <pre>{@code
51       * UncheckedBufferedReader s = UncheckedBufferedReader.builder()
52       *   .setFile(file)
53       *   .setBufferSize(8192)
54       *   .setCharset(Charset.defaultCharset())
55       *   .get();}
56       * </pre>
57       * <p>
58       * Using NIO Path:
59       * </p>
60       * <pre>{@code
61       * UncheckedBufferedReader s = UncheckedBufferedReader.builder()
62       *   .setPath(path)
63       *   .setBufferSize(8192)
64       *   .setCharset(Charset.defaultCharset())
65       *   .get();}
66       * </pre>
67       *
68       * @see #get()
69       */
70      // @formatter:on
71      public static class Builder extends AbstractStreamBuilder<UncheckedBufferedReader, Builder> {
72  
73          /**
74           * Constructs a new builder of {@link UncheckedBufferedReader}.
75           */
76          public Builder() {
77              // empty
78          }
79  
80          /**
81           * Builds a new {@link UncheckedBufferedReader}.
82           *
83           * <p>
84           * You must set an aspect that supports {@link #getReader()} on this builder, otherwise, this method throws an exception.
85           * </p>
86           * <p>
87           * This builder uses the following aspects:
88           * </p>
89           * <ul>
90           * <li>{@link #getReader()} gets the target aspect.</li>
91           * <li>{@link #getBufferSize()}</li>
92           * </ul>
93           *
94           * @return a new instance.
95           * @throws UnsupportedOperationException if the origin cannot provide a {@link Reader}.
96           * @throws IllegalStateException if the {@code origin} is {@code null}.
97           * @see #getReader()
98           * @see #getBufferSize()
99           * @see #getUnchecked()
100          */
101         @SuppressWarnings("resource")
102         @Override
103         public UncheckedBufferedReader get() {
104             // This an unchecked class, so this method is as well.
105             return Uncheck.get(() -> new UncheckedBufferedReader(getReader(), getBufferSize()));
106         }
107 
108     }
109 
110     /**
111      * Constructs a new {@link Builder}.
112      *
113      * @return a new {@link Builder}.
114      */
115     public static Builder builder() {
116         return new Builder();
117     }
118 
119     /**
120      * Constructs a buffering character-input stream that uses an input buffer of the specified size.
121      *
122      * @param reader     A Reader
123      * @param bufferSize Input-buffer size
124      * @throws IllegalArgumentException If {@code bufferSize <= 0}
125      */
126     private UncheckedBufferedReader(final Reader reader, final int bufferSize) {
127         super(reader, bufferSize);
128     }
129 
130     /**
131      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
132      */
133     @Override
134     public void close() throws UncheckedIOException {
135         Uncheck.run(super::close);
136     }
137 
138     /**
139      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
140      */
141     @Override
142     public void mark(final int readAheadLimit) throws UncheckedIOException {
143         Uncheck.accept(super::mark, readAheadLimit);
144     }
145 
146     /**
147      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
148      */
149     @Override
150     public int read() throws UncheckedIOException {
151         return Uncheck.getAsInt(super::read);
152     }
153 
154     /**
155      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
156      */
157     @Override
158     public int read(final char[] cbuf) throws UncheckedIOException {
159         return Uncheck.apply(super::read, cbuf);
160     }
161 
162     /**
163      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
164      */
165     @Override
166     public int read(final char[] cbuf, final int off, final int len) throws UncheckedIOException {
167         return Uncheck.apply(super::read, cbuf, off, len);
168     }
169 
170     /**
171      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
172      */
173     @Override
174     public int read(final CharBuffer target) throws UncheckedIOException {
175         return Uncheck.apply(super::read, target);
176     }
177 
178     /**
179      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
180      */
181     @Override
182     public String readLine() throws UncheckedIOException {
183         return Uncheck.get(super::readLine);
184     }
185 
186     /**
187      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
188      */
189     @Override
190     public boolean ready() throws UncheckedIOException {
191         return Uncheck.getAsBoolean(super::ready);
192     }
193 
194     /**
195      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
196      */
197     @Override
198     public void reset() throws UncheckedIOException {
199         Uncheck.run(super::reset);
200     }
201 
202     /**
203      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
204      */
205     @Override
206     public long skip(final long n) throws UncheckedIOException {
207         return Uncheck.apply(super::skip, n);
208     }
209 
210 }