Source for org.jfree.util.Log

   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: }