File: LogStream.java

package info (click to toggle)
imagej 1.54g-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,520 kB
  • sloc: java: 132,209; sh: 286; xml: 255; makefile: 6
file content (203 lines) | stat: -rw-r--r-- 6,520 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package ij.io;
import ij.IJ;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

/**
 * This class provides the functionality to divert output sent to the System.out
 * and System.err streams to ImageJ's log console. The purpose is to allow 
 * use of existing Java classes or writing new generic Java classes that only 
 * output to System.out and are thus less dependent on ImageJ.
 * See the ImageJ plugin Redirect_System_Streams at
 *    http://staff.fh-hagenberg.at/burger/imagej/
 * for usage examples.
 *
 * @author Wilhelm Burger (wilbur at ieee.org)
 * See Also: Redirect_System_Streams (http://staff.fh-hagenberg.at/burger/imagej/)
 */
public class LogStream extends PrintStream {
	
	private static String outPrefix = "out> ";	// prefix string for System.out
	private static String errPrefix = "err >";	// prefix string for System.err
	
	private static PrintStream originalSystemOut = null;
	private static PrintStream originalSystemErr = null;
	private static PrintStream temporarySystemOut = null;
	private static PrintStream temporarySystemErr = null;
	
	/**
	 * Redirects all output sent to <code>System.out</code> and <code>System.err</code> to ImageJ's log console
	 * using the default prefixes.
	 */
	public static void redirectSystem(boolean redirect) {
		if (redirect)
			redirectSystem();
		else
			revertSystem();
	}
	
	/**
	 * Redirects all output sent to <code>System.out</code> and <code>System.err</code> to ImageJ's log console
	 * using the default prefixes.
	 * Alternatively use 
	 * {@link #redirectSystemOut(String)} and {@link #redirectSystemErr(String)}
	 * to redirect the streams separately and to specify individual prefixes.
	 */
	public static void redirectSystem() {
		redirectSystemOut(outPrefix);
		redirectSystemErr(errPrefix);
	}

	/**
	 * Redirects all output sent to <code>System.out</code> to ImageJ's log console.
	 * @param prefix The prefix string inserted at the start of each output line. 
	 * Pass <code>null</code>  to use the default prefix or an empty string to 
	 * remove the prefix.
	 */
	public static void redirectSystemOut(String prefix) {
		if (originalSystemOut == null) {		// has no effect if System.out is already replaced
			originalSystemOut = System.out;		// remember the original System.out stream
			temporarySystemOut = new LogStream(prefix);
			System.setOut(temporarySystemOut);
		}
	}
	
	/**
	 * Redirects all output sent to <code>System.err</code> to ImageJ's log console.
	 * @param prefix The prefix string inserted at the start of each output line. 
	 * Pass <code>null</code>  to use the default prefix or an empty string to 
	 * remove the prefix.
	 */
	public static void redirectSystemErr(String prefix) {
		if (originalSystemErr == null) {		// has no effect if System.out is already replaced
			originalSystemErr = System.err;		// remember the original System.out stream
			temporarySystemErr = new LogStream(prefix);
			System.setErr(temporarySystemErr);
		}
	}
	
	/**
	 * Returns the redirection stream for {@code System.out} if it exists.
	 * Note that a reference to the current output stream can also be obtained directly from 
	 * the {@code System.out} field.
	 * @return A reference to the {@code PrintStream} object currently substituting {@code System.out}
	 * or {@code null} of if {@code System.out} is currently not redirected.
	 */
	public static PrintStream getCurrentOutStream() {
		return temporarySystemOut;
	}
	
	/**
	 * Returns the redirection stream for {@code System.err} if it exists.
	 * Note that a reference to the current output stream can also be obtained directly from 
	 * the {@code System.err} field.
	 * @return A reference to the {@code PrintStream} object currently substituting {@code System.err}
	 * or {@code null} of if {@code System.err} is currently not redirected.
	 */
	public static PrintStream getCurrentErrStream() {
		return temporarySystemErr;
	}
	
	/**
	 * Use this method to revert both <code>System.out</code> and <code>System.err</code> 
	 * to their original output streams.
	 */
	public static void revertSystem() {
		revertSystemOut();
		revertSystemErr();
	}

	/**
	 * Use this method to revert<code>System.out</code>
	 * to the original output stream.
	 */
	public static void revertSystemOut() {
		if (originalSystemOut != null && temporarySystemOut != null) {
			temporarySystemOut.flush();
			temporarySystemOut.close();
			System.setOut(originalSystemOut);
			originalSystemOut = null;
			temporarySystemOut = null;
		}
	}
	
	/**
	 * Use this method to revert<code>System.err</code>
	 * to the original output stream.
	 */
	public static void revertSystemErr() {
		if (originalSystemErr != null && temporarySystemErr != null) {
			temporarySystemErr.flush();
			temporarySystemErr.close();
			System.setErr(originalSystemErr);
			originalSystemErr = null;
			temporarySystemErr = null;
		}
	}
	
	// ----------------------------------------------------------------
	
	private final String endOfLineSystem = System.getProperty("line.separator"); 
	private final String endOfLineShort = String.format("\n"); 	
	private final ByteArrayOutputStream byteStream;
	private final String prefix;
	
	public LogStream() {
		super(new ByteArrayOutputStream());
		this.byteStream = (ByteArrayOutputStream) this.out;
		this.prefix = "";
	}

	private LogStream(String prefix) {
		super(new ByteArrayOutputStream());
		this.byteStream = (ByteArrayOutputStream) this.out;
		this.prefix = (prefix == null) ? "" : prefix;
	}
	
	@Override
	// ever called?
	public void write(byte[] b) {
		this.write(b, 0, b.length);
	}
	
	@Override
	public void write(byte[] b, int off, int len) {
		String msg = new String(b, off, len);
		if (msg.equals(endOfLineSystem) || msg.equals(endOfLineShort)) { // this is a newline sequence only
			ejectBuffer();
		} else {
			byteStream.write(b, off, len);	// append message to buffer
			if (msg.endsWith(endOfLineSystem) || msg.endsWith(endOfLineShort)) { // line terminated by Newline
				// note that this does not seem to happen ever (even with format)!?
				ejectBuffer();
			}
		}
	}
	
	@Override
	// ever called?
	public void write(int b) {
		byteStream.write(b);
	}

	@Override
	public void flush() {
		if (byteStream.size() > 0) {
			String msg = byteStream.toString();
			if (msg.endsWith(endOfLineSystem) || msg.endsWith(endOfLineShort))
				ejectBuffer();
		}
		super.flush();
	}
	
	@Override
	public void close() {
		super.close();
	}
	
	private void ejectBuffer() {
		IJ.log(prefix + byteStream.toString());
		byteStream.reset();
	}
	
}