Project Report: fawkez

Packagesummary org.jcoderz.commons.logging

org.jcoderz.commons.logging.StackTraceElementParser

LineHitsNoteSource
1  /*
2   * $Id: StackTraceElementParser.java 1011 2008-06-16 17:57:36Z 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.logging;
34  
35  import java.nio.CharBuffer;
36  import java.text.ParseException;
37  import java.util.regex.Matcher;
38  import java.util.regex.Pattern;
39  
40  /**
41   * This helper class is used to parse a CharBuffer containing data of one
42   * line of a StackTrace.
43   * A Stacktrace line is one of:
44   * <ul>
45   * <li><code>at packagename.classname.methodname(</code>...<code>)</code>
46   * <li><code>Caused by: </code>...
47   * <li><code>...</code> nn <code>more</code>
48   * <li><code>exception message</code>
49   * </ul>
50   *
51   */
52 (1)public final class StackTraceElementParser
53  {
540    private static final Pattern FULL_LOCATION_PATTERN = Pattern.compile(
55           "^\\s*at\\s+[^\\s\\.]([^\\s\\(]+\\.)*[^\\s\\(]+\\(.*\\)\\s*$");
560    private static final Pattern LOCATION_PATTERN = Pattern.compile(
57           "^\\s*at\\s+");
580    private static final Pattern CLASS_PATTERN = Pattern.compile(
59           "([^\\s\\(]+\\.)*");
600    private static final Pattern METHOD_PATTERN = Pattern.compile(
61           "[^\\s\\(]+\\s*\\(");
620    private static final Pattern LINE_PATTERN = Pattern.compile(
63           "[^\\d\\)]+");
64  
650    private static final Pattern FULL_CAUSE_PATTERN = Pattern.compile(
66           "^\\s*Caused by\\:\\s*.*$");
670    private static final Pattern CAUSE_PATTERN = Pattern.compile(
68           "^\\s*Caused by\\:\\s*");
69  
700    private static final Pattern FULL_MORE_PATTERN = Pattern.compile(
71           "^\\s*\\.+\\s*\\d+\\s+more\\s*$");
720    private static final Pattern MORE_PATTERN = Pattern.compile(
73           "^\\s*\\.+\\s*");
74  
750    private static final Pattern FULL_EXCEPTION_TEXT_PATTERN = Pattern.compile(
76           "^\\s*.*$");
770    private static final Pattern EXCEPTION_TEXT_PATTERN = Pattern.compile(
78           "^\\s*");
79  
80     /**
81      * Hide the default constructor.
82      */
83     private StackTraceElementParser ()
840    {
85        // nop
860    }
87  
88     /**
89      * Parses the supplied buffer for the parameters of a stacktrace element and
90      * returns the information as StackTraceInfo.
91      *
92      * @param buffer The buffer containing data of one stack trace line.
93      *
94      * @return A new instance of StackTraceInfo containing the information of the
95      * parsed line.
96      *
97      * @throws ParseException if an error occurs.
98      */
99     public static StackTraceInfo parse (final CharBuffer buffer)
100           throws ParseException
101     {
1020       StackTraceInfo rc = null;
1030       StackTraceInfo stInfo = null;
104  
1050(2)      if ((stInfo = parseLocation(buffer)) != null)
106        {
1070          rc = stInfo;
108        }
1090(3)      else if ((stInfo = parseCause(buffer)) != null)
110        {
1110          rc = stInfo;
112        }
1130(4)      else if ((stInfo = parseMore(buffer)) != null)
114        {
1150          rc = stInfo;
116        }
1170(5)      else if ((stInfo = parseMore(buffer)) != null)
118        {
1190          rc = stInfo;
120        }
1210(6)      else if ((stInfo = parseExceptionText(buffer)) != null)
122        {
1230          rc = stInfo;
124        }
125        else
126        {
1270          throw new ParseException(
128                 "Buffer does not match any of the defined patterns: "
129                 + buffer, buffer.position());
130        }
1310       return rc;
132     }
133  
134     private static StackTraceInfo parseLocation (final CharBuffer buffer)
135           throws ParseException
136     {
1370       StackTraceInfo rc = null;
138  
1390       Matcher matcher = FULL_LOCATION_PATTERN.matcher(buffer);
140  
1410       if (matcher.matches())
142        {
1430          final int savePos = buffer.position();
144  
1450          matcher = LOCATION_PATTERN.matcher(buffer);
1460          if (! matcher.lookingAt())
147           {
1480             throw new ParseException("Cannot parse correctly: " + buffer,
149                    buffer.position());
150           }
1510          int pos = matcher.end();
1520          buffer.position(buffer.position() + pos);
1530          matcher = CLASS_PATTERN.matcher(buffer);
1540          if (! matcher.lookingAt())
155           {
1560             throw new ParseException("Cannot parse correctly: " + buffer,
157                    buffer.position());
158           }
1590          pos = matcher.end();
1600          final CharBuffer classname = buffer.asReadOnlyBuffer();
1610          classname.limit(classname.position() + pos - 1);
162  
1630          buffer.position(buffer.position() + pos);
1640          matcher = METHOD_PATTERN.matcher(buffer);
1650          if (! matcher.lookingAt())
166           {
1670             throw new ParseException("Cannot parse correctly: " + buffer,
168                    buffer.position());
169           }
1700          pos = matcher.end();
1710          final CharBuffer methodname = buffer.asReadOnlyBuffer();
1720          methodname.limit(methodname.position() + pos - 1);
1730          int line = -1;
1740          matcher = LINE_PATTERN.matcher(buffer);
175           // this time there need not to be a match
1760          if (matcher.lookingAt())
177           {
1780             pos = matcher.end();
1790             buffer.position(buffer.position() + pos);
1800             boolean digit = false;
1810             int i = 0;
1820             while (Character.isDigit(buffer.charAt(i)))
183              {
1840                ++i;
1850                digit = true;
186              }
1870             if (digit)
188              {
1890                line = Integer.parseInt(buffer.subSequence(0, i).toString());
190              }
191           }
1920          buffer.position(savePos);
1930          rc = new StackTraceInfo(
194                 buffer.asReadOnlyBuffer(), classname, methodname, line);
195        }
1960       return rc;
197     }
198  
199     private static StackTraceInfo parseCause (final CharBuffer buffer)
200           throws ParseException
201     {
2020       StackTraceInfo rc = null;
2030       Matcher matcher = FULL_CAUSE_PATTERN.matcher(buffer);
2040       if (matcher.matches())
205        {
2060          final int savePos = buffer.position();
2070          matcher = CAUSE_PATTERN.matcher(buffer);
2080          if (! matcher.lookingAt())
209           {
2100             throw new ParseException("Cannot parse a caused-by correctly: "
211                    + buffer, buffer.position());
212           }
2130          final int pos = matcher.end();
2140          buffer.position(buffer.position() + pos);
2150          final CharBuffer cause = buffer.asReadOnlyBuffer();
2160          buffer.position(savePos);
2170          rc = new StackTraceInfo(buffer.asReadOnlyBuffer(), cause, true);
218        }
2190       return rc;
220     }
221  
222     private static StackTraceInfo parseExceptionText (final CharBuffer buffer)
223           throws ParseException
224     {
2250       StackTraceInfo rc = null;
2260       Matcher matcher = FULL_EXCEPTION_TEXT_PATTERN.matcher(buffer);
2270       if (matcher.matches())
228        {
2290          final int savePos = buffer.position();
2300          matcher = EXCEPTION_TEXT_PATTERN.matcher(buffer);
2310          if (! matcher.lookingAt())
232           {
2330             throw new ParseException(
234                    "Cannot parse an exception text correctly: " + buffer,
235                    buffer.position());
236           }
2370          final int pos = matcher.end();
2380          buffer.position(buffer.position() + pos);
2390          final CharBuffer exceptionText = buffer.asReadOnlyBuffer();
2400          buffer.position(savePos);
2410          rc = new StackTraceInfo(
242                 buffer.asReadOnlyBuffer(), exceptionText, false);
243        }
2440       return rc;
245     }
246  
247     private static StackTraceInfo parseMore (final CharBuffer buffer)
248           throws ParseException
249     {
2500       StackTraceInfo rc = null;
2510       Matcher matcher = FULL_MORE_PATTERN.matcher(buffer);
2520       if (matcher.matches())
253        {
2540          final int savePos = buffer.position();
2550          matcher = MORE_PATTERN.matcher(buffer);
2560          if (! matcher.lookingAt())
257           {
2580             throw new ParseException("Cannot parse a more-line correctly: "
259                    + buffer, buffer.position());
260           }
2610          final int pos = matcher.end();
2620          buffer.position(buffer.position() + pos);
2630          boolean digit = false;
2640          int i = 0;
2650          while (Character.isDigit(buffer.charAt(i)))
266           {
2670             ++i;
2680             digit = true;
269           }
2700          if (! digit)
271           {
2720             throw new ParseException("Number of more lines is missing: "
273                    + buffer, buffer.position());
274           }
2750          final int moreLines = Integer.parseInt(
276                 buffer.subSequence(0, i).toString());
2770          buffer.position(savePos);
2780          rc = new StackTraceInfo(buffer.asReadOnlyBuffer(), moreLines);
279        }
2800       return rc;
281     }
282  }

Findings in this File

c (1) 52 : 0 Type Javadoc comment is missing an @author tag.
c (2) 105 : 19 Inner assignments should be avoided.
c (3) 109 : 24 Inner assignments should be avoided.
c (4) 113 : 24 Inner assignments should be avoided.
c (5) 117 : 24 Inner assignments should be avoided.
c (6) 121 : 24 Inner assignments should be avoided.