001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.tomcat.util.log;
018:
019: import java.io.IOException;
020: import java.io.PrintStream;
021: import java.util.Hashtable;
022: import java.util.Stack;
023:
024: /**
025: * This helper class may be used to do sophisticated redirection of
026: * System.out and System.err on a per Thread basis.
027: *
028: * A stack is implemented per Thread so that nested startCapture
029: * and stopCapture can be used.
030: *
031: * @author Remy Maucherat
032: * @author Glenn L. Nielsen
033: */
034: public class SystemLogHandler extends PrintStream {
035:
036: // ----------------------------------------------------------- Constructors
037:
038: /**
039: * Construct the handler to capture the output of the given steam.
040: */
041: public SystemLogHandler(PrintStream wrapped) {
042: super (wrapped);
043: out = wrapped;
044: }
045:
046: // ----------------------------------------------------- Instance Variables
047:
048: /**
049: * Wrapped PrintStream.
050: */
051: protected PrintStream out = null;
052:
053: /**
054: * Thread <-> CaptureLog associations.
055: */
056: protected static Hashtable logs = new Hashtable();
057:
058: /**
059: * Spare CaptureLog ready for reuse.
060: */
061: protected static Stack reuse = new Stack();
062:
063: // --------------------------------------------------------- Public Methods
064:
065: /**
066: * Start capturing thread's output.
067: */
068: public static void startCapture() {
069: CaptureLog log = null;
070: if (!reuse.isEmpty()) {
071: log = (CaptureLog) reuse.pop();
072: } else {
073: log = new CaptureLog();
074: }
075: Thread thread = Thread.currentThread();
076: Stack stack = (Stack) logs.get(thread);
077: if (stack == null) {
078: stack = new Stack();
079: logs.put(thread, stack);
080: }
081: stack.push(log);
082: }
083:
084: /**
085: * Stop capturing thread's output and return captured data as a String.
086: */
087: public static String stopCapture() {
088: Stack stack = (Stack) logs.get(Thread.currentThread());
089: if (stack == null || stack.isEmpty()) {
090: return null;
091: }
092: CaptureLog log = (CaptureLog) stack.pop();
093: if (log == null) {
094: return null;
095: }
096: String capture = log.getCapture();
097: log.reset();
098: reuse.push(log);
099: return capture;
100: }
101:
102: // ------------------------------------------------------ Protected Methods
103:
104: /**
105: * Find PrintStream to which the output must be written to.
106: */
107: protected PrintStream findStream() {
108: Stack stack = (Stack) logs.get(Thread.currentThread());
109: if (stack != null && !stack.isEmpty()) {
110: CaptureLog log = (CaptureLog) stack.peek();
111: if (log != null) {
112: PrintStream ps = log.getStream();
113: if (ps != null) {
114: return ps;
115: }
116: }
117: }
118: return out;
119: }
120:
121: // ---------------------------------------------------- PrintStream Methods
122:
123: public void flush() {
124: findStream().flush();
125: }
126:
127: public void close() {
128: findStream().close();
129: }
130:
131: public boolean checkError() {
132: return findStream().checkError();
133: }
134:
135: protected void setError() {
136: //findStream().setError();
137: }
138:
139: public void write(int b) {
140: findStream().write(b);
141: }
142:
143: public void write(byte[] b) throws IOException {
144: findStream().write(b);
145: }
146:
147: public void write(byte[] buf, int off, int len) {
148: findStream().write(buf, off, len);
149: }
150:
151: public void print(boolean b) {
152: findStream().print(b);
153: }
154:
155: public void print(char c) {
156: findStream().print(c);
157: }
158:
159: public void print(int i) {
160: findStream().print(i);
161: }
162:
163: public void print(long l) {
164: findStream().print(l);
165: }
166:
167: public void print(float f) {
168: findStream().print(f);
169: }
170:
171: public void print(double d) {
172: findStream().print(d);
173: }
174:
175: public void print(char[] s) {
176: findStream().print(s);
177: }
178:
179: public void print(String s) {
180: findStream().print(s);
181: }
182:
183: public void print(Object obj) {
184: findStream().print(obj);
185: }
186:
187: public void println() {
188: findStream().println();
189: }
190:
191: public void println(boolean x) {
192: findStream().println(x);
193: }
194:
195: public void println(char x) {
196: findStream().println(x);
197: }
198:
199: public void println(int x) {
200: findStream().println(x);
201: }
202:
203: public void println(long x) {
204: findStream().println(x);
205: }
206:
207: public void println(float x) {
208: findStream().println(x);
209: }
210:
211: public void println(double x) {
212: findStream().println(x);
213: }
214:
215: public void println(char[] x) {
216: findStream().println(x);
217: }
218:
219: public void println(String x) {
220: findStream().println(x);
221: }
222:
223: public void println(Object x) {
224: findStream().println(x);
225: }
226:
227: }
|