1 /*
2 * Copyright 2007, 2008 Ange Optimization ApS
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package eu.simuline.octave.util;
17
18 import java.io.IOException;
19 import java.io.Writer;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 /**
25 * Will protect a Writer from being closed by {@link #close()},
26 * useful for protecting stdout and stderr from being closed.
27 * Trying to close via {@link #close()} results in loosing connection
28 * whereas {@link #reallyClose()} really closes the writer.
29 *
30 * @author Kim Hansen
31 */
32 public final class NoCloseWriter extends Writer {
33
34 private static final Log LOG = LogFactory.getLog(NoCloseWriter.class);
35
36 /**
37 * A writer or <code>null</code>.
38 * The latter is the case if initialized with <code>null</code>,
39 * or if tried to close via {@link #close()}.
40 * In the latter case
41 * it is not even possible to close with {@link #reallyClose()}.
42 */
43 private Writer writer;
44
45 /**
46 * Create a NoCloseWriter that will protect writer.
47 *
48 * @param writer
49 * the writer to be protected from being closed by {@link #close()}.
50 */
51 public NoCloseWriter(final Writer writer) {
52 this.writer = writer;
53 }
54
55 @Override
56 public void write(final char[] cbuf, final int off, final int len)
57 throws IOException {
58
59 if (this.writer == null) {
60 return;
61 }
62 this.writer.write(cbuf, off, len);
63 }
64
65 @Override
66 public void flush() throws IOException {
67 if (this.writer == null) {
68 return;
69 }
70 this.writer.flush();
71 }
72
73 /**
74 * Flushes the writer and looses the connection to it.
75 * No close and also in future no close possible.
76 *
77 * @throws IOException
78 * from the underlying writer.
79 * @see #reallyClose()
80 */
81 @Override
82 public void close() throws IOException {
83 LOG.debug("ignoring close() on a writer");
84 if (this.writer == null) {
85 return;
86 }
87 this.writer.flush();
88 this.writer = null;
89 }
90
91 /**
92 * Really closes the underlying writer, with one exception ;-).
93 *
94 * @throws IOException
95 * from the underlying writer.
96 * @throws NullPointerException
97 * if the NoCloseWriter has been closed via {@link #close()}.
98 */
99 public void reallyClose() throws IOException {
100 LOG.debug("reallyClose() a writer");
101 this.writer.close();
102 }
103
104 }