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 package org.apache.commons.io.input;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.function.Supplier;
22
23 import org.apache.commons.io.function.Erase;
24
25 /**
26 * Always throws an exception from all {@link InputStream} methods where {@link IOException} is declared.
27 * <p>
28 * This class is mostly useful for testing error handling.
29 * </p>
30 *
31 * @since 2.0
32 */
33 public class BrokenInputStream extends InputStream {
34
35 /**
36 * The singleton instance using a default IOException.
37 *
38 * @since 2.12.0
39 */
40 public static final BrokenInputStream INSTANCE = new BrokenInputStream();
41
42 /**
43 * A supplier for the exception that is thrown by all methods of this class.
44 */
45 private final Supplier<Throwable> exceptionSupplier;
46
47 /**
48 * Constructs a new stream that always throws an {@link IOException}.
49 */
50 public BrokenInputStream() {
51 this(() -> new IOException("Broken input stream"));
52 }
53
54 /**
55 * Constructs a new stream that always throws the given exception.
56 *
57 * @param exception the exception to be thrown.
58 * @deprecated Use {@link #BrokenInputStream(Throwable)}.
59 */
60 @Deprecated
61 public BrokenInputStream(final IOException exception) {
62 this(() -> exception);
63 }
64
65 /**
66 * Constructs a new stream that always throws the supplied exception.
67 *
68 * @param exceptionSupplier a supplier for the IOException or RuntimeException to be thrown.
69 * @since 2.12.0
70 */
71 public BrokenInputStream(final Supplier<Throwable> exceptionSupplier) {
72 this.exceptionSupplier = exceptionSupplier;
73 }
74
75 /**
76 * Constructs a new stream that always throws the given exception.
77 *
78 * @param exception the exception to be thrown.
79 * @since 2.16.0
80 */
81 public BrokenInputStream(final Throwable exception) {
82 this(() -> exception);
83 }
84
85 /**
86 * Throws the configured exception.
87 *
88 * @return nothing.
89 * @throws IOException always throws the exception configured in a constructor.
90 */
91 @Override
92 public int available() throws IOException {
93 throw rethrow();
94 }
95
96 /**
97 * Throws the configured exception.
98 *
99 * @throws IOException always throws the exception configured in a constructor.
100 */
101 @Override
102 public void close() throws IOException {
103 throw rethrow();
104 }
105
106 /**
107 * Throws the configured exception.
108 *
109 * @return nothing.
110 * @throws IOException always throws the exception configured in a constructor.
111 */
112 @Override
113 public int read() throws IOException {
114 throw rethrow();
115 }
116
117 /**
118 * Throws the configured exception.
119 *
120 * @throws IOException always throws the exception configured in a constructor.
121 */
122 @Override
123 public synchronized void reset() throws IOException {
124 throw rethrow();
125 }
126
127 /**
128 * Throws the configured exception from its supplier.
129 *
130 * @return Throws the configured exception from its supplier.
131 */
132 private RuntimeException rethrow() {
133 return Erase.rethrow(exceptionSupplier.get());
134 }
135
136 /**
137 * Throws the configured exception.
138 *
139 * @param n ignored.
140 * @return nothing.
141 * @throws IOException always throws the exception configured in a constructor.
142 */
143 @Override
144 public long skip(final long n) throws IOException {
145 throw rethrow();
146 }
147
148 }