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 }