Project Report: fawkez

Packagesummary org.jcoderz.commons.tracing

org.jcoderz.commons.tracing.TracingInjector

LineHitsNoteSource
1  /*
2   * $Id: ArraysUtil.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.tracing;
34  
35  
36  import java.io.File;
37  import java.io.FileInputStream;
38  import java.io.FileOutputStream;
39  import java.io.FileReader;
40  import java.io.IOException;
41  import java.io.LineNumberReader;
42  import java.util.ArrayList;
43  import java.util.Iterator;
44  import java.util.List;
45  import java.util.logging.Level;
46  import java.util.logging.Logger;
47  
48  import org.jcoderz.commons.util.FileUtils;
49  import org.jcoderz.commons.util.IoUtil;
50  import org.jcoderz.commons.util.StringUtil;
51  import org.objectweb.asm.ClassReader;
52  import org.objectweb.asm.ClassWriter;
53  import org.objectweb.asm.Type;
54  import org.objectweb.asm.tree.ClassNode;
55  import org.objectweb.asm.tree.MethodNode;
56  
57  /**
58   *
59 (1) * TODO: Create unit tests!
60 (2) * TODO: Might add 'this' to <init> exiting logger
61 (3) * TODO: Store {@link System#currentTimeMillis()} / nanos
62   *  to compute time!
63 (4) * TODO: Create a method compressing the localVariableTable
64   *       + create localVariableTable if none is given! (seen with
65   *       aspectj generated classes)
66 (5) * TODO: Instead of boolean indicating if loggable store
67   *       reference to logger or null in method variable
68   *
69   * @author mandelan
70   */
710(6)public class TracingInjector
72  {
730   static final Type THROWABLE_TYPE = Type.getType(Throwable.class);
74    static final String PREFIX = "LGI$";
75    static final String LOCAL_PREFIX = "lgi$";
76    static final String STATIC_LOGGER_FIELD_NAME
77      = PREFIX + "LGR";
78    static final String IS_LOGGABLE_FIELD_NAME
79      = LOCAL_PREFIX + "isLoggable";
80    static final String RESULT_VAR_FIELD_NAME
81      = LOCAL_PREFIX + "result";
82  
830   private static final String CLASSNAME = TracingInjector.class.getName();
840   private static final Logger logger = Logger.getLogger(CLASSNAME);
85  
86    /**
87     *
88     * @author Andreas Mandel
89     */
90    public interface Matcher
91    {
92      /**
93       *
94       * @param cn
95    * @return
96       */
97 (7)(8)(9)(10)    public boolean matches (ClassNode cn);
98  
99      /**
100       *
101       * @param mn
102    * @return
103       */
104 (11)(12)(13)(14)    public boolean matches (MethodNode mn);
105  
106      /**
107       *
108       * @param cn
109    * @param mn
110    * @return
111       */
112 (15)(16)(17)(18)(19)    public boolean matches (ClassNode cn, MethodNode mn);
113    }
114  
115    /**
116     *
117     * @author Andreas Mandel
118     */
1190   public static class MethodMatcher implements Matcher
120    {
121 (20)(21)    public final static String COMMENT = "#";
122 (22)(23)    public final static String COMMENT2 = "//";
1230(24)    final List mPatterString = new ArrayList();
1240(25)    final List mPatterns = new ArrayList();
125  
126      /**
127       * Method matcher that is configured by the given File.
128       * 
129       * @param inFile
130    * @throws IOException
131    */
132 (26)    public MethodMatcher (File inFile)
133 (27)      throws IOException
1340     {
1350       LineNumberReader reader = null;
1360       final FileReader fr = new FileReader(inFile);
137        try
138        {
1390         reader = new LineNumberReader(fr);
1400         String line = reader.readLine();
1410         while (line != null)
142          {
1430           if (!StringUtil.isEmptyOrNull(line) && !line.startsWith(COMMENT)
144                && !line.startsWith(COMMENT2))
145            {
1460             mPatterString.add(line.trim());
1470             final AspectPattern aspectPattern = new AspectPattern(line.trim());
1480             mPatterns.add(aspectPattern);
149            }
1500           line = reader.readLine();
151          }
152        }
153        finally
154        {
1550         IoUtil.close(reader);
1560         IoUtil.close(fr);
1570       }
1580     }
159  
160      /** {@inheritDoc} */
161      public String toString ()
162      {
1630       return mPatterns.toString();
164      }
165  
166      /**
167       * @param cn
168    * @return
169       */
170 (28)(29)(30)(31)    public boolean matches(ClassNode cn)
171      {
1720       final Iterator i = mPatterns.iterator();
1730       boolean matched = false;
1740       while (i.hasNext() && !matched)
175        {
1760         final AspectPattern pattern = (AspectPattern) i.next();
1770         matched |= pattern.matchClass(cn.name);
178 (32)        // TODO: Check inheritance!!!
179          // return matcher!!!
1800       }
1810       return matched;
182      }
183  
184      /**
185       * @param mn
186    * @return
187       */
188 (33)(34)(35)(36)    public boolean matches(MethodNode mn)
189      {
1900(37)      throw new UnsupportedOperationException("TODO");
191      }
192  
193      /**
194       * @param cn
195    * @param mn
196    * @return
197       */
198 (38)(39)(40)(41)(42)    public boolean matches(ClassNode cn, MethodNode mn)
199      {
2000       final Iterator i = mPatterns.iterator();
2010       boolean matched = false;
2020       while (i.hasNext() && !matched)
203        {
2040         final AspectPattern pattern = (AspectPattern) i.next();
2050         if (pattern.matchClass(cn.name))
206 (43)          // TODO: Check inheritance!!!
207          {
2080           matched |=
209              pattern.matchAccess(mn.access)
210              && pattern.matchMethod(mn.desc);
211          }
2120       }
2130       return matched;
214      }
215    }
216  
217    /**
218     *
219     * @param inFile
220    * @param outFile
221    * @param matcher
222    * @param java5
223    * @param pai
224    * @throws IOException
225    */
226 (44)(45)(46)  public static void inject (File inFile, File outFile, Matcher matcher,
227 (47)(48)      boolean java5, boolean pai)
228 (49)    throws IOException
229    {
2300     final ClassNode cn = new ClassNode();
2310     final FileInputStream is = new FileInputStream(inFile);
232      try
233      {
2340       final ClassReader cr = new ClassReader(is);
2350       cr.accept(cn, 0);
236      }
237      finally
238      {
2390       IoUtil.close(is);
2400     }
2410     if (matcher.matches(cn))
242      {
2430       if (logger.isLoggable(Level.FINE))
244        {
2450         logger.fine("Will inject tracing into: " + cn.name);
246        }
2470       new ClassTracingInjector(cn, java5, pai).inject(matcher);
2480       final FileOutputStream os = new FileOutputStream(outFile);
249        try
250        {
2510         final ClassWriter cw = new ClassWriter(
252              /* ClassWriter.COMPUTE_FRAMES +*/ ClassWriter.COMPUTE_MAXS);
2530         cn.accept(cw);
2540         os.write(cw.toByteArray());
255        }
256        finally
257        {
2580         IoUtil.close(os);
2590       }
2600     }
261      else
262      {
2630       if (logger.isLoggable(Level.FINE))
264        {
2650         logger.fine("Direct copy for: " + cn.name + " (no match)");
266        }
2670       FileUtils.copy(inFile, outFile);
268      }
2690   }
270  }

Findings in this File

i (1) 59 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (2) 60 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (3) 61 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (4) 63 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (5) 66 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
c (6) 71 : 1 Utility classes should not have a public or default constructor.
c (7) 97 : 0 Expected an @return tag.
c (8) 97 : 39 Expected @param tag for 'cn'.
c (9) 97 : 12 Avoid modifiers which are implied by the context
d (10) 97 : 0 @return tag has no arguments.
c (11) 104 : 0 Expected an @return tag.
c (12) 104 : 40 Expected @param tag for 'mn'.
c (13) 104 : 12 Avoid modifiers which are implied by the context
d (14) 104 : 0 @return tag has no arguments.
c (15) 112 : 0 Expected an @return tag.
c (16) 112 : 39 Expected @param tag for 'cn'.
c (17) 112 : 54 Expected @param tag for 'mn'.
c (18) 112 : 12 Avoid modifiers which are implied by the context
d (19) 112 : 0 @return tag has no arguments.
c (20) 121 : 5 Missing a Javadoc comment.
c (21) 121 : 18 'static' modifier out of order with the JLS suggestions.
c (22) 122 : 5 Missing a Javadoc comment.
c (23) 122 : 18 'static' modifier out of order with the JLS suggestions.
c (24) 123 : 16 Variable 'mPatterString' must be private and have accessor methods.
c (25) 124 : 16 Variable 'mPatterns' must be private and have accessor methods.
c (26) 132 : 32 Expected @param tag for 'inFile'.
c (27) 133 : 14 Expected @throws tag for 'IOException'.
c (28) 170 : 0 Expected an @return tag.
c (29) 170 : 27 '(' is not preceded with whitespace.
c (30) 170 : 38 Expected @param tag for 'cn'.
d (31) 170 : 0 @return tag has no arguments.
i (32) 178 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
c (33) 188 : 0 Expected an @return tag.
c (34) 188 : 27 '(' is not preceded with whitespace.
c (35) 188 : 39 Expected @param tag for 'mn'.
d (36) 188 : 0 @return tag has no arguments.
i (37) 190 : 0 method org.jcoderz.commons.tracing.TracingInjector$MethodMatcher.matches(MethodNode) throws exception with static message string
c (38) 198 : 0 Expected an @return tag.
c (39) 198 : 27 '(' is not preceded with whitespace.
c (40) 198 : 38 Expected @param tag for 'cn'.
c (41) 198 : 53 Expected @param tag for 'mn'.
d (42) 198 : 0 @return tag has no arguments.
i (43) 206 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
c (44) 226 : 35 Expected @param tag for 'inFile'.
c (45) 226 : 48 Expected @param tag for 'outFile'.
c (46) 226 : 65 Expected @param tag for 'matcher'.
c (47) 227 : 15 Expected @param tag for 'java5'.
c (48) 227 : 30 Expected @param tag for 'pai'.
c (49) 228 : 12 Expected @throws tag for 'IOException'.