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 037 // ----------------------------------------------------------- Constructors 038 039 040 /** 041 * Construct the handler to capture the output of the given steam. 042 */ 043 public SystemLogHandler(PrintStream wrapped) { 044 super(wrapped); 045 out = wrapped; 046 } 047 048 049 // ----------------------------------------------------- Instance Variables 050 051 052 /** 053 * Wrapped PrintStream. 054 */ 055 protected PrintStream out = null; 056 057 058 /** 059 * Thread <-> CaptureLog associations. 060 */ 061 protected static Hashtable logs = new Hashtable(); 062 063 064 /** 065 * Spare CaptureLog ready for reuse. 066 */ 067 protected static Stack reuse = new Stack(); 068 069 070 // --------------------------------------------------------- Public Methods 071 072 073 /** 074 * Start capturing thread's output. 075 */ 076 public static void startCapture() { 077 CaptureLog log = null; 078 if (!reuse.isEmpty()) { 079 log = (CaptureLog)reuse.pop(); 080 } else { 081 log = new CaptureLog(); 082 } 083 Thread thread = Thread.currentThread(); 084 Stack stack = (Stack)logs.get(thread); 085 if (stack == null) { 086 stack = new Stack(); 087 logs.put(thread, stack); 088 } 089 stack.push(log); 090 } 091 092 093 /** 094 * Stop capturing thread's output and return captured data as a String. 095 */ 096 public static String stopCapture() { 097 Stack stack = (Stack)logs.get(Thread.currentThread()); 098 if (stack == null || stack.isEmpty()) { 099 return null; 100 } 101 CaptureLog log = (CaptureLog)stack.pop(); 102 if (log == null) { 103 return null; 104 } 105 String capture = log.getCapture(); 106 log.reset(); 107 reuse.push(log); 108 return capture; 109 } 110 111 112 // ------------------------------------------------------ Protected Methods 113 114 115 /** 116 * Find PrintStream to which the output must be written to. 117 */ 118 protected PrintStream findStream() { 119 Stack stack = (Stack)logs.get(Thread.currentThread()); 120 if (stack != null && !stack.isEmpty()) { 121 CaptureLog log = (CaptureLog)stack.peek(); 122 if (log != null) { Rate123 PrintStream ps = log.getStream(); 124 if (ps != null) { 125 return ps; 126 } 127 } 128 } 129 return out; 130 } 131 132 133 // ---------------------------------------------------- PrintStream Methods 134 135 136 public void flush() { 137 findStream().flush(); 138 } 139 140 public void close() { 141 findStream().close(); 142 } 143 144 public boolean checkError() { 145 return findStream().checkError(); 146 } 147 148 protected void setError() { 149 //findStream().setError(); 150 } 151 152 public void write(int b) { 153 findStream().write(b); 154 } 155 156 public void write(byte[] b) 157 throws IOException { 158 findStream().write(b); 159 } 160 161 public void write(byte[] buf, int off, int len) { 162 findStream().write(buf, off, len); 163 } 164 165 public void print(boolean b) { 166 findStream().print(b); 167 } 168 169 public void print(char c) { 170 findStream().print(c); 171 } 172 173 public void print(int i) { 174 findStream().print(i); 175 } 176 177 public void print(long l) { 178 findStream().print(l); 179 } 180 181 public void print(float f) { 182 findStream().print(f); 183 } 184 185 public void print(double d) { 186 findStream().print(d); 187 } 188 189 public void print(char[] s) { 190 findStream().print(s); 191 } 192 193 public void print(String s) { 194 findStream().print(s); 195 } 196 197 public void print(Object obj) { 198 findStream().print(obj); 199 } 200 201 public void println() { 202 findStream().println(); 203 } 204 205 public void println(boolean x) { 206 findStream().println(x); 207 } 208 209 public void println(char x) { 210 findStream().println(x); 211 } 212 213 public void println(int x) { 214 findStream().println(x); 215 } 216 217 public void println(long x) { 218 findStream().println(x); 219 } 220 221 public void println(float x) { 222 findStream().println(x); 223 } 224 225 public void println(double x) { 226 findStream().println(x); 227 } 228 229 public void println(char[] x) { 230 findStream().println(x); 231 } 232 233 public void println(String x) { 234 findStream().println(x); 235 } 236 237 public void println(Object x) { 238 findStream().println(x); 239 } 240 241 }