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    *      https://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.FilterInputStream;
22  import java.io.IOException;
23  import java.io.UncheckedIOException;
24  
25  import org.apache.commons.io.build.AbstractStreamBuilder;
26  import org.apache.commons.io.function.Uncheck;
27  
28  /**
29   * A {@link BufferedReader} that throws {@link UncheckedIOException} instead of {@link IOException}.
30   * <p>
31   * To build an instance, use {@link Builder}.
32   * </p>
33   *
34   * @see Builder
35   * @see BufferedReader
36   * @see IOException
37   * @see UncheckedIOException
38   * @since 2.12.0
39   */
40  public final class UncheckedFilterInputStream extends FilterInputStream {
41  
42      // @formatter:off
43      /**
44       * Builds a new {@link UncheckedFilterInputStream}.
45       *
46       * <p>
47       * Using File IO:
48       * </p>
49       * <pre>{@code
50       * UncheckedFilterInputStream s = UncheckedFilterInputStream.builder()
51       *   .setFile(file)
52       *   .get();}
53       * </pre>
54       * <p>
55       * Using NIO Path:
56       * </p>
57       * <pre>{@code
58       * UncheckedFilterInputStream s = UncheckedFilterInputStream.builder()
59       *   .setPath(path)
60       *   .get();}
61       * </pre>
62       *
63       * @see #get()
64       */
65      // @formatter:on
66      public static class Builder extends AbstractStreamBuilder<UncheckedFilterInputStream, Builder> {
67  
68          /**
69           * Constructs a new builder of {@link UncheckedFilterInputStream}.
70           */
71          public Builder() {
72              // empty
73          }
74  
75          /**
76           * Builds a new {@link UncheckedFilterInputStream}.
77           * <p>
78           * You must set an aspect that supports {@link #getInputStream()} on this builder, otherwise, this method throws an exception.
79           * </p>
80           * <p>
81           * This builder uses the following aspects:
82           * </p>
83           * <ul>
84           * <li>{@link #getInputStream()} gets the target aspect.</li>
85           * </ul>
86           *
87           * @return a new instance.
88           * @throws UnsupportedOperationException if the origin cannot provide an {@link #getInputStream()}.
89           * @see #getInputStream()
90           * @see #getUnchecked()
91           */
92          @Override
93          public UncheckedFilterInputStream get() {
94              // This an unchecked class, so this method is as well.
95              return Uncheck.get(() -> new UncheckedFilterInputStream(this));
96          }
97  
98      }
99  
100     /**
101      * Constructs a new {@link Builder}.
102      *
103      * @return a new {@link Builder}.
104      */
105     public static Builder builder() {
106         return new Builder();
107     }
108 
109     /**
110      * Constructs a {@link UncheckedFilterInputStream}.
111      *
112      * @param builder A builder providing the underlying input stream.
113      * @throws IOException
114      */
115     @SuppressWarnings("resource") // caller closes
116     private UncheckedFilterInputStream(final Builder builder) throws IOException {
117         super(builder.getInputStream());
118     }
119 
120     /**
121      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
122      */
123     @Override
124     public int available() throws UncheckedIOException {
125         return Uncheck.getAsInt(super::available);
126     }
127 
128     /**
129      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
130      */
131     @Override
132     public void close() throws UncheckedIOException {
133         Uncheck.run(super::close);
134     }
135 
136     /**
137      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
138      */
139     @Override
140     public int read() throws UncheckedIOException {
141         return Uncheck.getAsInt(super::read);
142     }
143 
144     /**
145      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
146      */
147     @Override
148     public int read(final byte[] b) throws UncheckedIOException {
149         return Uncheck.apply(super::read, b);
150     }
151 
152     /**
153      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
154      */
155     @Override
156     public int read(final byte[] b, final int off, final int len) throws UncheckedIOException {
157         return Uncheck.apply(super::read, b, off, len);
158     }
159 
160     /**
161      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
162      */
163     @Override
164     public synchronized void reset() throws UncheckedIOException {
165         Uncheck.run(super::reset);
166     }
167 
168     /**
169      * Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
170      */
171     @Override
172     public long skip(final long n) throws UncheckedIOException {
173         return Uncheck.apply(super::skip, n);
174     }
175 
176 }