KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > util > monolog > wrapper > log4j > MonologCategory


1 /**
2  * Copyright (C) 2001-2003 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package org.objectweb.util.monolog.wrapper.log4j;
20
21 import org.apache.log4j.Appender;
22 import org.apache.log4j.Priority;
23 //import org.apache.log4j.Logger;
24
import org.apache.log4j.spi.LoggingEvent;
25 import org.objectweb.util.monolog.api.BasicLevel;
26 import org.objectweb.util.monolog.api.Handler;
27 import org.objectweb.util.monolog.api.Level;
28 import org.objectweb.util.monolog.api.TopicalLogger;
29 import org.objectweb.util.monolog.wrapper.common.AbstractFactory;
30 import org.objectweb.util.monolog.wrapper.common.EnumrationImpl;
31
32 import java.io.PrintWriter JavaDoc;
33 import java.io.StringWriter JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Enumeration JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.Iterator JavaDoc;
38
39 /**
40  * This class wraps the Logger concept into the log4j world. This class extends
41  * therefore the Logger class. This implementation supports
42  * <ul>
43  * <li>The multiple topic feature by adding a parent list into each node.</li>
44  * <li>The inheritance model: The same instance represents the monolog aspect
45  * (Logger) and the Log4j aspect (Logger).
46  * <li>The delegation model: There are two instances, a Logger object (or a
47  * class which inherits from Logger as RootLogger), and a MonologCategory
48  * which delegates calls to the first objects.</li>
49  * </ul>
50  *
51  * @author Sebastien Chassande-Barrioz
52  */

53 public class MonologCategory
54     extends org.apache.log4j.Logger
55     implements TopicalLogger {
56
57     protected boolean enable = true;
58     protected final static int DISABLE_OFF = -1;
59     protected final static int DISABLE_ON = org.apache.log4j.Level.FATAL.toInt();
60     protected OwPriority interPriority = null;
61     protected byte depth = 2;
62
63     /**
64      * This field references all parent of this Logger.
65      * key = topic of the current logger
66      * value = its parent either the topic. A parent can be a MonologCategory or
67      * a Logger.
68      */

69     protected HashMap JavaDoc topicToparents = null;
70
71     /**
72      * This field references all appenders associated to the current Logger
73      */

74     protected ArrayList JavaDoc appenders = null;
75
76     /**
77      * This field references the inner Logger if the delegation was choosen.
78      */

79     protected org.apache.log4j.Logger categ = null;
80
81     /**
82      * This field is the class name of the class localized in the top of the
83      * log system layer. The initial value is by default the class name of this
84      * class. Indeed the monolog call directly this class. This information
85      * is used to knwon the caller in the execution stack.
86      */

87     private final static String JavaDoc instanceFQN
88         = "org.objectweb.util.monolog.wrapper.log4j.MonologCategory";
89
90     /**
91      * This constructor initializes the instance in inheritance mode. It
92      * initializes the instanceFQN, and struture of parents.
93      */

94     public MonologCategory(String JavaDoc _initialName) {
95         super(_initialName);
96         topicToparents = new HashMap JavaDoc();
97     }
98
99     /**
100      * This constructor initializes the instance in delegation mode.
101      * @param c is the inner Logger. All calls will be foward to this instance
102      */

103     public MonologCategory(org.apache.log4j.Logger c) {
104         super(c.getName());
105         categ = c;
106     }
107
108     /**
109      * It formats a message by adding the object and the method name where the
110      * call to monolog was done.
111      * @param msg is the original message
112      * @param removeTopStack is the number of monolog method call. Indeed this method
113      * fetch a stack trace. This method fetches one line in this stack. The
114      * parameter is the line number in this stack.
115      */

116     public static String JavaDoc format(String JavaDoc msg, int removeTopStack) {
117         Throwable JavaDoc t = new Throwable JavaDoc().fillInStackTrace();
118         StringWriter JavaDoc sw = new StringWriter JavaDoc();
119         t.printStackTrace(new PrintWriter JavaDoc(sw));
120         String JavaDoc m = sw.getBuffer().toString();
121
122         int deb = -1,fin = 0;
123
124         // take the right line
125
deb = -1;
126         for (int i = 0; i < (removeTopStack + 1); i++) {
127             deb = m.indexOf("\n", deb + 1);
128         }
129
130         deb = m.indexOf("at ", deb);
131         fin = m.indexOf("\n", deb);
132         m = m.substring(deb + 3, fin);
133
134         // remove param
135
deb = m.indexOf("(");
136         fin = m.indexOf(":");
137         m = m.substring(0, deb + 1) + m.substring(fin + 1, m.length());
138
139         // remove package name
140
deb = m.indexOf("(");
141         int c1 = 0;
142         int c2 = 0;
143         int current = m.indexOf(".");
144         while (current != -1 && current < deb) {
145             c1 = c2;
146             c2 = current;
147             current = m.indexOf(".", current + 1);
148         }
149         m = m.substring(c1 + 1, m.length());
150
151         return m + ": " + msg;
152     }
153
154     private org.apache.log4j.Level convertToLog4jLevel(int value) {
155         switch (value) {
156         case org.apache.log4j.Level.DEBUG_INT:
157             return org.apache.log4j.Level.DEBUG;
158         case org.apache.log4j.Level.INFO_INT:
159             return org.apache.log4j.Level.INFO;
160         case org.apache.log4j.Level.WARN_INT:
161             return org.apache.log4j.Level.WARN;
162         case org.apache.log4j.Level.ERROR_INT:
163             return org.apache.log4j.Level.ERROR;
164         case org.apache.log4j.Level.FATAL_INT:
165             return org.apache.log4j.Level.FATAL;
166         default:
167             if (interPriority == null)
168                 interPriority = new OwPriority(value);
169             else
170                 interPriority.level = value;
171             return interPriority;
172         }
173     }
174
175     // IMPLEMENTATION OF CLASS org.apache.log4j.Logger
176

177     /**
178      Starting from this Logger, search the Logger hierarchy for a
179      non-null priority and return it. Otherwise, return the priority of the
180      root Logger.
181
182      <p>The Logger class is designed so that this method executes as
183      quickly as possible.
184      */

185     public org.apache.log4j.Level getChainedLevel() {
186         if (categ != null) {
187             return categ.getEffectiveLevel();
188         }
189         if (level != null) {
190             return level;
191         }
192         org.apache.log4j.Level current = parent.getEffectiveLevel();
193         org.apache.log4j.Logger[] cats = (org.apache.log4j.Logger[])
194             topicToparents.values().toArray(new org.apache.log4j.Logger[0]);
195         for (int i = 0; i < cats.length; i++) {
196             org.apache.log4j.Level neo = cats[i].getEffectiveLevel();
197             if (neo.isGreaterOrEqual(current)) {
198                 current = neo;
199             }
200         }
201         return current;
202     }
203
204     /**
205      * In inheritance mode this method delegates the treatment to the other
206      * callAppendes methods.
207      * In delegation mode, the call is forwarded on the inner Logger instance.
208      */

209     public void callAppenders(LoggingEvent event) {
210         if (categ != null) {
211             categ.callAppenders(event);
212         }
213         callAppenders(event, false);
214     }
215
216     /**
217      * This method calls all the parent loggers and call its appender either
218      * the followin condition:
219      * <ul>
220      * <li>if the called parameter is equals to true then all parent are call
221      * with the same value, and the logging event are transmitted to the
222      * appenders. The true is return beacause the event must be transmitted</li>
223      *
224      * <li>Or if the current priority is define and the message priority is
225      * equals or greater then the current priority then all parent are call
226      * with the same value, and the logging event are transmitted to the
227      * appenders. The true is return beacause the event must be transmitted</li>
228      *
229      * <li>Else It is needed to check one of the parent is enable for the
230      * logging event. This is done by the recall of each parent. If one of the
231      * parent return true, then the event must be logged.</li>
232      * </ul>
233      * @param event is the logging event
234      * @param called is the boolean which permits to know if the current logger must
235      * call or not its appender without check its priority.
236      * return true is the logging event is enabled in the current logger or one
237      * of its ancestors.
238      */

239     public synchronized boolean callAppenders(LoggingEvent event, boolean called) {
240         org.apache.log4j.Level l = event.getLevel();
241         if (called
242             || (level != null
243             && l.isGreaterOrEqual(level))) {
244             for (Enumeration JavaDoc en = getAllAppenders();
245                  en.hasMoreElements();) {
246                 ((Appender) en.nextElement()).doAppend(event);
247             }
248             if (additive) {
249                 if (parent instanceof MonologCategory)
250                     ((MonologCategory) parent).callAppenders(event, true);
251                 else
252                     parent.callAppenders(event);
253                 for (Iterator JavaDoc it = topicToparents.values().iterator(); it.hasNext();) {
254                     org.apache.log4j.Logger c = (org.apache.log4j.Logger) it.next();
255                     if (c instanceof MonologCategory)
256                         ((MonologCategory) c).callAppenders(event, true);
257                     else
258                         c.callAppenders(event);
259                 }
260             }
261             return true;
262         }
263         else if (level == null && additive) {
264             if (parent instanceof MonologCategory) {
265                 called |= ((MonologCategory) parent).callAppenders(event, false);
266             }
267             else if (parent.isEnabledFor(l)) {
268                 called = true;
269                 parent.callAppenders(event);
270             }
271             for (Iterator JavaDoc it = topicToparents.values().iterator(); it.hasNext();) {
272                 org.apache.log4j.Logger c = (org.apache.log4j.Logger) it.next();
273                 if (c instanceof MonologCategory) {
274                     called |= ((MonologCategory) c).callAppenders(event, false);
275                 }
276                 else if (c.isEnabledFor(l)) {
277                     called = true;
278                     c.callAppenders(event);
279                 }
280             }
281             if (called) {
282                 for (Enumeration JavaDoc en = getAllAppenders();
283                      en.hasMoreElements();) {
284                     ((Appender) en.nextElement()).doAppend(event);
285                 }
286             }
287         }
288         return called;
289     }
290
291
292     // IMPLEMENTATION OF INTERFACE Logger
293

294     /**
295      * Check if the level parameter are not filtered by the logger
296      */

297     public boolean isLoggable(int l) {
298         if (categ != null) {
299             return l >= categ.getEffectiveLevel().toInt();
300         }
301         return l >= getEffectiveLevel().toInt();
302     }
303
304     public boolean isLoggable(Level l) {
305         if (categ != null) {
306             return l.getIntValue() >= categ.getEffectiveLevel().toInt();
307         }
308         return l.getIntValue() >= getEffectiveLevel().toInt();
309     }
310
311     /**
312      * Is the handler enabled
313      */

314     public boolean isOn() {
315         return enable;
316     }
317
318     /**
319      * Log an object with a specific level. If the level parameter is
320      * loggable the object is handled.
321      */

322     public void log(int l, Object JavaDoc o) {
323         if (!enable || !isLoggable(l)) {
324             return;
325         }
326         if (categ != null)
327             categ.log(convertToLog4jLevel(l), (o == null?o:o.toString()), null);
328         else
329             forcedLog(instanceFQN, convertToLog4jLevel(l), (o == null?o:o.toString()), null);
330     }
331
332     public void log(Level l, Object JavaDoc o) {
333         if (!enable || !isLoggable(l.getIntValue())) {
334             return;
335         }
336         if (categ != null)
337             categ.log(convertToLog4jLevel(l.getIntValue()),
338                     (o == null?o:o.toString()), null);
339         else
340             forcedLog(instanceFQN, convertToLog4jLevel(l.getIntValue()),
341                     (o == null?o:o.toString()), null);
342     }
343
344     /**
345      * Log an object and a trowable with a specific level.
346      */

347     public void log(int l, Object JavaDoc o, Throwable JavaDoc t) {
348         if (!enable || !isLoggable(l)) {
349             return;
350         }
351         if (categ != null)
352             categ.log(convertToLog4jLevel(l),
353                     (o == null?o:o.toString()), t);
354         else
355             forcedLog(instanceFQN, convertToLog4jLevel(l),
356                     (o == null?o:o.toString()), t);
357     }
358
359     public void log(Level l, Object JavaDoc o, Throwable JavaDoc t) {
360         if (!enable || !isLoggable(l.getIntValue())) {
361             return;
362         }
363         if (categ != null)
364             categ.log(convertToLog4jLevel(l.getIntValue()),
365                     (o == null?o:o.toString()), t);
366         else
367             forcedLog(instanceFQN, convertToLog4jLevel(l.getIntValue()),
368                     (o == null?o:o.toString()), t);
369     }
370
371     /**
372      * Log an object and a trowable with a specific level. This method
373      * permits to specify an object instance and a method.
374      */

375     public void log(int l, Object JavaDoc o, Object JavaDoc location, Object JavaDoc method) {
376         if (!enable || !isLoggable(l)) {
377             return;
378         }
379         if (categ != null)
380             categ.log(convertToLog4jLevel(l), (o == null?o:o.toString()), null);
381         else
382             forcedLog(instanceFQN, convertToLog4jLevel(l),
383                 (location == null?"":location.toString())
384                 + (method == null?"":method.toString())
385                 + (o == null?o:o.toString()),
386                 null);
387     }
388
389     public void log(Level l, Object JavaDoc o, Object JavaDoc location, Object JavaDoc method) {
390         if (!enable || !isLoggable(l.getIntValue())) {
391             return;
392         }
393         if (categ != null)
394             categ.log(convertToLog4jLevel(l.getIntValue()), (o == null?o:o.toString()), null);
395         else
396             forcedLog(instanceFQN, convertToLog4jLevel(l.getIntValue()),
397                 (location == null?"":location.toString())
398                 + (method == null?"":method.toString())
399                 + (o == null?o:o.toString()),
400                 null);
401     }
402
403     /**
404      * Log an object and a trowable with a specific level. This method
405      * permits to specify an object instance and a method.
406      */

407     public void log(int l, Object JavaDoc o, Throwable JavaDoc t, Object JavaDoc location,
408                     Object JavaDoc method) {
409         if (!enable || !isLoggable(l)) {
410             return;
411         }
412         if (categ != null)
413             categ.log(convertToLog4jLevel(l), (o == null?o:o.toString()), t);
414         else
415             forcedLog(instanceFQN, convertToLog4jLevel(l),
416                 (location == null?"":location.toString())
417                 + (method == null?"":method.toString())
418                 + (o == null?o:o.toString()),
419                 t);
420     }
421
422     public void log(Level l, Object JavaDoc o, Throwable JavaDoc t, Object JavaDoc location,
423                     Object JavaDoc method) {
424         if (!enable || !isLoggable(l.getIntValue())) {
425             return;
426         }
427         if (categ != null)
428             categ.log(convertToLog4jLevel(l.getIntValue()), (o == null?o:o.toString()), t);
429         else
430             forcedLog(instanceFQN, convertToLog4jLevel(l.getIntValue()),
431                 (location == null?"":location.toString())
432                 + (method == null?"":method.toString())
433                 + (o == null?o:o.toString()),
434                 t);
435     }
436
437     /**
438      * Enable the handler
439      */

440     public void turnOn() {
441         enable = true;
442     }
443
444     /**
445      * Disable the handler
446      */

447     public void turnOff() {
448         enable = false;
449     }
450
451     // IMPLEMENTATION OF INTERFACE TopicalLogger
452

453     /**
454      * Set the current level of the logger
455      */

456     public void setIntLevel(int level) {
457         if (level == BasicLevel.INHERIT) {
458             if (categ != null)
459                 categ.setLevel(null);
460             else
461                 super.setLevel(null);
462             return;
463         }
464         if (categ != null)
465             categ.setLevel(convertToLog4jLevel(level));
466         else
467             super.setLevel(convertToLog4jLevel(level));
468     }
469
470     public void setLevel(Level l) {
471         if (l == null || l.getIntValue() == BasicLevel.INHERIT) {
472             if (categ != null)
473                 categ.setLevel(null);
474             else
475                 super.setLevel(null);
476             return;
477         }
478         if (categ != null)
479             categ.setLevel(convertToLog4jLevel(l.getIntValue()));
480         else
481             super.setLevel(convertToLog4jLevel(l.getIntValue()));
482     }
483
484     /**
485      * Return the current Level of the logger
486      */

487     public int getCurrentIntLevel() {
488         if (categ != null)
489             return categ.getLevel().toInt();
490         else
491             return (level != null ? level.toInt() : BasicLevel.INHERIT);
492     }
493
494     public Level getCurrentLevel() {
495         org.apache.log4j.Level p = null;
496         if (categ != null)
497             p = categ.getLevel();
498         else
499             p = level;
500         if (p != null)
501             return LevelImpl.getLevel(p.toInt());
502         else
503             return BasicLevel.LEVEL_INHERIT;
504     }
505
506     /**
507      * Add a handler in the Handler list of the topicalLogger
508      */

509     public void addHandler(Handler h) throws Exception JavaDoc {
510         if (h instanceof Appender) {
511             if (categ != null)
512                 categ.addAppender((Appender) h);
513             else
514                 super.addAppender((Appender) h);
515         }
516         else
517             throw new UnsupportedOperationException JavaDoc(
518                 "The type of the handler does not match with this wrapper");
519     }
520
521     /**
522      * Add a topic to the topicalLogger
523      */

524     public void addTopic(String JavaDoc topic) throws Exception JavaDoc {
525         if (categ == null) {
526             Object JavaDoc p = parent;
527             String JavaDoc n = name;
528             org.apache.log4j.Logger.getLogger(topic, new BetaCF(this));
529             topicToparents.put(topic, parent);
530             parent = (org.apache.log4j.Logger) p;
531             name = n;
532         }
533     }
534
535     public Handler[] getHandler() {
536         ArrayList JavaDoc al = new ArrayList JavaDoc();
537         if (categ != null) {
538             for (Enumeration JavaDoc en = categ.getAllAppenders(); en.hasMoreElements();) {
539                 Appender a = (Appender) en.nextElement();
540                 if (a instanceof Handler) {
541                     al.add(a);
542                 }
543                 else {
544                     al.add(new GenericHandler(a));
545                 }
546             }
547         }
548         else {
549             for (Enumeration JavaDoc en = getAllAppenders(); en.hasMoreElements();) {
550                 Appender a = (Appender) en.nextElement();
551                 if (a instanceof Handler) {
552                     al.add(a);
553                 }
554                 else {
555                     al.add(new GenericHandler(a));
556                 }
557             }
558         }
559         return (Handler[]) al.toArray(new Handler[0]);
560     }
561
562     public Handler getHandler(String JavaDoc hn) {
563         Appender a = null;
564         if (categ != null) {
565             a = categ.getAppender(hn);
566         }
567         else {
568             a = getAppender(hn);
569         }
570         if (a instanceof Handler) {
571             return (Handler) a;
572         }
573         else {
574             return new GenericHandler(a);
575         }
576     }
577
578     public void removeAllHandlers() throws Exception JavaDoc {
579         if (categ != null) {
580             categ.removeAllAppenders();
581         }
582         else {
583             removeAllAppenders();
584         }
585     }
586
587     /**
588      * Returns the list of the different names of the topicalLogger
589      */

590     public Enumeration JavaDoc getTopics() {
591         return new EnumrationImpl(
592             topicToparents.keySet().toArray(new String JavaDoc[0]));
593     }
594
595     /**
596      * Returns the list of the different names of the topicalLogger
597      */

598     public String JavaDoc[] getTopic() {
599         String JavaDoc[] res = null;
600         if (categ != null) {
601             res = new String JavaDoc[1];
602             res[0] = AbstractFactory.getTopicWithoutPrefix(categ.getName());
603             return res;
604         }
605         res = new String JavaDoc[topicToparents.size() + 1];
606         res[0] = AbstractFactory.getTopicWithoutPrefix(name);
607         int i=1;
608         for (Iterator JavaDoc it = topicToparents.keySet().iterator(); it.hasNext();) {
609             res[i] = AbstractFactory.getTopicWithoutPrefix((String JavaDoc) it.next());
610             i++;
611         }
612         return res;
613     }
614
615     /**
616      * Remove a handler from the Handler list of the topicalLogger
617      */

618     public void removeHandler(Handler h) throws Exception JavaDoc {
619         if (h instanceof Appender) {
620             if (categ != null) {
621                 categ.removeAppender((Appender) h);
622                 if (h instanceof GenericHandler) {
623                     categ.removeAppender(((GenericHandler) h).getAppender());
624                 }
625             }
626             else {
627                 super.removeAppender((Appender) h);
628                 if (h instanceof GenericHandler) {
629                     super.removeAppender(((GenericHandler) h).getAppender());
630                 }
631             }
632         }
633         else
634             throw new UnsupportedOperationException JavaDoc(
635                 "The type of the handler does not match with this wrapper");
636     }
637
638     /**
639      * Remove a topic from the topicalLogger
640      */

641     public void removeTopic(String JavaDoc topic) throws Exception JavaDoc {
642         if (categ == null)
643             topicToparents.remove(topic);
644     }
645
646     // IMPLEMENTATION OF THE Handler INTERFACE //
647
//-----------------------------------------//
648
public void setName(String JavaDoc n) {
649         name = n;
650     }
651
652     public String JavaDoc getType() {
653         return "logger";
654     }
655
656     public String JavaDoc[] getAttributeNames() {
657         return new String JavaDoc[0];
658     }
659
660     public Object JavaDoc getAttribute(String JavaDoc name) {
661         return null;
662     }
663
664     public Object JavaDoc setAttribute(String JavaDoc name, Object JavaDoc value) {
665         return null;
666     }
667
668     // INNER CLASSES //
669
//---------------//
670
public static class OwPriority extends org.apache.log4j.Level {
671
672         protected int level = 10000;
673
674         public OwPriority(int l) {
675             super(l, "INTER", l);
676             this.level = l;
677         }
678
679         public boolean isGreaterOrEqual(Priority pr) {
680             return level >= pr.toInt();
681         }
682     }
683
684     public static class BetaCF implements org.apache.log4j.spi.LoggerFactory {
685         MonologCategory mc = null;
686
687         public BetaCF(MonologCategory mc) {
688             this.mc = mc;
689         }
690
691         public org.apache.log4j.Logger makeNewLoggerInstance(String JavaDoc name) {
692             return mc;
693         }
694     }
695
696 }
697
Popular Tags