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.output;
18
19 import java.io.IOException;
20 import java.io.Writer;
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 Writer} 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 BrokenWriter extends Writer {
34
35 /**
36 * The singleton instance using a default IOException.
37 *
38 * @since 2.12.0
39 */
40 public static final BrokenWriter INSTANCE = new BrokenWriter();
41
42 /**
43 * Supplies the exception that is thrown by all methods of this class.
44 */
45 private final Supplier<Throwable> exceptionSupplier;
46
47 /**
48 * Constructs a new writer that always throws an {@link IOException}.
49 */
50 public BrokenWriter() {
51 this(() -> new IOException("Broken writer"));
52 }
53
54 /**
55 * Constructs a new writer that always throws the given exception.
56 *
57 * @param exception the exception to be thrown.
58 * @deprecated Use {@link #BrokenWriter(Throwable)}.
59 */
60 @Deprecated
61 public BrokenWriter(final IOException exception) {
62 this(() -> exception);
63 }
64
65 /**
66 * Constructs a new writer 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 BrokenWriter(final Supplier<Throwable> exceptionSupplier) {
72 this.exceptionSupplier = exceptionSupplier;
73 }
74
75 /**
76 * Constructs a new writer that always throws the given exception.
77 *
78 * @param exception the exception to be thrown.
79 * @since 2.16.0
80 */
81 public BrokenWriter(final Throwable exception) {
82 this(() -> exception);
83 }
84
85 /**
86 * Throws the configured exception.
87 *
88 * @throws IOException always throws the exception configured in a constructor.
89 */
90 @Override
91 public void close() throws IOException {
92 throw rethrow();
93 }
94
95 /**
96 * Throws the configured exception.
97 *
98 * @throws IOException always throws the exception configured in a constructor.
99 */
100 @Override
101 public void flush() throws IOException {
102 throw rethrow();
103 }
104
105 /**
106 * Throws the configured exception from its supplier.
107 *
108 * @return Throws the configured exception from its supplier.
109 */
110 private RuntimeException rethrow() {
111 return Erase.rethrow(exceptionSupplier.get());
112 }
113
114 /**
115 * Throws the configured exception.
116 *
117 * @param cbuf ignored.
118 * @param off ignored.
119 * @param len ignored.
120 * @throws IOException always throws the exception configured in a constructor.
121 */
122 @Override
123 public void write(final char[] cbuf, final int off, final int len) throws IOException {
124 throw rethrow();
125 }
126
127 }