001: /**
002: * Copyright (C) 2001-2003 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library 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 GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.util.monolog.wrapper.printwriter;
018:
019: import org.objectweb.util.monolog.api.BasicLevel;
020: import org.objectweb.util.monolog.api.Handler;
021: import org.objectweb.util.monolog.api.Level;
022: import org.objectweb.util.monolog.api.MonologFactoryListener;
023: import org.objectweb.util.monolog.api.TopicalLogger;
024: import org.objectweb.util.monolog.api.Logger;
025: import org.objectweb.util.monolog.api.MonologFactory;
026: import org.objectweb.util.monolog.wrapper.common.EnumrationImpl;
027: import org.objectweb.util.monolog.wrapper.common.LevelImpl;
028:
029: import java.io.PrintWriter;
030: import java.io.StringWriter;
031: import java.util.Enumeration;
032: import java.util.Hashtable;
033: import java.util.Vector;
034: import java.util.Properties;
035: import java.util.Map;
036: import java.util.HashMap;
037: import java.util.Iterator;
038:
039: /**
040: * This class is a simple implementation of the Logger interface provided by
041: * the monolog specification.
042: *
043: *@author sebastien.chassande@inrialpes.fr
044: */
045: public class LoggerImpl implements TopicalLogger, MonologFactory {
046:
047: public final static String PRINT_WRITER = "printwriter";
048:
049: /**
050: * The current level of this logger
051: */
052: private int level = BasicLevel.DEBUG;
053: private Level lev = null;
054:
055: protected String name = null;
056: protected Vector topics = null;
057: protected Hashtable handlers = null;
058: protected boolean additivity = true;
059: protected Map levels = null;
060:
061: /**
062: * The printwriter which messages are written.
063: */
064: private PrintWriter pw = null;
065:
066: private boolean isOn = true;
067:
068: /**
069: * This constructor permits to specify the printWriter linked to this
070: * logger
071: *
072: */
073: public LoggerImpl() {
074: this (null);
075: }
076:
077: /**
078: * This constructor permits to specify the printWriter linked to this
079: * logger
080: *
081: *@param _pw the printwriter
082: */
083: public LoggerImpl(PrintWriter _pw) {
084: this ("org.objectweb.util.monolog.wrapper.printwriter", _pw);
085: }
086:
087: /**
088: * This constructor permits to specify the printWriter linked to this
089: * logger
090: *
091: *@param _pw the printwriter
092: */
093: public LoggerImpl(String n, PrintWriter _pw) {
094: name = n;
095: pw = _pw;
096: }
097:
098: public PrintWriter getPrintWriter() {
099: return pw;
100: }
101:
102: public void addMonologFactoryListener(MonologFactoryListener mfl) {
103: }
104:
105: public void removeMonologFactoryListener(MonologFactoryListener mfl) {
106: }
107:
108: // IMPLEMENTATION OF THE HandlerFactory INTERFACE //
109: //-----------------------------------------------//
110: public void configure(Properties prop) throws Exception {
111: }
112:
113: // IMPLEMENTATION OF THE HandlerFactory INTERFACE //
114: //-----------------------------------------------//
115: public Handler createHandler(String hn, String handlertype) {
116: return this ;
117: }
118:
119: public Handler removeHandler(String handlername) {
120: return this ;
121: }
122:
123: public Handler[] getHandlers() {
124: return new Handler[] { this };
125: }
126:
127: // IMPLEMENTATION OF THE LevelFactory INTERFACE //
128: //-----------------------------------------------//
129:
130: public synchronized Level defineLevel(String name, int value) {
131: Level l = new LevelImpl(name, value);
132: if (levels == null) {
133: levels = new HashMap();
134: }
135: levels.put(new Integer(value), l);
136: return l;
137: }
138:
139: public Level defineLevel(String name, String value) {
140: Level l = new LevelImpl(name, value, this );
141: if (levels == null) {
142: levels = new HashMap();
143: }
144: levels.put(new Integer(value), l);
145: return l;
146: }
147:
148: public Level getLevel(String name) {
149: Iterator it = levels.values().iterator();
150: while (it.hasNext()) {
151: Level l = (Level) it.next();
152: if (l.getName().equals(name)) {
153: return l;
154: }
155: }
156: return null;
157: }
158:
159: /**
160: * This method is not synchronized because the configuration is rarely
161: */
162: public Level getLevel(int value) {
163: return (Level) levels.get(new Integer(value));
164: }
165:
166: /**
167: * This method is not synchronized because the configuration is rarely
168: */
169: public Level[] getLevels() {
170: return (Level[]) levels.values().toArray(
171: new Level[levels.size()]);
172: }
173:
174: public synchronized void removeLevel(String name) {
175: Iterator it = levels.values().iterator();
176: while (it.hasNext()) {
177: Level l = (Level) it.next();
178: if (l.getName().equals(name)) {
179: it.remove();
180: }
181: }
182: }
183:
184: // IMPLEMENTATION OF THE LoggerFactory INTERFACE //
185: //-----------------------------------------------//
186:
187: public Logger getLogger(String key) {
188: return this ;
189: }
190:
191: public Logger getLogger(String key, String resourceBundleName) {
192: return this ;
193: }
194:
195: public String getResourceBundleName() {
196: return null;
197: }
198:
199: public void setResourceBundleName(String resourceBundleName) {
200: }
201:
202: public Logger[] getLoggers() {
203: return new Logger[] { this };
204: }
205:
206: public String getTopicPrefix() {
207: return null;
208: }
209:
210: // IMPLEMENTATION OF THE TopicalLogger INTERFACE //
211: //-----------------------------------------------//
212:
213: /**
214: * Sets the IntLevel attribute of the LoggerImpl object
215: *
216: *@param l The new IntLevel value
217: */
218: public void setIntLevel(int l) {
219: level = l;
220: }
221:
222: /**
223: * Sets the Level attribute of the LoggerImpl object
224: *
225: *@param l The new Level value
226: */
227: public void setLevel(Level l) {
228: lev = l;
229: if (lev != null) {
230: level = lev.getIntValue();
231: }
232: }
233:
234: /**
235: * Gets the CurrentIntLevel attribute of the LoggerImpl object
236: *
237: *@return The CurrentIntLevel value
238: */
239: public int getCurrentIntLevel() {
240: return level;
241: }
242:
243: /**
244: * Gets the CurrentLevel attribute of the LoggerImpl object
245: *
246: *@return The CurrentLevel value
247: */
248: public Level getCurrentLevel() {
249: return (lev == null ? lev = new LevelImpl(
250: (level == -1 ? "INHERIT" : "INTER"), level) : lev);
251: }
252:
253: /**
254: * Gets the Loggable attribute of the LoggerImpl object
255: *
256: *@param l Description of Parameter
257: *@return The Loggable value
258: */
259: public boolean isLoggable(int l) {
260: return pw != null && l >= level;
261: }
262:
263: /**
264: * Gets the Loggable attribute of the LoggerImpl object
265: *
266: *@param l Description of Parameter
267: *@return The Loggable value
268: */
269: public boolean isLoggable(Level l) {
270: return pw != null && l != null && l.getIntValue() >= level;
271: }
272:
273: /**
274: * Gets the On attribute of the LoggerImpl object
275: *
276: *@return The On value
277: */
278: public boolean isOn() {
279: return isOn;
280: }
281:
282: /**
283: * Gets the Topics attribute of the LoggerImpl object
284: *
285: *@return The Topics value
286: */
287: public Enumeration getTopics() {
288: if (topics == null) {
289: String[] ar = { name };
290: return new EnumrationImpl(ar);
291: } else {
292: String[] str = new String[topics.size()];
293: for (int i = 0; i < topics.size(); i++) {
294: str[i] = (String) (topics.elementAt(i));
295: }
296: return new EnumrationImpl(str);
297: }
298: }
299:
300: /**
301: * Log method
302: */
303: public void log(int level, Object o) {
304: if (pw == null || !isOn() || o == null || !isLoggable(level)) {
305: return;
306: }
307: if (level == BasicLevel.ERROR) {
308: pw.println("**" + format(o.toString(), 2));
309: } else {
310: pw.println(format(o.toString(), 2));
311: }
312: }
313:
314: /**
315: * Log method
316: */
317: public void log(Level l, Object o) {
318: }
319:
320: /**
321: * Log method
322: */
323: public void log(int level, Object o, Throwable t) {
324: if (pw == null || !isOn() || o == null || !isLoggable(level)) {
325: return;
326: }
327: pw.println(o.toString() + ":" + t.toString());
328: }
329:
330: /**
331: * Log method
332: */
333: public void log(Level l, Object o, Throwable t) {
334: }
335:
336: /**
337: * Log method
338: */
339: public void log(int level, Object o, Object location, Object method) {
340: if (pw == null || !isOn() || o == null || !isLoggable(level)) {
341: return;
342: }
343: pw.println(location.toString() + "." + method.toString()
344: + "(...) :" + o.toString());
345: }
346:
347: /**
348: * Log method
349: */
350: public void log(Level l, Object o, Object location, Object method) {
351: }
352:
353: /**
354: * Log method
355: */
356: public void log(int level, Object o, Throwable t, Object location,
357: Object method) {
358: if (pw == null || !isOn() || o == null || !isLoggable(level)) {
359: return;
360: }
361: pw.println(location.toString() + "." + method.toString()
362: + "(...) :" + o.toString() + " " + t.toString());
363: }
364:
365: /**
366: * Log method
367: */
368: public void log(Level l, Object o, Throwable t, Object location,
369: Object method) {
370: }
371:
372: /**
373: * Turn on this logger
374: */
375: public void turnOn() {
376: isOn = true;
377: }
378:
379: /**
380: * Turn off this logger
381: */
382: public void turnOff() {
383: isOn = false;
384: }
385:
386: /**
387: * The toString method is override to signal the logger imlementation
388: * fowards its messages to a printwriter
389: */
390: public String toString() {
391: return "Personnal implementation on PrintWriter object";
392: }
393:
394: // IMPLEMENTATION OF THE TopicalLogger INTERFACE //
395: //-----------------------------------------------//
396:
397: public void addHandler(Handler h) throws Exception {
398: if (h != null) {
399: if (handlers == null) {
400: handlers = new Hashtable();
401: }
402: handlers.put(h.getName(), h);
403: }
404: }
405:
406: public void addTopic(String topic) throws Exception {
407: if (topics == null) {
408: topics = new Vector();
409: topics.addElement(name);
410: }
411: topics.addElement(topic);
412: }
413:
414: public void removeHandler(Handler h) throws Exception {
415: if (h != null && handlers != null) {
416: handlers.remove(h.getName());
417: }
418: }
419:
420: public void removeAllHandlers() throws Exception {
421: if (handlers != null) {
422: handlers.clear();
423: }
424: }
425:
426: public void removeTopic(String topic) throws Exception {
427: if (topics != null) {
428: topics.removeElement(topic);
429: }
430: }
431:
432: public void setAdditivity(boolean a) {
433: additivity = a;
434: }
435:
436: public boolean getAdditivity() {
437: return additivity;
438: }
439:
440: public Handler[] getHandler() {
441: Handler[] result;
442: if (handlers == null)
443: result = new Handler[0];
444: else {
445: result = new Handler[handlers.size()];
446: int i = 0;
447: for (Enumeration e = handlers.elements(); e
448: .hasMoreElements(); i++) {
449: result[i] = (Handler) (e.nextElement());
450: }
451: }
452: return (result);
453: }
454:
455: public Handler getHandler(String hn) {
456: return (handlers == null ? null : (Handler) handlers.get(hn));
457: }
458:
459: public String[] getTopic() {
460: if (topics == null) {
461: String[] ar = { name };
462: return ar;
463: } else {
464: String[] str = new String[topics.size()];
465: for (int i = 0; i < topics.size(); i++) {
466: str[i] = (String) (topics.elementAt(i));
467: }
468: return str;
469: }
470: }
471:
472: // IMPLEMENTATION OF THE Handler INTERFACE //
473: //-----------------------------------------//
474: public String getName() {
475: return name;
476: }
477:
478: public void setName(String n) {
479: name = n;
480: }
481:
482: public String getType() {
483: return "logger";
484: }
485:
486: public String[] getAttributeNames() {
487: String[] ar = { PRINT_WRITER };
488: return ar;
489: }
490:
491: public Object getAttribute(String name) {
492: if (PRINT_WRITER.equalsIgnoreCase(name)) {
493: return pw;
494: }
495: return null;
496: }
497:
498: public Object setAttribute(String name, Object value) {
499: if (PRINT_WRITER.equalsIgnoreCase(name) && value != null
500: && value instanceof PrintWriter) {
501: pw = (PrintWriter) value;
502: }
503: return null;
504: }
505:
506: /**
507: * This method permits to format messages. More exatcly this method find
508: * the class name and the method name where the log call was done.
509: * In order to find the right class name and method name, this method is
510: * parametrable either the number of call done in this logger.
511: */
512: public static String format(String msg, int removeTopStack) {
513: Throwable t = new Throwable().fillInStackTrace();
514: StringWriter sw = new StringWriter();
515: t.printStackTrace(new PrintWriter(sw));
516: String m = sw.getBuffer().toString();
517:
518: int deb = -1;
519:
520: int fin = 0;
521:
522: // take the right line
523: deb = -1;
524: for (int i = 0; i < (removeTopStack + 1); i++) {
525: deb = m.indexOf("\n", deb + 1);
526: }
527:
528: deb = m.indexOf("at ", deb);
529: fin = m.indexOf("\n", deb);
530: m = m.substring(deb + 3, fin);
531:
532: // remove param
533: deb = m.indexOf("(");
534: fin = m.indexOf(":");
535: m = m.substring(0, deb + 1) + m.substring(fin + 1, m.length());
536:
537: // remove package name
538: deb = m.indexOf("(");
539: int c1 = 0;
540: int c2 = 0;
541: int current = m.indexOf(".");
542: while (current != -1 && current < deb) {
543: c1 = c2;
544: c2 = current;
545: current = m.indexOf(".", current + 1);
546: }
547: m = m.substring(c1 + 1, m.length());
548:
549: return m + ": " + msg;
550: }
551:
552: static {
553: if (BasicLevel.FATAL <= 0 || BasicLevel.ERROR <= 0
554: || BasicLevel.WARN <= 0 || BasicLevel.INFO <= 0
555: || BasicLevel.DEBUG <= 0) {
556: BasicLevel.FATAL = 50000;
557: BasicLevel.ERROR = 40000;
558: BasicLevel.WARN = 30000;
559: BasicLevel.INFO = 20000;
560: BasicLevel.DEBUG = 10000;
561: }
562: }
563: }
|