📄 Update year in copyright line
[jSite.git] / src / main / java / de / todesbaum / util / io / TeeOutputStream.java
1 /*
2  * jSite - TeeOutputStream.java - Copyright Â© 2010–2019 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package de.todesbaum.util.io;
19
20 import java.io.IOException;
21 import java.io.OutputStream;
22
23 /**
24  * {@link OutputStream} that sends all data it receives to multiple other output
25  * streams. If an error occurs during a {@link #write(int)} to one of the
26  * underlying output streams no guarantees are made about how much data is sent
27  * to each stream, i.e. there is no good way to recover from such an error.
28  *
29  * @author <a href="mailto:bombe@pterodactylus.net">David â€˜Bombe’ Roden</a>
30  */
31 public class TeeOutputStream extends OutputStream {
32
33         /** The output streams. */
34         private final OutputStream[] outputStreams;
35
36         /**
37          * Creates a new tee output stream that sends all to all given output
38          * streams.
39          *
40          * @param outputStreams
41          *            The output streams to send all data to
42          */
43         public TeeOutputStream(OutputStream... outputStreams) {
44                 this.outputStreams = outputStreams;
45         }
46
47         /**
48          * {@inheritDoc}
49          * <p>
50          * An effort is made to close all output streams. If multiple exceptions
51          * occur, only the first exception is thrown after all output streams have
52          * been tried to close.
53          */
54         @Override
55         public void close() throws IOException {
56                 IOException occuredException = null;
57                 for (OutputStream outputStream : outputStreams) {
58                         try {
59                                 outputStream.flush();
60                         } catch (IOException ioe1) {
61                                 if (occuredException == null) {
62                                         occuredException = ioe1;
63                                 }
64                         }
65                 }
66                 if (occuredException != null) {
67                         throw occuredException;
68                 }
69         }
70
71         /**
72          * {@inheritDoc}
73          * <p>
74          * An effort is made to flush all output streams. If multiple exceptions
75          * occur, only the first exception is thrown after all output streams have
76          * been tried to flush.
77          */
78         @Override
79         public void flush() throws IOException {
80                 IOException occuredException = null;
81                 for (OutputStream outputStream : outputStreams) {
82                         try {
83                                 outputStream.flush();
84                         } catch (IOException ioe1) {
85                                 if (occuredException == null) {
86                                         occuredException = ioe1;
87                                 }
88                         }
89                 }
90                 if (occuredException != null) {
91                         throw occuredException;
92                 }
93         }
94
95         /**
96          * {@inheritDoc}
97          */
98         @Override
99         public void write(byte[] buffer) throws IOException {
100                 for (OutputStream outputStream : outputStreams) {
101                         outputStream.write(buffer);
102                 }
103         }
104
105         /**
106          * {@inheritDoc}
107          */
108         @Override
109         public void write(byte[] buffer, int offset, int length) throws IOException {
110                 for (OutputStream outputStream : outputStreams) {
111                         outputStream.write(buffer, offset, length);
112                 }
113         }
114
115         /**
116          * {@inheritDoc}
117          */
118         @Override
119         public void write(int data) throws IOException {
120                 for (OutputStream outputStream : outputStreams) {
121                         outputStream.write(data);
122                 }
123         }
124
125 }