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