Project Report: fawkez

Packagesummary org.jcoderz.commons

org.jcoderz.commons.DevelopersLogFormatter

LineHitsNoteSource
1  /*
2   * $Id: DevelopersLogFormatter.java 1360 2009-03-29 12:06:12Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons;
34  
35  
36  import java.io.PrintWriter;
37  import java.io.StringWriter;
38  import java.text.MessageFormat;
39  import java.util.Arrays;
40  import java.util.Iterator;
41  import java.util.logging.Formatter;
42  import java.util.logging.Level;
43  import java.util.logging.LogRecord;
44  
45  import org.jcoderz.commons.types.Date;
46  import org.jcoderz.commons.util.ArraysUtil;
47  import org.jcoderz.commons.util.StringUtil;
48  
49  /**
50   * This type implements a Formatter to be used for logging onto
51   * the console. It tries to fulfill developers need during development
52   * as console output and is not meant to be a production system logger.
53   * It formats both standard a {@link java.util.logging.LogRecord} and
54   * instances of {@link org.jcoderz.commons.Loggable}.
55   *
56   */
570(1)public class DevelopersLogFormatter
58        extends Formatter
59  {
600(2)(3)   private final ThreadLocal mMessageFormatters = new ThreadLocal();
61  
620(4)   private static final String LINE_SEPARATOR
63         = System.getProperty("line.separator");
64 (5)   private static final int LOCATION_LENGTH = 30;
65  
66 (6)   private static final long DUMP_TIME_DIFF = 60 * 1000;
67  
68     // THREADSAVE?
690    private long mLastCall = 0;
70  
71  
72     /** {@inheritDoc} */
73     public String format (LogRecord record)
74     {
750       final StringBuffer sb = new StringBuffer();
760       Loggable loggable = null;
770       if (record.getParameters() != null && record.getParameters().length > 0)
78        {
790          if (record.getParameters()[0] instanceof Loggable)
80           {
810(7)            loggable = (Loggable) record.getParameters()[0];
82           }
83        }
84  
850       if (record.getMillis() - mLastCall >= DUMP_TIME_DIFF)
86        {
870           mLastCall = record.getMillis();
880           formatDumpTime(sb, record.getMillis());
89        }
90  
910       if (record.getLevel() == Level.FINER)
92        {
930(8)(9)          if (record.getMessage() == "THROW")
94            {
950               formatThrown(sb, record);
96            }
970(10)          else if (record.getMessage() == "ENTRY")
98            {
990               formatEntering(sb, record);
100            }
1010(11)          else if (record.getMessage() == "ENTRY {0}")
102            {
1030               formatEntering(sb, record);
104            }
1050           else if (record.getMessage().startsWith("ENTRY {0} {1}"))
106            {
1070               formatEntering(sb, record);
108            }
1090(12)          else if (record.getMessage() == "RETURN")
110            {
1110               formatExiting(sb, record);
112            }
1130(13)          else if (record.getMessage() == "RETURN {0}")
114            {
1150               formatExiting(sb, record);
116            }
117            else
118            {
1190               format(sb, record);
120            }
121        }
122        else
123        {
1240           format(sb, record);
125        }
1260       sb.append(LINE_SEPARATOR);
127  
1280       return sb.toString();
129     }
130  
131     private void formatDumpTime (StringBuffer sb, long millis)
132     {
1330        sb.append(new Date(millis).toString());
1340        sb.append(LINE_SEPARATOR);
1350    }
136  
137     private void format (StringBuffer sb, LogRecord record)
138     {
1390        formatLevelMarkerStart(sb, record.getLevel());
1400        sb.append(getChar(record.getLevel()));
1410        formatLocation(sb, record);
1420        sb.append(": ");
1430        formatMessage(sb, record);
1440        if (record.getThrown() != null)
145         {
1460            sb.append(LINE_SEPARATOR);
1470            formatStackTrace(sb, record.getThrown());
148         }
1490        formatLevelMarkerEnd(sb, record.getLevel());
1500    }
151  
152  
153     private void formatStackTrace (StringBuffer sb, Throwable thrown)
154 (14)   { // TODO: Refine
1550        final StringWriter sw = new StringWriter();
1560        final PrintWriter pw = new PrintWriter(sw);
1570        thrown.printStackTrace(pw);
1580        sb.append(sw.toString().trim());
1590    }
160  
161     private void formatMessage (StringBuffer sb, LogRecord record)
162     {
1630        final Object [] parameters = record.getParameters();
1640        final String msg = record.getMessage();
1650(15)       if (parameters != null && parameters.length != 0 &&
166             !StringUtil.isEmptyOrNull(msg) && msg.indexOf('{') >= 0)
167         {
168             try
169             {
1700                final MessageFormat formatter = new MessageFormat(msg);
1710                formatter.format(parameters, sb, null);
172             }
1730            catch (IllegalArgumentException ex)
174             {
1750                sb.append(ArraysUtil.toString(parameters));
1760                sb.append(' ');
1770                sb.append(msg);
1780            }
179         }
180         else
181         {
1820            sb.append(msg);
183         }
1840    }
185  
186  
187     private static void formatEntering (StringBuffer sb, LogRecord record)
188     {
1890        sb.append('>'); // Indent?
1900        formatLocation(sb, record);
1910        sb.append('(');
1920        formatArgumentsCompact(sb, record.getParameters());
1930        sb.append(')');
1940    }
195  
196     private static void formatExiting (StringBuffer sb, LogRecord record)
197     {
1980        sb.append('<'); // Indent?
1990        formatLocation(sb, record);
2000        sb.append(' ');
2010        formatArgumentsCompact(sb, record.getParameters());
2020    }
203  
204     private static void formatArgumentsCompact (StringBuffer sb,
205         Object[] parameters)
206     {
2070        final Iterator i = Arrays.asList(parameters).iterator();
2080        while (i.hasNext())
209         {
2100(16)           Object parameter = i.next();
2110            sb.append(parameter);
2120            if (i.hasNext())
213             {
2140                sb.append(", ");
215             }
2160        }
2170    }
218  
219     private static void formatThrown (StringBuffer sb, LogRecord record)
220     {
2210        sb.append('!'); // Throwing!
2220        formatLocation(sb, record);
2230        sb.append(": ");
2240        formatThrowableCompact(sb, record.getThrown());
2250    }
226  
227      private static void formatThrowableCompact (StringBuffer sb,
228          Throwable thrown)
229      {
2300         Throwable ex = thrown;
2310         sb.append(String.valueOf(ex));
2320         while (ex.getCause() != null)
233          {
2340             sb.append(" CAUSED BY: ");
2350             sb.append(String.valueOf(ex));
2360             ex = ex.getCause();
237          }
2380     }
239  
240      private static void formatLocation (StringBuffer sb, LogRecord record)
241 (17)    { // TODO: Refine!!
242  
2430         final String className = record.getSourceClassName();
2440         final StringBuffer b = new StringBuffer();
2450         if (!StringUtil.isEmptyOrNull(className))
246          {
2470             b.append(className);
248          }
249          else
250          {
2510             b.append('?');
252          }
2530         b.append('.');
2540         final String methodName = record.getSourceMethodName();
2550         if (!StringUtil.isEmptyOrNull(methodName))
256          {
2570             b.append(methodName);
258          }
259          else
260          {
2610             b.append('?');
262          }
2630         while (b.length() < LOCATION_LENGTH)
264          { // IMPROVEME
2650             b.insert(0, ' ');
266          }
2670         if (b.length() > LOCATION_LENGTH)
268          {
2690             b.replace(0, b.length() - LOCATION_LENGTH , "");
270          }
2710         sb.append(b);
2720     }
273  
274      private char getChar (Level level)
275      {
2760         final int value = level.intValue();
277          final char result;
2780         if (value <= Level.FINEST.intValue())
279          {
2800             result = '.';
281          }
2820         else if (value <= Level.FINER.intValue())
283          {
2840             result = 'o';
285          }
2860         else if (value <= Level.FINE.intValue())
287          {
2880             result = 'O';
289          }
2900         else if (value <= Level.CONFIG.intValue())
291          {
2920             result = '#';
293          }
2940         else if (value <= Level.INFO.intValue())
295          {
2960             result = ' ';
297          }
2980         else if (value <= Level.WARNING.intValue())
299          {
3000             result = '!';
301          }
3020         else if (value <= Level.SEVERE.intValue())
303          {
3040             result = '*';
305          }
306          else
307          {
3080             result = '|';
309          }
3100         return result;
311      }
312  
313      private void formatLevelMarkerStart (StringBuffer sb, Level level)
314      {
3150         final int value = level.intValue();
3160         if (value > Level.INFO.intValue())
317          {
3180             sb.append("+----------------------------------");
3190             sb.append(LINE_SEPARATOR);
320          }
3210     }
322  
323      private void formatLevelMarkerEnd (StringBuffer sb, Level level)
324      {
3250         final int value = level.intValue();
3260         if (value > Level.INFO.intValue())
327          {
3280             sb.append(LINE_SEPARATOR);
3290             sb.append("+----------------------------------");
330          }
3310     }
332  }

Findings in this File

c (1) 57 : 0 Type Javadoc comment is missing an @author tag.
w (2) 60 : 0 class org.jcoderz.commons.DevelopersLogFormatter defines fields that are used only as locals
i (3) 60 : 0 Unread field: org.jcoderz.commons.DevelopersLogFormatter.mMessageFormatters
c (4) 62 : 4 Static variable definition in wrong order.
c (5) 64 : 4 Static variable definition in wrong order.
c (6) 66 : 4 Static variable definition in wrong order.
w (7) 81 : 0 Dead store to loggable in org.jcoderz.commons.DevelopersLogFormatter.format(LogRecord)
c (8) 93 : 35 Literal Strings should be compared using equals(), not '=='.
i (9) 93 : 0 Comparison of String objects using == or != in org.jcoderz.commons.DevelopersLogFormatter.format(LogRecord)
c (10) 97 : 40 Literal Strings should be compared using equals(), not '=='.
c (11) 101 : 40 Literal Strings should be compared using equals(), not '=='.
c (12) 109 : 40 Literal Strings should be compared using equals(), not '=='.
c (13) 113 : 40 Literal Strings should be compared using equals(), not '=='.
i (14) 154 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
c (15) 165 : 57 '&&' should be on a new line.
c (16) 210 : 19 Variable 'parameter' should be declared final.
i (17) 241 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.