001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.io.output; 018 019import java.io.IOException; 020import java.io.OutputStream; 021import java.util.function.Function; 022import java.util.function.Supplier; 023 024import org.apache.commons.io.function.Erase; 025 026/** 027 * Always throws an exception from all {@link OutputStream} methods where {@link IOException} is declared. 028 * <p> 029 * This class is mostly useful for testing error handling. 030 * </p> 031 * 032 * @since 2.0 033 */ 034public class BrokenOutputStream extends OutputStream { 035 036 /** 037 * The singleton instance using a default IOException. 038 * 039 * @since 2.12.0 040 */ 041 public static final BrokenOutputStream INSTANCE = new BrokenOutputStream(); 042 043 /** 044 * Supplies the exception that is thrown by all methods of this class. 045 */ 046 private final Function<String, Throwable> exceptionFunction; 047 048 /** 049 * Constructs a new stream that always throws an {@link IOException}. 050 */ 051 public BrokenOutputStream() { 052 this(m -> new IOException("Broken output stream: " + m)); 053 } 054 055 /** 056 * Constructs a new stream that always throws the given exception. 057 * 058 * @param exception the exception to be thrown. 059 * @deprecated Use {@link #BrokenOutputStream(Throwable)}. 060 */ 061 @Deprecated 062 public BrokenOutputStream(final IOException exception) { 063 this(m -> exception); 064 } 065 066 /** 067 * Constructs a new stream that always throws the supplied exception. 068 * <p> 069 * This class uses the invoked method name as the function input. 070 * </p> 071 * 072 * @param exceptionFunction a supplier for the IOException or RuntimeException to be thrown. 073 * @since 2.19.0 074 */ 075 public BrokenOutputStream(final Function<String, Throwable> exceptionFunction) { 076 this.exceptionFunction = exceptionFunction; 077 } 078 079 /** 080 * Constructs a new stream that always throws the supplied exception. 081 * 082 * @param exceptionSupplier a supplier for the IOException or RuntimeException to be thrown. 083 * @since 2.12.0 084 * @deprecated Use {@link #BrokenOutputStream(Function)}. 085 */ 086 @Deprecated 087 public BrokenOutputStream(final Supplier<Throwable> exceptionSupplier) { 088 this.exceptionFunction = m -> exceptionSupplier.get(); 089 } 090 091 /** 092 * Constructs a new stream that always throws the given exception. 093 * 094 * @param exception the exception to be thrown. 095 * @since 2.16.0 096 */ 097 public BrokenOutputStream(final Throwable exception) { 098 this(m -> exception); 099 } 100 101 /** 102 * Throws the configured exception. 103 * 104 * @throws IOException always throws the exception configured in a constructor. 105 */ 106 @Override 107 public void close() throws IOException { 108 throw rethrow("close()"); 109 } 110 111 /** 112 * Throws the configured exception. 113 * 114 * @throws IOException always throws the exception configured in a constructor. 115 */ 116 @Override 117 public void flush() throws IOException { 118 throw rethrow("flush()"); 119 } 120 121 /** 122 * Throws the configured exception from its supplier. 123 * 124 * @param method The exception function argument. 125 * @return Throws the configured exception from its supplier. 126 */ 127 private RuntimeException rethrow(final String method) { 128 return Erase.rethrow(exceptionFunction.apply(method)); 129 } 130 131 /** 132 * Throws the configured exception. 133 * 134 * @param b ignored. 135 * @throws IOException always throws the exception configured in a constructor. 136 */ 137 @Override 138 public void write(final int b) throws IOException { 139 throw rethrow("write(int)"); 140 } 141 142}