Frames | No Frames |
1: /* ======================================================================== 2: * JCommon : a free general purpose class library for the Java(tm) platform 3: * ======================================================================== 4: * 5: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jcommon/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * -------- 28: * Log.java 29: * -------- 30: * (C)opyright 2002-2004, by Thomas Morgner and Contributors. 31: * 32: * Original Author: Thomas Morgner (taquera@sherito.org); 33: * Contributor(s): David Gilbert (for Object Refinery Limited); 34: * 35: * $Id: Log.java,v 1.5 2006/06/08 17:42:20 taqua Exp $ 36: * 37: * Changes 38: * ------- 39: * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon 40: * 11-Jun-2003 : Removing LogTarget did not work. 41: * 42: */ 43: 44: package org.jfree.util; 45: 46: import java.util.ArrayList; 47: import java.util.Arrays; 48: import java.util.HashMap; 49: 50: /** 51: * A simple logging facility. Create a class implementing the {@link org.jfree.util.LogTarget} 52: * interface to use this feature. 53: * 54: * @author Thomas Morgner 55: */ 56: public class Log { 57: 58: /** 59: * A simple message class. 60: */ 61: public static class SimpleMessage { 62: 63: /** 64: * The message. 65: */ 66: private String message; 67: 68: /** 69: * The parameters. 70: */ 71: private Object[] param; 72: 73: /** 74: * Creates a new message. 75: * 76: * @param message the message text. 77: * @param param1 parameter 1. 78: */ 79: public SimpleMessage(final String message, final Object param1) { 80: this.message = message; 81: this.param = new Object[]{param1}; 82: } 83: 84: /** 85: * Creates a new message. 86: * 87: * @param message the message text. 88: * @param param1 parameter 1. 89: * @param param2 parameter 2. 90: */ 91: public SimpleMessage(final String message, final Object param1, 92: final Object param2) { 93: this.message = message; 94: this.param = new Object[]{param1, param2}; 95: } 96: 97: /** 98: * Creates a new message. 99: * 100: * @param message the message text. 101: * @param param1 parameter 1. 102: * @param param2 parameter 2. 103: * @param param3 parameter 3. 104: */ 105: public SimpleMessage(final String message, final Object param1, 106: final Object param2, final Object param3) { 107: this.message = message; 108: this.param = new Object[]{param1, param2, param3}; 109: } 110: 111: /** 112: * Creates a new message. 113: * 114: * @param message the message text. 115: * @param param1 parameter 1. 116: * @param param2 parameter 2. 117: * @param param3 parameter 3. 118: * @param param4 parameter 4. 119: */ 120: public SimpleMessage(final String message, final Object param1, 121: final Object param2, final Object param3, 122: final Object param4) { 123: this.message = message; 124: this.param = new Object[]{param1, param2, param3, param4}; 125: } 126: 127: /** 128: * Creates a new message. 129: * 130: * @param message the message text. 131: * @param param the parameters. 132: */ 133: public SimpleMessage(final String message, final Object[] param) { 134: this.message = message; 135: this.param = param; 136: } 137: 138: /** 139: * Returns a string representation of the message (useful for debugging). 140: * 141: * @return the string. 142: */ 143: public String toString() { 144: final StringBuffer b = new StringBuffer(); 145: b.append(this.message); 146: if (this.param != null) { 147: for (int i = 0; i < this.param.length; i++) { 148: b.append(this.param[i]); 149: } 150: } 151: return b.toString(); 152: } 153: } 154: 155: 156: /** 157: * The logging threshold. 158: */ 159: private int debuglevel; 160: 161: /** 162: * Storage for the log targets. 163: */ 164: private LogTarget[] logTargets; 165: 166: /** The log contexts. */ 167: private HashMap logContexts; 168: 169: /** 170: * the singleton instance of the Log system. 171: */ 172: private static Log singleton; 173: 174: /** 175: * Creates a new Log instance. The Log is used to manage the log targets. 176: */ 177: protected Log() { 178: this.logContexts = new HashMap(); 179: this.logTargets = new LogTarget[0]; 180: this.debuglevel = 100; 181: } 182: 183: /** 184: * Returns the singleton Log instance. A new instance is created if necessary. 185: * 186: * @return the singleton instance. 187: */ 188: public static synchronized Log getInstance() { 189: if (singleton == null) { 190: singleton = new Log(); 191: } 192: return singleton; 193: } 194: 195: /** 196: * Redefines or clears the currently used log instance. 197: * 198: * @param log the new log instance or null, to return to the default implementation. 199: */ 200: protected static synchronized void defineLog(final Log log) { 201: singleton = log; 202: } 203: 204: /** 205: * Returns the currently defined debug level. The higher the level, the more details 206: * are printed. 207: * 208: * @return the debug level. 209: */ 210: public int getDebuglevel() { 211: return this.debuglevel; 212: } 213: 214: /** 215: * Defines the debug level for the log system. 216: * 217: * @param debuglevel the new debug level 218: * @see #getDebuglevel() 219: */ 220: protected void setDebuglevel(final int debuglevel) { 221: this.debuglevel = debuglevel; 222: } 223: 224: /** 225: * Adds a log target to this facility. Log targets get informed, via the LogTarget interface, 226: * whenever a message is logged with this class. 227: * 228: * @param target the target. 229: */ 230: public synchronized void addTarget(final LogTarget target) { 231: if (target == null) { 232: throw new NullPointerException(); 233: } 234: final LogTarget[] data = new LogTarget[this.logTargets.length + 1]; 235: System.arraycopy(this.logTargets, 0, data, 0, this.logTargets.length); 236: data[this.logTargets.length] = target; 237: this.logTargets = data; 238: } 239: 240: /** 241: * Removes a log target from this facility. 242: * 243: * @param target the target to remove. 244: */ 245: public synchronized void removeTarget(final LogTarget target) { 246: if (target == null) { 247: throw new NullPointerException(); 248: } 249: final ArrayList l = new ArrayList(); 250: l.addAll(Arrays.asList(this.logTargets)); 251: l.remove(target); 252: 253: final LogTarget[] targets = new LogTarget[l.size()]; 254: this.logTargets = (LogTarget[]) l.toArray(targets); 255: } 256: 257: /** 258: * Returns the registered logtargets. 259: * 260: * @return the logtargets. 261: */ 262: public LogTarget[] getTargets() { 263: return (LogTarget[]) this.logTargets.clone(); 264: } 265: 266: /** 267: * Replaces all log targets by the given target. 268: * 269: * @param target the new and only logtarget. 270: */ 271: public synchronized void replaceTargets(final LogTarget target) { 272: if (target == null) { 273: throw new NullPointerException(); 274: } 275: this.logTargets = new LogTarget[]{target}; 276: } 277: 278: /** 279: * A convenience method for logging a 'debug' message. 280: * 281: * @param message the message. 282: */ 283: public static void debug(final Object message) { 284: log(LogTarget.DEBUG, message); 285: } 286: 287: /** 288: * A convenience method for logging a 'debug' message. 289: * 290: * @param message the message. 291: * @param e the exception. 292: */ 293: public static void debug(final Object message, final Exception e) { 294: log(LogTarget.DEBUG, message, e); 295: } 296: 297: /** 298: * A convenience method for logging an 'info' message. 299: * 300: * @param message the message. 301: */ 302: public static void info(final Object message) { 303: log(LogTarget.INFO, message); 304: } 305: 306: /** 307: * A convenience method for logging an 'info' message. 308: * 309: * @param message the message. 310: * @param e the exception. 311: */ 312: public static void info(final Object message, final Exception e) { 313: log(LogTarget.INFO, message, e); 314: } 315: 316: /** 317: * A convenience method for logging a 'warning' message. 318: * 319: * @param message the message. 320: */ 321: public static void warn(final Object message) { 322: log(LogTarget.WARN, message); 323: } 324: 325: /** 326: * A convenience method for logging a 'warning' message. 327: * 328: * @param message the message. 329: * @param e the exception. 330: */ 331: public static void warn(final Object message, final Exception e) { 332: log(LogTarget.WARN, message, e); 333: } 334: 335: /** 336: * A convenience method for logging an 'error' message. 337: * 338: * @param message the message. 339: */ 340: public static void error(final Object message) { 341: log(LogTarget.ERROR, message); 342: } 343: 344: /** 345: * A convenience method for logging an 'error' message. 346: * 347: * @param message the message. 348: * @param e the exception. 349: */ 350: public static void error(final Object message, final Exception e) { 351: log(LogTarget.ERROR, message, e); 352: } 353: 354: /** 355: * Logs a message to the main log stream. All attached log targets will also 356: * receive this message. If the given log-level is higher than the given debug-level 357: * in the main config file, no logging will be done. 358: * 359: * @param level log level of the message. 360: * @param message text to be logged. 361: */ 362: protected void doLog(int level, final Object message) { 363: if (level > 3) { 364: level = 3; 365: } 366: if (level <= this.debuglevel) { 367: for (int i = 0; i < this.logTargets.length; i++) { 368: final LogTarget t = this.logTargets[i]; 369: t.log(level, message); 370: } 371: } 372: } 373: 374: /** 375: * Logs a message to the main log stream. All attached log targets will also 376: * receive this message. If the given log-level is higher than the given debug-level 377: * in the main config file, no logging will be done. 378: * 379: * @param level log level of the message. 380: * @param message text to be logged. 381: */ 382: public static void log(final int level, final Object message) { 383: getInstance().doLog(level, message); 384: } 385: 386: /** 387: * Logs a message to the main log stream. All attached logTargets will also 388: * receive this message. If the given log-level is higher than the given debug-level 389: * in the main config file, no logging will be done. 390: * <p/> 391: * The exception's stacktrace will be appended to the log-stream 392: * 393: * @param level log level of the message. 394: * @param message text to be logged. 395: * @param e the exception, which should be logged. 396: */ 397: public static void log(final int level, final Object message, final Exception e) { 398: getInstance().doLog(level, message, e); 399: } 400: 401: /** 402: * Logs a message to the main log stream. All attached logTargets will also 403: * receive this message. If the given log-level is higher than the given debug-level 404: * in the main config file, no logging will be done. 405: * <p/> 406: * The exception's stacktrace will be appended to the log-stream 407: * 408: * @param level log level of the message. 409: * @param message text to be logged. 410: * @param e the exception, which should be logged. 411: */ 412: protected void doLog(int level, final Object message, final Exception e) { 413: if (level > 3) { 414: level = 3; 415: } 416: 417: if (level <= this.debuglevel) { 418: for (int i = 0; i < this.logTargets.length; i++) { 419: final LogTarget t = this.logTargets[i]; 420: t.log(level, message, e); 421: } 422: } 423: } 424: 425: /** 426: * Initializes the logging system. Implementors should 427: * override this method to supply their own log configuration. 428: */ 429: public void init() { 430: // this method is intentionally empty. 431: } 432: 433: /** 434: * Returns true, if the log level allows debug messages to be 435: * printed. 436: * 437: * @return true, if messages with an log level of DEBUG are allowed. 438: */ 439: public static boolean isDebugEnabled() { 440: return getInstance().getDebuglevel() >= LogTarget.DEBUG; 441: } 442: 443: /** 444: * Returns true, if the log level allows informational 445: * messages to be printed. 446: * 447: * @return true, if messages with an log level of INFO are allowed. 448: */ 449: public static boolean isInfoEnabled() { 450: return getInstance().getDebuglevel() >= LogTarget.INFO; 451: } 452: 453: /** 454: * Returns true, if the log level allows warning messages to be 455: * printed. 456: * 457: * @return true, if messages with an log level of WARN are allowed. 458: */ 459: public static boolean isWarningEnabled() { 460: return getInstance().getDebuglevel() >= LogTarget.WARN; 461: } 462: 463: /** 464: * Returns true, if the log level allows error messages to be 465: * printed. 466: * 467: * @return true, if messages with an log level of ERROR are allowed. 468: */ 469: public static boolean isErrorEnabled() { 470: return getInstance().getDebuglevel() >= LogTarget.ERROR; 471: } 472: 473: /** 474: * Creates a log context. 475: * 476: * @param context the class (<code>null</code> not permitted). 477: * 478: * @return A log context. 479: */ 480: public static LogContext createContext(final Class context) { 481: return createContext(context.getName()); 482: } 483: 484: /** 485: * Creates a log context. 486: * 487: * @param context the label for the context. 488: * 489: * @return A log context. 490: */ 491: public static LogContext createContext(final String context) { 492: return getInstance().internalCreateContext(context); 493: } 494: 495: /** 496: * Creates a log context. 497: * 498: * @param context the name of the logging context (a common prefix). 499: * 500: * @return A log context. 501: */ 502: protected LogContext internalCreateContext(final String context) { 503: synchronized (this) { 504: LogContext ctx = (LogContext) this.logContexts.get(context); 505: if (ctx == null) { 506: ctx = new LogContext(context); 507: this.logContexts.put(context, ctx); 508: } 509: return ctx; 510: } 511: } 512: 513: }