KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > incava > qualog > QlWriter


1 package org.incava.qualog;
2
3 import java.io.*;
4 import java.util.*;
5
6
7 /**
8  * <p>Writes the logging output, applying filters and decorations. The
9  * <code>Qualog</code> class offers a much cleaner and more thorough interface
10  * than this class.</p>
11  *
12  * @see org.incava.qualog.Qualog
13  */

14 public class QlWriter
15 {
16     public static final int NO_OUTPUT = 0;
17
18     public static final int QUIET = 1;
19     
20     public static final int VERBOSE = 2;
21     
22     public int fileWidth = 25;
23
24     public boolean columns = true;
25
26     public int lineWidth = 5;
27
28     public int functionWidth = 25;
29
30     public int classWidth = 35;
31
32     public boolean showFiles = true;
33
34     public boolean showClasses = true;
35     
36     public PrintWriter out = new PrintWriter(System.out, true);
37
38     public List packagesSkipped = new ArrayList(Arrays.asList(
39                                                     new String JavaDoc[] {
40                                                         "org.incava.qualog",
41                                                     }));
42     
43     public List classesSkipped = new ArrayList(Arrays.asList(
44                                                    new String JavaDoc[] {
45                                                        "tr.Ace"
46                                                    }));
47     
48     public List methodsSkipped = new ArrayList(Arrays.asList(
49                                                    new String JavaDoc[] {
50                                                    }));
51
52     private int outputType = NO_OUTPUT;
53
54     private Map packageColors = new HashMap();
55
56     private Map classColors = new HashMap();
57
58     private Map methodColors = new HashMap();
59
60     private Map fileColors = new HashMap();
61
62     private Map levelColors = new HashMap();
63
64     private StackTraceElement JavaDoc prevStackElement = null;
65     
66     private Thread JavaDoc prevThread = null;
67
68     private String JavaDoc prevDisplayedClass = null;
69
70     private String JavaDoc prevDisplayedMethod = null;
71
72     private QlLevel level = Qualog.LEVEL9;
73
74     private List filters = new ArrayList();
75
76     private boolean useColor = true;
77
78     /**
79      * Adds a filter to be applied for output.
80      *
81      * @see org.incava.qualog.QlFilter
82      */

83     public void addFilter(QlFilter filter)
84     {
85         filters.add(filter);
86     }
87
88     public void setDisabled(Class JavaDoc cls)
89     {
90         addFilter(new QlClassFilter(cls, null));
91     }
92
93     public void setClassColor(String JavaDoc className, ANSIColor color)
94     {
95         classColors.put(className, color);
96     }
97
98     public void setPackageColor(String JavaDoc pkg, ANSIColor color)
99     {
100     }
101
102     public void setMethodColor(String JavaDoc className, String JavaDoc methodName, ANSIColor color)
103     {
104         methodColors.put(className + "#" + methodName, color);
105     }
106
107     public void clearClassColor(String JavaDoc className)
108     {
109         classColors.remove(className);
110     }
111
112     public void setFileColor(String JavaDoc fileName, ANSIColor color)
113     {
114         fileColors.put(fileName, color);
115     }
116
117     public void set(boolean columns, int fileWidth, int lineWidth, int classWidth, int functionWidth)
118     {
119         this.columns = columns;
120         this.fileWidth = fileWidth;
121         this.lineWidth = lineWidth;
122         this.classWidth = classWidth;
123         this.functionWidth = functionWidth;
124     }
125
126     /**
127      * Sets the output type and level. Either verbose or quiet can be enabled.
128      */

129     public void setOutput(int type, QlLevel level)
130     {
131         this.outputType = type;
132         this.level = level;
133     }
134
135     public boolean verbose()
136     {
137         return outputType == VERBOSE;
138     }
139
140     public void setColumns(boolean cols)
141     {
142         columns = cols;
143     }
144
145     public void addClassSkipped(Class JavaDoc cls)
146     {
147         addClassSkipped(cls.getName());
148     }
149     
150     public void addClassSkipped(String JavaDoc clsName)
151     {
152         classesSkipped.add(clsName);
153     }
154
155     /**
156      * Resets parameters to their defaults.
157      */

158     public void clear()
159     {
160         packageColors = new HashMap();
161         classColors = new HashMap();
162         methodColors = new HashMap();
163         fileColors = new HashMap();
164         levelColors = new HashMap();
165         prevStackElement = null;
166         prevThread = null;
167         prevDisplayedClass = null;
168         prevDisplayedMethod = null;
169         level = Qualog.LEVEL9;
170         filters = new ArrayList();
171     }
172
173     public void reset()
174     {
175         prevThread = Thread.currentThread();
176         prevStackElement = null;
177     }
178
179     public boolean stack(QlLevel level,
180                          ANSIColor[] msgColors,
181                          String JavaDoc name,
182                          Object JavaDoc obj,
183                          ANSIColor fileColor,
184                          ANSIColor classColor,
185                          ANSIColor methodColor,
186                          int numFrames)
187     {
188         if (isLoggable(level)) {
189             String JavaDoc nm = name == null ? "" : name;
190         
191             if (obj == null) {
192                 String JavaDoc msg = nm + ": " + "null";
193                 return stack(level, msgColors, msg, fileColor, classColor, methodColor, numFrames);
194             }
195             else if (obj instanceof Collection) {
196                 Collection c = (Collection)obj;
197                 return QlCollection.stack(level, msgColors, nm, c, fileColor, classColor, methodColor, numFrames);
198             }
199             else if (obj instanceof Iterator) {
200                 Iterator it = (Iterator)obj;
201                 return QlIterator.stack(level, msgColors, nm, it, fileColor, classColor, methodColor, numFrames);
202             }
203             else if (obj instanceof Enumeration) {
204                 Enumeration en = (Enumeration)obj;
205                 return QlEnumeration.stack(level, msgColors, nm, en, fileColor, classColor, methodColor, numFrames);
206             }
207             else if (obj instanceof Object JavaDoc[]) {
208                 Object JavaDoc[] ary = (Object JavaDoc[])obj;
209                 return QlObjectArray.stack(level, msgColors, nm, ary, fileColor, classColor, methodColor, numFrames);
210             }
211             else if (obj instanceof Map) {
212                 Map m = (Map)obj;
213                 return QlMap.stack(level, msgColors, nm, m, fileColor, classColor, methodColor, numFrames);
214             }
215             else if (obj.getClass().isArray()) {
216                 String JavaDoc[] strs = null;
217                 if (obj instanceof byte[]) {
218                     byte[] ary = (byte[])obj;
219                     strs = new String JavaDoc[ary.length];
220                     for (int ai = 0; ai < ary.length; ++ai) {
221                         strs[ai] = String.valueOf(ary[ai]);
222                     }
223                 }
224                 else if (obj instanceof char[]) {
225                     char[] ary = (char[])obj;
226                     strs = new String JavaDoc[ary.length];
227                     for (int ai = 0; ai < ary.length; ++ai) {
228                         strs[ai] = String.valueOf(ary[ai]);
229                     }
230                 }
231                 else if (obj instanceof double[]) {
232                     double[] ary = (double[])obj;
233                     strs = new String JavaDoc[ary.length];
234                     for (int ai = 0; ai < ary.length; ++ai) {
235                         strs[ai] = String.valueOf(ary[ai]);
236                     }
237                 }
238                 else if (obj instanceof float[]) {
239                     float[] ary = (float[])obj;
240                     strs = new String JavaDoc[ary.length];
241                     for (int ai = 0; ai < ary.length; ++ai) {
242                         strs[ai] = String.valueOf(ary[ai]);
243                     }
244                 }
245                 else if (obj instanceof int[]) {
246                     int[] ary = (int[])obj;
247                     strs = new String JavaDoc[ary.length];
248                     for (int ai = 0; ai < ary.length; ++ai) {
249                         strs[ai] = String.valueOf(ary[ai]);
250                     }
251                 }
252                 else if (obj instanceof long[]) {
253                     long[] ary = (long[])obj;
254                     strs = new String JavaDoc[ary.length];
255                     for (int ai = 0; ai < ary.length; ++ai) {
256                         strs[ai] = String.valueOf(ary[ai]);
257                     }
258                 }
259
260                 return QlObjectArray.stack(level, msgColors, nm, strs, fileColor, classColor, methodColor, numFrames);
261             }
262             else {
263                 String JavaDoc msg = nm + ": " + objectToString(obj);
264                 return stack(level, msgColors, msg, fileColor, classColor, methodColor, numFrames);
265             }
266         }
267         else {
268             return true;
269         }
270     }
271
272     public boolean isSkipped(StackTraceElement JavaDoc ste)
273     {
274         String JavaDoc className = ste.getClassName();
275         if (classesSkipped.contains(className) || methodsSkipped.contains(ste.getMethodName())) {
276             return true;
277         }
278         else {
279             Iterator pit = packagesSkipped.iterator();
280             while (pit.hasNext()) {
281                 String JavaDoc pkgName = (String JavaDoc)pit.next();
282                 if (className.startsWith(pkgName)) {
283                     return true;
284                 }
285             }
286         }
287         return false;
288     }
289
290     public boolean isLoggable(QlLevel level)
291     {
292         return outputType != NO_OUTPUT && this.level != null && this.level.compareTo(level) >= 0;
293     }
294
295
296     /**
297      * Returns the index in the stack where logging (stacks) should be
298      * displayed. Returns -1 if the end of the stack is reached and no logging
299      * should occur.
300      */

301     public synchronized int findStackStart(StackTraceElement JavaDoc[] stack)
302     {
303         for (int fi = 0; fi < stack.length; ++fi) {
304             if (!isSkipped(stack[fi])) {
305                 return fi;
306             }
307         }
308         
309         return stack.length;
310     }
311
312     public synchronized boolean stack(QlLevel lvl,
313                                       ANSIColor[] msgColor,
314                                       String JavaDoc msg,
315                                       ANSIColor fileColor,
316                                       ANSIColor classColor,
317                                       ANSIColor methodColor,
318                                       int numFrames)
319     {
320         if (isLoggable(lvl)) {
321             if (outputType == QUIET) {
322                 numFrames = 1;
323             }
324
325             StackTraceElement JavaDoc[] stack = getStack(numFrames);
326
327             // when we're switching threads, reset to a null state.
328
if (!Thread.currentThread().equals(prevThread)) {
329                 reset();
330             }
331
332             int fi = findStackStart(stack);
333
334             for (int framesShown = 0; fi < stack.length && framesShown < numFrames; ++fi, ++framesShown) {
335                 StackTraceElement JavaDoc stackElement = stack[fi];
336                 String JavaDoc className = stackElement.getClassName();
337                 String JavaDoc methodName = stackElement.getMethodName();
338                 boolean filtered = false;
339                 
340                 if (framesShown == 0) {
341                     Iterator fit = filters.iterator();
342                     while (fit.hasNext()) {
343                         QlFilter filter = (QlFilter)fit.next();
344                         int lineNum = stackElement.getLineNumber();
345                         String JavaDoc fileName = stackElement.getFileName();
346                             
347                         if (filter.isMatch(fileName, lineNum, className, methodName)) {
348                             QlLevel flevel = filter.getLevel();
349                             filtered = filtered || flevel != null && level.compareTo(flevel) < 0;
350                         }
351                     }
352                 }
353
354                 if (filtered) {
355                     return true;
356                 }
357
358                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
359
360                 if (outputType == VERBOSE) {
361                     if (showFiles) {
362                         outputFileName(buf, fileColor, stackElement);
363                     }
364                     if (showClasses) {
365                         outputClassAndMethod(buf, classColor, methodColor, stackElement);
366                     }
367                 }
368                 outputMessage(buf, framesShown, msgColor, msg, stackElement);
369
370                 out.println(buf.toString());
371
372                 // System.err.println("buf: " + buf.toString());
373

374                 prevStackElement = stackElement;
375             }
376         }
377         return true;
378     }
379
380     void setUseColor(boolean useColor)
381     {
382         this.useColor = useColor;
383     }
384
385     protected void outputFileName(StringBuffer JavaDoc buf, ANSIColor fileColor, StackTraceElement JavaDoc stackElement)
386     {
387         String JavaDoc fileName = stackElement.getFileName();
388         
389         buf.append("[");
390         if (fileName == null) {
391             fileName = "";
392         }
393
394         if (prevStackElement != null &&
395             prevStackElement.getFileName() != null &&
396             prevStackElement.getFileName().equals(fileName)) {
397             
398             int width = columns ? Math.min(fileWidth, fileName.length()) : fileName.length();
399             fileName = repeat(width, ' ');
400         }
401
402         String JavaDoc lnStr = stackElement.getLineNumber() >= 0 ? String.valueOf(stackElement.getLineNumber()) : "";
403
404         ANSIColor col = fileColor;
405         if (col == null) {
406             col = (ANSIColor)fileColors.get(fileName);
407         }
408
409         if (columns) {
410             if (col == null) {
411                 appendPadded(buf, fileName, fileWidth);
412                 buf.append(' ');
413                 buf.append(repeat(lineWidth - lnStr.length(), ' ')).append(lnStr);
414             }
415             else {
416                 buf.append(col);
417                 buf.append(fileName);
418                 buf.append(Qualog.NONE);
419                 repeat(buf, fileWidth - fileName.length(), ' ');
420                 repeat(buf, 1 + lineWidth - lnStr.length(), ' ');
421                 buf.append(col).append(lnStr).append(Qualog.NONE);
422             }
423         }
424         else if (col == null) {
425             appendPadded(buf, fileName + ":" + lnStr, fileWidth);
426         }
427         else {
428             buf.append(col);
429             buf.append(fileName);
430             buf.append(':');
431             buf.append(lnStr);
432             buf.append(Qualog.NONE);
433             repeat(buf, fileWidth - fileName.length() - 1 - lnStr.length(), ' ');
434         }
435
436         buf.append("] ");
437     }
438
439     protected void outputClassAndMethod(StringBuffer JavaDoc buf,
440                                         ANSIColor classColor,
441                                         ANSIColor methodColor,
442                                         StackTraceElement JavaDoc stackElement)
443     {
444         buf.append("{");
445
446         String JavaDoc className = stackElement.getClassName();
447         
448         if (classColor == null) {
449             classColor = (ANSIColor)classColors.get(className);
450         }
451         
452         boolean sameClass = prevStackElement != null && prevStackElement.getClassName().equals(className);
453         if (sameClass) {
454             className = repeat(prevDisplayedClass.length(), ' ');
455             classColor = null;
456         }
457         else if (className != null && (className.startsWith("org.") || className.startsWith("com."))) {
458             className = "..." + className.substring(className.indexOf('.', 5) + 1);
459         }
460
461         int totalWidth = classWidth + 1 + functionWidth;
462
463         int classPadding = 0;
464         if (className.length() > classWidth) {
465             if (classWidth > 0) {
466                 className = className.substring(0, classWidth - 1) + '-';
467             }
468             else {
469                 className = "";
470             }
471         }
472         else {
473             classPadding = classWidth - className.length();
474         }
475
476         if (classColor != null) {
477             buf.append(classColor);
478         }
479         buf.append(className);
480         if (classColor != null) {
481             buf.append(Qualog.NONE);
482         }
483
484         if (columns) {
485             repeat(buf, classPadding, ' ');
486         }
487
488         prevDisplayedClass = className;
489
490         buf.append('#');
491         
492         String JavaDoc methodName = stackElement.getMethodName();
493
494         if (methodColor == null) {
495             methodColor = (ANSIColor)methodColors.get(methodName);
496         }
497         
498         if (sameClass && prevStackElement != null && prevStackElement.getMethodName().equals(methodName)) {
499             methodName = repeat(prevDisplayedMethod.length(), ' ');
500             methodColor = null;
501         }
502
503         int methodPadding = 0;
504         if (methodName.length() > functionWidth) {
505             methodName = methodName.substring(0, functionWidth - 1) + '-';
506         }
507         else {
508             methodPadding = functionWidth - methodName.length();
509         }
510
511         if (methodColor != null) {
512             buf.append(methodColor);
513         }
514         buf.append(methodName);
515         if (methodColor != null) {
516             buf.append(Qualog.NONE);
517         }
518
519         if (!columns) {
520             repeat(buf, classPadding, ' ');
521         }
522         repeat(buf, methodPadding, ' ');
523
524         prevDisplayedMethod = methodName;
525
526         buf.append("} ");
527     }
528
529     protected void outputMessage(StringBuffer JavaDoc buf,
530                                  int framesShown,
531                                  ANSIColor[] msgColor,
532                                  String JavaDoc msg,
533                                  StackTraceElement JavaDoc stackElement)
534     {
535         // remove ending EOLN
536
if (framesShown > 0) {
537             msg = "\"\"";
538         }
539         else {
540             while (msg.length() > 0 && "\r\n".indexOf(msg.charAt(msg.length() - 1)) != -1) {
541                 msg = msg.substring(0, msg.length() - 1);
542             }
543             if (useColor) {
544                 boolean hasColor = false;
545                 if (msgColor == null || (msgColor.length > 0 && msgColor[0] == null)) {
546                     ANSIColor col = null;
547                     col = (ANSIColor)methodColors.get(stackElement.getClassName() + "#" + stackElement.getMethodName());
548                     if (col == null) {
549                         col = (ANSIColor)classColors.get(stackElement.getClassName());
550                         if (col == null) {
551                             col = (ANSIColor)fileColors.get(stackElement.getFileName());
552                         }
553                     }
554                     if (col != null) {
555                         msg = col + msg;
556                         hasColor = true;
557                     }
558                 }
559                 else {
560                     for (int i = 0; i < msgColor.length; ++i) {
561                         if (msgColor[i] != null) {
562                             msg = msgColor[i] + msg;
563                             hasColor = true;
564                         }
565                     }
566                 }
567
568                 if (hasColor) {
569                     msg += Qualog.NONE;
570                 }
571             }
572         }
573
574         buf.append(msg);
575     }
576     
577     protected StackTraceElement JavaDoc[] getStack(int depth)
578     {
579         return (new Exception JavaDoc("")).getStackTrace();
580     }
581
582     protected String JavaDoc repeat(int len, char ch)
583     {
584         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
585         for (int i = 0; i < len; ++i) {
586             buf.append(ch);
587         }
588         return buf.toString();
589     }
590
591     protected StringBuffer JavaDoc repeat(StringBuffer JavaDoc buf, int len, char ch)
592     {
593         for (int i = 0; i < len; ++i) {
594             buf.append(ch);
595         }
596         return buf;
597     }
598
599     protected void appendPadded(StringBuffer JavaDoc buf, String JavaDoc str, int maxSize)
600     {
601         if (str.length() > maxSize) {
602             buf.append(str.substring(0, maxSize - 1)).append("-");
603         }
604         else {
605             buf.append(str);
606             repeat(buf, maxSize - str.length(), ' ');
607         }
608     }
609
610     protected String JavaDoc objectToString(Object JavaDoc obj)
611     {
612         String JavaDoc str = null;
613         if (obj == null) {
614             str = "null";
615         }
616         else {
617             Class JavaDoc[] undecorated = new Class JavaDoc[] {
618                 String JavaDoc.class,
619                 Number JavaDoc.class,
620                 Character JavaDoc.class,
621                 Boolean JavaDoc.class
622             };
623
624             Class JavaDoc cls = obj.getClass();
625
626             for (int ui = 0; ui < undecorated.length; ++ui) {
627                 if (undecorated[ui].isAssignableFrom(cls)) {
628                     str = obj.toString();
629                     break;
630                 }
631             }
632
633             if (str == null) {
634                 str = obj.toString() + " (" + obj.getClass() + ") #" + Integer.toHexString(obj.hashCode());
635             }
636         }
637         return str;
638     }
639         
640
641 }
642
Popular Tags