001: /* ========================================================================
002: * JCommon : a free general purpose class library for the Java(tm) platform
003: * ========================================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jcommon/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * --------
028: * Log.java
029: * --------
030: * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
031: *
032: * Original Author: Thomas Morgner (taquera@sherito.org);
033: * Contributor(s): David Gilbert (for Object Refinery Limited);
034: *
035: * $Id: Log.java,v 1.5 2006/06/08 17:42:20 taqua Exp $
036: *
037: * Changes
038: * -------
039: * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon
040: * 11-Jun-2003 : Removing LogTarget did not work.
041: *
042: */
043:
044: package org.jfree.util;
045:
046: import java.util.ArrayList;
047: import java.util.Arrays;
048: import java.util.HashMap;
049:
050: /**
051: * A simple logging facility. Create a class implementing the {@link org.jfree.util.LogTarget}
052: * interface to use this feature.
053: *
054: * @author Thomas Morgner
055: */
056: public class Log {
057:
058: /**
059: * A simple message class.
060: */
061: public static class SimpleMessage {
062:
063: /**
064: * The message.
065: */
066: private String message;
067:
068: /**
069: * The parameters.
070: */
071: private Object[] param;
072:
073: /**
074: * Creates a new message.
075: *
076: * @param message the message text.
077: * @param param1 parameter 1.
078: */
079: public SimpleMessage(final String message, final Object param1) {
080: this .message = message;
081: this .param = new Object[] { param1 };
082: }
083:
084: /**
085: * Creates a new message.
086: *
087: * @param message the message text.
088: * @param param1 parameter 1.
089: * @param param2 parameter 2.
090: */
091: public SimpleMessage(final String message, final Object param1,
092: final Object param2) {
093: this .message = message;
094: this .param = new Object[] { param1, param2 };
095: }
096:
097: /**
098: * Creates a new message.
099: *
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: * The logging threshold.
157: */
158: private int debuglevel;
159:
160: /**
161: * Storage for the log targets.
162: */
163: private LogTarget[] logTargets;
164:
165: /** The log contexts. */
166: private HashMap logContexts;
167:
168: /**
169: * the singleton instance of the Log system.
170: */
171: private static Log singleton;
172:
173: /**
174: * Creates a new Log instance. The Log is used to manage the log targets.
175: */
176: protected Log() {
177: this .logContexts = new HashMap();
178: this .logTargets = new LogTarget[0];
179: this .debuglevel = 100;
180: }
181:
182: /**
183: * Returns the singleton Log instance. A new instance is created if necessary.
184: *
185: * @return the singleton instance.
186: */
187: public static synchronized Log getInstance() {
188: if (singleton == null) {
189: singleton = new Log();
190: }
191: return singleton;
192: }
193:
194: /**
195: * Redefines or clears the currently used log instance.
196: *
197: * @param log the new log instance or null, to return to the default implementation.
198: */
199: protected static synchronized void defineLog(final Log log) {
200: singleton = log;
201: }
202:
203: /**
204: * Returns the currently defined debug level. The higher the level, the more details
205: * are printed.
206: *
207: * @return the debug level.
208: */
209: public int getDebuglevel() {
210: return this .debuglevel;
211: }
212:
213: /**
214: * Defines the debug level for the log system.
215: *
216: * @param debuglevel the new debug level
217: * @see #getDebuglevel()
218: */
219: protected void setDebuglevel(final int debuglevel) {
220: this .debuglevel = debuglevel;
221: }
222:
223: /**
224: * Adds a log target to this facility. Log targets get informed, via the LogTarget interface,
225: * whenever a message is logged with this class.
226: *
227: * @param target the target.
228: */
229: public synchronized void addTarget(final LogTarget target) {
230: if (target == null) {
231: throw new NullPointerException();
232: }
233: final LogTarget[] data = new LogTarget[this .logTargets.length + 1];
234: System.arraycopy(this .logTargets, 0, data, 0,
235: 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,
398: final Exception e) {
399: getInstance().doLog(level, message, e);
400: }
401:
402: /**
403: * Logs a message to the main log stream. All attached logTargets will also
404: * receive this message. If the given log-level is higher than the given debug-level
405: * in the main config file, no logging will be done.
406: * <p/>
407: * The exception's stacktrace will be appended to the log-stream
408: *
409: * @param level log level of the message.
410: * @param message text to be logged.
411: * @param e the exception, which should be logged.
412: */
413: protected void doLog(int level, final Object message,
414: final Exception e) {
415: if (level > 3) {
416: level = 3;
417: }
418:
419: if (level <= this .debuglevel) {
420: for (int i = 0; i < this .logTargets.length; i++) {
421: final LogTarget t = this .logTargets[i];
422: t.log(level, message, e);
423: }
424: }
425: }
426:
427: /**
428: * Initializes the logging system. Implementors should
429: * override this method to supply their own log configuration.
430: */
431: public void init() {
432: // this method is intentionally empty.
433: }
434:
435: /**
436: * Returns true, if the log level allows debug messages to be
437: * printed.
438: *
439: * @return true, if messages with an log level of DEBUG are allowed.
440: */
441: public static boolean isDebugEnabled() {
442: return getInstance().getDebuglevel() >= LogTarget.DEBUG;
443: }
444:
445: /**
446: * Returns true, if the log level allows informational
447: * messages to be printed.
448: *
449: * @return true, if messages with an log level of INFO are allowed.
450: */
451: public static boolean isInfoEnabled() {
452: return getInstance().getDebuglevel() >= LogTarget.INFO;
453: }
454:
455: /**
456: * Returns true, if the log level allows warning messages to be
457: * printed.
458: *
459: * @return true, if messages with an log level of WARN are allowed.
460: */
461: public static boolean isWarningEnabled() {
462: return getInstance().getDebuglevel() >= LogTarget.WARN;
463: }
464:
465: /**
466: * Returns true, if the log level allows error messages to be
467: * printed.
468: *
469: * @return true, if messages with an log level of ERROR are allowed.
470: */
471: public static boolean isErrorEnabled() {
472: return getInstance().getDebuglevel() >= LogTarget.ERROR;
473: }
474:
475: /**
476: * Creates a log context.
477: *
478: * @param context the class (<code>null</code> not permitted).
479: *
480: * @return A log context.
481: */
482: public static LogContext createContext(final Class context) {
483: return createContext(context.getName());
484: }
485:
486: /**
487: * Creates a log context.
488: *
489: * @param context the label for the context.
490: *
491: * @return A log context.
492: */
493: public static LogContext createContext(final String context) {
494: return getInstance().internalCreateContext(context);
495: }
496:
497: /**
498: * Creates a log context.
499: *
500: * @param context the name of the logging context (a common prefix).
501: *
502: * @return A log context.
503: */
504: protected LogContext internalCreateContext(final String context) {
505: synchronized (this ) {
506: LogContext ctx = (LogContext) this .logContexts.get(context);
507: if (ctx == null) {
508: ctx = new LogContext(context);
509: this.logContexts.put(context, ctx);
510: }
511: return ctx;
512: }
513: }
514:
515: }
|