001 /* 002 Copyright (C) 2001-2003 Laurent Martelli <laurent@aopsys.com> 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.util; 019 020 import java.io.FileOutputStream; 021 import java.io.PrintStream; 022 import java.text.DateFormat; 023 import java.text.SimpleDateFormat; 024 import java.util.Date; 025 import java.util.Hashtable; 026 import java.util.Map; 027 import java.util.Set; 028 029 /** 030 * The <code>Log</code> class provides a means to send some 031 * informational, debugging or error messages like 032 * <code>System.out.println</code> but traces can be enabled or 033 * disabled at runtime. 034 * 035 * <p>JAC supports a -V launching option that allows the user to 036 * enable a given trace category (for instance, by using <code>-V 037 * jac</code>, the user can see what happens in the JAC core system. 038 * 039 * @author <a href="mailto:laurent@aopsys.com">Laurent Martelli</a> */ 040 041 public final class Log{ 042 043 // enabled traces 044 static Hashtable levels = new Hashtable(); 045 046 static PrintStream out = System.out; 047 048 static String logHeader = ""; 049 050 static Date date = new Date(); 051 static DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS "); 052 053 /** 054 * Sets the logging file. 055 * 056 * @param name the file name if null=>log to the standard output 057 * @param header a string to prepend to each line logged. 058 */ 059 public static void setFileName(String name, String header) { 060 try { 061 logHeader = header; 062 out = new PrintStream(new FileOutputStream(name)); 063 } catch(Exception e) { 064 out = System.out; 065 e.printStackTrace(); 066 } 067 } 068 069 /** 070 * Traces with a level lower than <code>levels[category]</code> are 071 * discarded. 072 * 073 * @param category a string representing the category to trace 074 * @param level the level of the trace (1 is always printed) 075 * @param message the message to print out */ 076 077 public static void trace(String category, int level, String message) { 078 if (!(category!=null && levels.containsKey(category))) { 079 levels.put(category, new Integer(0)); 080 } 081 if (level<=((Integer)levels.get(category)).intValue()) { 082 date.setTime(System.currentTimeMillis()); 083 out.print(dateFormat.format(date)); 084 out.print(logHeader); 085 out.print(category); 086 out.print(": "); 087 out.println(message); 088 } 089 } 090 091 /** 092 * Print the stack trace of an exception with a level lower than 093 * <code>levels[category]</code> are discarded. 094 * 095 * @param category a string representing the category to trace 096 * @param level the level of the trace (1 is always printed) 097 * @param exception the exception */ 098 099 public static void trace(String category, int level, Throwable exception) { 100 if (category!=null && levels.containsKey(category)) { 101 if (level<=((Integer)levels.get(category)).intValue()) { 102 out.println(logHeader+category+": StackTrace"); 103 exception.printStackTrace(out); 104 } 105 } else { 106 levels.put(category, new Integer(0)); 107 } 108 } 109 110 111 /** 112 * Prints a stack trace. 113 * 114 * @param category a string representing the category to trace 115 * @param level the level of the trace (1 is always printed) 116 */ 117 public static void stack(String category, int level) { 118 if (category!=null && levels.containsKey(category)) { 119 if (level<=((Integer)levels.get(category)).intValue()) { 120 out.println(logHeader+category+": StackTrace"); 121 new Exception().printStackTrace(out); 122 } 123 } else { 124 levels.put(category, new Integer(0)); 125 } 126 } 127 128 public static void stack(String category) { 129 stack(category,1); 130 } 131 132 /** 133 * Traces with a level equals to 1. 134 * 135 * @param category a string representing the category to trace 136 * @param message the message to print out 137 * @see #trace(String,int,String) */ 138 139 public static void trace(String category, String message) { 140 Log.trace(category, 1, message); 141 } 142 143 /** 144 * Print a stack trace with a level equals to 1. 145 * 146 * @param category a string representing the category to trace 147 * @param exception the message to print out 148 * @see #trace(String,int,String) */ 149 150 public static void trace(String category, Throwable exception) { 151 Log.trace(category, 1, exception); 152 } 153 154 /** 155 * Traces an error into the <code>System.err</code> stream. 156 * 157 * @param message the error message to print out */ 158 159 public static void error(String message) { 160 out.println(logHeader+"ERROR: "+message); 161 } 162 163 /** 164 * Traces a warning into the <code>System.err</code> stream. 165 * 166 * @param message the warning message to print out 167 * @param level warning level (0=important, 1=normal, 2=low, ...) 168 */ 169 public static void warning(String message, int level) { 170 if (level<=1) { 171 out.println(logHeader+"WARNING: "+message); 172 } 173 } 174 175 /** 176 * Traces a warning into the <code>System.err</code> stream. 177 * 178 * @param message the warning message to print out 179 */ 180 public static void warning(String message) { 181 warning(message, 1); 182 } 183 184 /** 185 * Traces a warning into the <code>System.err</code> stream only if 186 * the given category is enable to trace. 187 * 188 * @param message the warning message to print out 189 */ 190 public static void warning(String category, String message) { 191 warning(category+": "+message, 1); 192 } 193 194 /** 195 * Traces a warning into the <code>System.err</code> stream only if 196 * the given category is enable to trace. 197 * 198 * @param message the warning message to print out 199 */ 200 public static void warning(String category, int level, String message) { 201 warning(category+": "+message, level); 202 } 203 204 /** 205 * Sets the verbose level of a given category. 206 * 207 * <p>The higher, the more traces are printed out. 208 * 209 * @param category the category to set the level of 210 * @param level the category verbose level */ 211 212 public static void setLevel(String category, int level) { 213 levels.put(category, new Integer(level)); 214 } 215 216 /** 217 * Returns a Map category -> enabled saying which traces are enables 218 */ 219 public static Map getLevels() { 220 return levels; 221 } 222 223 public static Set getCategories(Object substance) { 224 return levels.keySet(); 225 } 226 227 public static String dump() { 228 return Strings.hex(levels)+" : "+levels; 229 } 230 }