001: /*
002:
003: Copyright 2004, Martian Software, Inc.
004:
005: Licensed under the Apache License, Version 2.0 (the "License");
006: you may not use this file except in compliance with the License.
007: 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:
017: */
018:
019: package com.martiansoftware.nailgun;
020:
021: import java.io.IOException;
022: import java.io.PrintStream;
023:
024: /**
025: * The class name is pretty descriptive. This creates a PrintStream
026: * much like a FilterOutputStream, but with the wrapped PrintStream
027: * being local to the current Thread. By setting System.out to a
028: * ThreadLocalPrintStream, different Threads can write to different
029: * PrintStreams simply by using System.out. Of course, the init()
030: * method must be called by the Thread that wishes to use the
031: * wrapped stream.
032: *
033: * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
034: */
035: class ThreadLocalPrintStream extends PrintStream {
036:
037: /**
038: * The PrintStreams for the various threads
039: */
040: private InheritableThreadLocal streams = null;
041:
042: private PrintStream defaultPrintStream = null;
043:
044: /**
045: * Creates a new InheritedThreadLocalPrintStream
046: * @param defaultPrintStream the PrintStream that will be used if the
047: * current thread has not called init()
048: */
049: public ThreadLocalPrintStream(PrintStream defaultPrintStream) {
050: super (defaultPrintStream);
051: streams = new InheritableThreadLocal();
052: this .defaultPrintStream = defaultPrintStream;
053: init(null);
054: }
055:
056: /**
057: * Sets the PrintStream for the current thread
058: * @param streamForCurrentThread the PrintStream for the current thread
059: */
060: void init(PrintStream streamForCurrentThread) {
061: streams.set(streamForCurrentThread);
062: }
063:
064: /**
065: * Returns this thread's PrintStream
066: * @return this thread's PrintStream
067: */
068: PrintStream getPrintStream() {
069: PrintStream result = (PrintStream) streams.get();
070: return ((result == null) ? defaultPrintStream : result);
071: }
072:
073: // BEGIN delegated java.io.PrintStream methods
074:
075: /**
076: * @see java.io.PrintStream#checkError()
077: */
078: public boolean checkError() {
079: return (getPrintStream().checkError());
080: }
081:
082: /**
083: * @see java.io.PrintStream#close()
084: */
085: public void close() {
086: getPrintStream().close();
087: }
088:
089: /**
090: * @see java.io.PrintStream#flush()
091: */
092: public void flush() {
093: getPrintStream().flush();
094: }
095:
096: /**
097: * @see java.io.PrintStream#print(boolean)
098: */
099: public void print(boolean b) {
100: getPrintStream().print(b);
101: }
102:
103: /**
104: * @see java.io.PrintStream#print(char)
105: */
106: public void print(char c) {
107: getPrintStream().print(c);
108: }
109:
110: /**
111: * @see java.io.PrintStream#print(char[])
112: */
113: public void print(char[] s) {
114: getPrintStream().print(s);
115: }
116:
117: /**
118: * @see java.io.PrintStream#print(double)
119: */
120: public void print(double d) {
121: getPrintStream().print(d);
122: }
123:
124: /**
125: * @see java.io.PrintStream#print(float)
126: */
127: public void print(float f) {
128: getPrintStream().print(f);
129: }
130:
131: /**
132: * @see java.io.PrintStream#print(int)
133: */
134: public void print(int i) {
135: getPrintStream().print(i);
136: }
137:
138: /**
139: * @see java.io.PrintStream#print(long)
140: */
141: public void print(long l) {
142: getPrintStream().print(l);
143: }
144:
145: /**
146: * @see java.io.PrintStream#print(Object)
147: */
148: public void print(Object obj) {
149: getPrintStream().print(obj);
150: }
151:
152: /**
153: * @see java.io.PrintStream#print(String)
154: */
155: public void print(String s) {
156: getPrintStream().print(s);
157: }
158:
159: /**
160: * @see java.io.PrintStream#println()
161: */
162: public void println() {
163: getPrintStream().println();
164: }
165:
166: /**
167: * @see java.io.PrintStream#println(boolean)
168: */
169: public void println(boolean x) {
170: getPrintStream().println(x);
171: }
172:
173: /**
174: * @see java.io.PrintStream#println(char)
175: */
176: public void println(char x) {
177: getPrintStream().println(x);
178: }
179:
180: /**
181: * @see java.io.PrintStream#println(char[])
182: */
183: public void println(char[] x) {
184: getPrintStream().println(x);
185: }
186:
187: /**
188: * @see java.io.PrintStream#println(double)
189: */
190: public void println(double x) {
191: getPrintStream().println(x);
192: }
193:
194: /**
195: * @see java.io.PrintStream#println(float)
196: */
197: public void println(float x) {
198: getPrintStream().println(x);
199: }
200:
201: /**
202: * @see java.io.PrintStream#println(int)
203: */
204: public void println(int x) {
205: getPrintStream().println(x);
206: }
207:
208: /**
209: * @see java.io.PrintStream#println(long)
210: */
211: public void println(long x) {
212: getPrintStream().println(x);
213: }
214:
215: /**
216: * @see java.io.PrintStream#println(Object)
217: */
218: public void println(Object x) {
219: getPrintStream().println(x);
220: }
221:
222: /**
223: * @see java.io.PrintStream#println(String)
224: */
225: public void println(String x) {
226: getPrintStream().println(x);
227: }
228:
229: /**
230: * @see java.io.PrintStream#write(byte[],int,int)
231: */
232: public void write(byte[] buf, int off, int len) {
233: getPrintStream().write(buf, off, len);
234: }
235:
236: /**
237: * @see java.io.PrintStream#write(int)
238: */
239: public void write(int b) {
240: getPrintStream().write(b);
241: }
242:
243: // END delegated java.io.PrintStream methods
244:
245: // BEGIN delegated java.io.FilterOutputStream methods
246:
247: /**
248: * @see java.io.FilterOutputStream#write(byte[])
249: */
250: public void write(byte[] b) throws IOException {
251: getPrintStream().write(b);
252: }
253:
254: // END delegated java.io.FilterOutputStream methods
255:
256: // Note: Should java.lang.Object methods be delegated? If not, and
257: // someone synchronizes on this stream, processes might be blocked
258: // that shouldn't be. It would certainly be stupid to delegate
259: // finalize(). Not so clear are hashcode(), equals(), notify(), and
260: // the wait() methods.
261: }
|