Quadcap Embeddable Database

com/quadcap/util/Debug.java

Go to the documentation of this file.
00001 package com.quadcap.util; 00002 00003 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.File; 00042 import java.io.FileOutputStream; 00043 import java.io.IOException; 00044 import java.io.PrintStream; 00045 00046 import java.util.Date; 00047 import java.util.Hashtable; 00048 00049 import java.sql.SQLException; 00050 00051 import java.text.SimpleDateFormat; 00052 00053 import com.quadcap.sql.file.DatafileException; 00054 00055 /** 00056 * Common functions for debug and log output. 00057 * 00058 * @author Stan Bailes 00059 */ 00060 public class Debug { 00061 static public PrintStream debugStream = System.out; 00062 static public int printLevel = 0; 00063 00064 private static String debugFileName = null; 00065 private static FileOutputStream debugFileStream = null; 00066 00067 static Hashtable debugMap = new Hashtable(); 00068 static NullSecurityManager sm = null; 00069 00070 static public final int debugOff = 0; 00071 static public final int debugSome = 1; 00072 static public final int debugAll = 3; 00073 static public final int debugPackage = 4; 00074 00075 static public int debugMode = debugAll; 00076 00077 static public final int debugNoTime = 0; 00078 static public final int debugElap = 1; 00079 static public final int debugInterval = 2; 00080 static public final int debugShowTime = 3; 00081 00082 static public int debugTime = debugShowTime; 00083 00084 static public long start = new Date().getTime(); 00085 static public long last = start; 00086 00087 static SimpleDateFormat sdf = 00088 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 00089 00090 00091 /*{com.quadcap.util.Config-vars.xml-0} 00092 * 00093 * <config> 00094 */ 00095 00096 /*{com.quadcap.util.Config-vars.xml-999999} 00097 * 00098 * </config> 00099 */ 00100 00101 /*{com.quadcap.util.Config-vars.xml-10} 00102 * 00103 * <config-var> 00104 * <config-name>debug.file</config-name> 00105 * <config-dflt>stderr</config-dflt> 00106 * <config-desc>Specify the name of the debug log file. The default 00107 * value, <code>stderr</code>, causes debug information to 00108 * be written to <code>System.err</code>.</config-desc> 00109 * </config-var> 00110 * 00111 * <config-var> 00112 * <config-name>debug.level</config-name> 00113 * <config-dflt>0</config-dflt> 00114 * <config-desc>Specify the level of debugging output. Level zero, 00115 * the lowest level, essentially turns debug output off (though 00116 * errors/exceptions will still be reported.) Increasing levels 00117 * will result in more debug output. The maximum debug level is 00118 * five (5).</config-desc> 00119 * </config-var> 00120 */ 00121 static { 00122 //System.setSecurityManager(sm = new NullSecurityManager()); 00123 try { 00124 ConfigString file = ConfigString.find("debug.file", "stderr"); 00125 if (file != null) { 00126 setLogFile(file.toString()); 00127 } 00128 ConfigNumber level = ConfigNumber.find("debug.level", "0"); 00129 if (level != null) { 00130 printLevel = level.intValue(); 00131 } 00133 Debug.print(e); 00134 } 00135 } 00136 00137 static public Class[] getClassContext() { 00138 return sm.pubGetClassContext(); 00139 } 00140 00141 static public void setDebugLevel(String name, String level) { 00142 debugMap.put(name, level); 00143 } 00144 00145 static public void print(Throwable e) { 00146 if (e == null) return; 00147 if (!(e instanceof SQLException)) { 00148 Debug.println(0, 2, e.getClass().getName()); 00149 } 00150 debugStream.print(hdr()); 00151 e.printStackTrace(debugStream); 00152 if (e instanceof SQLException) { 00153 printSQLException((SQLException)e); 00154 } else if (e.getCause() != null) { 00155 Debug.println("Cause of this exception:"); 00156 print(e.getCause()); 00157 } 00158 } 00159 00160 static void printSQLException(SQLException e) { 00161 StringBuffer sb = new StringBuffer(e.toString()); 00162 int idx; 00163 while ((idx = sb.toString().indexOf("Exception:")) >= 0) { 00164 sb.setCharAt(idx + 9, ','); 00165 } 00166 Debug.println(0, 3, sb.toString() + ", SQLState = " + e.getSQLState() + 00167 ", errorCode = " + e.getErrorCode()); 00168 SQLException next = e.getNextException(); 00169 if (next != null) { 00170 Debug.println("Next SQL Exception:"); 00171 printSQLException(next); 00172 } else if (e.getCause() != null) { 00173 Debug.println("Cause of this exception:"); 00174 print(e); 00175 } 00176 } 00177 00178 static public void println(String s) { 00179 println(0, 1, s); 00180 } 00181 00182 static public String getInterval() { 00183 String ret = null; 00184 Date d = new Date(); 00185 long now = d.getTime(); 00186 00187 switch (debugTime) { 00188 case debugInterval: 00189 ret = "" + (now - last); 00190 last = now; 00191 break; 00192 case debugElap: 00193 ret = "" + (now - start); 00194 break; 00195 case debugShowTime: 00196 ret = "" + sdf.format(d); 00197 break; 00198 } 00199 return ret; 00200 } 00201 00202 /** 00203 * Specify the file to be used for debug/log output. If there is 00204 * already a debug file open with a different name, it is closed first, 00205 * and if the name specified is <code>"stdout"</code>, then debug 00206 * output is directed to <code>System.out</code>. 00207 * 00208 * @param name the name of the debug log file. 00209 * @exception IOException may be thrown. 00210 */ 00211 static public void setLogFile(String name) throws IOException { 00212 if (name.equals("stdout")) { 00213 if (debugFileStream != null) { 00214 debugFileStream.close(); 00215 debugFileStream = null; 00216 } 00217 debugStream = System.out; 00218 } else if (name.equals("stderr")) { 00219 if (debugFileStream != null) { 00220 debugFileStream.close(); 00221 debugFileStream = null; 00222 } 00223 debugStream = System.err; 00224 } else { 00225 boolean append = name.startsWith("append:"); 00226 if (append) name = name.substring(7).trim(); 00227 name = new File(name).getAbsolutePath(); 00228 if (debugFileName == null || !name.equals(debugFileName)) { 00229 debugFileName = name; 00230 if (debugFileStream != null) { 00231 debugFileStream.close(); 00232 debugFileStream = null; 00233 } 00234 debugFileStream = new FileOutputStream(name, append); 00235 debugStream = new PrintStream(debugFileStream); 00236 println("---- [Debug started]"); 00237 } 00238 } 00239 } 00240 00241 /** 00242 * Specify the 'level' for debugging output. Only debug statements 00243 * satisfying <code>level &lt;= printLevel</code> result in output. 00244 * 00245 * @param printLevel the new debug output level. 00246 */ 00247 static public void setLogLevel(int printLevel) { 00248 if (printLevel != Debug.printLevel) { 00249 Debug.println(0, "Changing log level from " + Debug.printLevel + 00250 " to " + printLevel); 00251 Debug.printLevel = printLevel; 00252 } 00253 } 00254 00255 /** 00256 * Specify the debug mode using the convenient string representation 00257 * 00258 * @param mode the debug mode. 00259 */ 00260 static public void setDebugMode(String mode) { 00261 if (mode.equals("off")) { 00262 Debug.debugMode = Debug.debugOff; 00263 } else if (mode.equals("some")) { 00264 Debug.debugMode = Debug.debugSome; 00265 } else if (mode.equals("all")) { 00266 Debug.debugMode = Debug.debugAll; 00267 } else if (mode.equals("package")) { 00268 Debug.debugMode = Debug.debugPackage; 00269 } 00270 } 00271 00272 /** 00273 * Debug output at level <code>level</code>. 00274 */ 00275 static synchronized public void println(int level, String s) { 00276 println(level, 1, s); 00277 } 00278 00279 static String hdr() { 00280 StringBuffer sb = new StringBuffer(); 00281 if (debugTime != debugNoTime) { 00282 sb.append(getInterval()); 00283 sb.append(": "); 00284 } 00285 sb.append("["); 00286 sb.append(Thread.currentThread().getName()); 00287 sb.append("] "); 00288 return sb.toString(); 00289 } 00290 00291 /** 00292 * Debug output at level <code>level</code>. 00293 */ 00294 static synchronized public void println(int level, int depth, String s) { 00295 if (level > printLevel) return; 00296 debugStream.print(hdr()); 00297 if (sm != null) { 00298 String className = debugSite(level, depth+1); 00299 debugStream.print(className + ": "); 00300 } 00301 debugStream.println(s); 00302 } 00303 00304 static String debugSite(int level, int depth) { 00305 if (debugMode == debugOff || level > printLevel) return null; 00306 boolean print = true; 00307 Class[] classes = sm.pubGetClassContext(); 00308 00309 String className = ""; 00310 String packageName = ""; 00311 if (classes.length > 2 + depth) { 00312 Class caller = classes[2 + depth]; 00313 className = caller.getName(); 00314 int pos = className.lastIndexOf('.'); 00315 if (pos >= 0) { 00316 packageName = className.substring(0, pos); 00317 className = className.substring(pos+1); 00318 } 00319 } 00320 00321 String debugVal; 00322 00323 switch (debugMode) { 00324 case debugSome: 00325 debugVal = (String)debugMap.get(className); 00326 if (debugVal != null && level <= Integer.parseInt(debugVal)) { 00327 print = debugMode == debugSome; 00328 } 00329 break; 00330 case debugPackage: 00331 debugVal = (String)debugMap.get(packageName); 00332 if (debugVal != null && level <= Integer.parseInt(debugVal)) { 00333 print = debugMode == debugPackage; 00334 } 00335 break; 00336 } 00337 00338 if (print) return className; 00339 return null; 00340 } 00341 00342 }