Project Report: fawkez

Packagesummary org.jcoderz.commons.tracing

org.jcoderz.commons.tracing.TracingInjectorTask

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  import java.io.File;
36  import java.io.IOException;
37  import java.util.ArrayList;
38  import java.util.Iterator;
39  import java.util.LinkedList;
40  import java.util.List;
41  import java.util.logging.Handler;
42  import java.util.logging.Level;
43  import java.util.logging.Logger;
44  
45  import org.apache.tools.ant.BuildException;
46  import org.apache.tools.ant.DirectoryScanner;
47  import org.apache.tools.ant.Project;
48  import org.apache.tools.ant.Task;
49  import org.apache.tools.ant.types.FileSet;
50  import org.jcoderz.commons.tracing.TracingInjector.Matcher;
51  import org.jcoderz.commons.tracing.TracingInjector.MethodMatcher;
52  import org.jcoderz.commons.util.IoUtil;
53  
54  /**
55   * Ant task for TracingInjection.
56   *
57   * <p>This ant task takes a fileset <code>fileset</code> as input and
58   * one directory <code>destDir</code> as output. It copies ALL files
59   * from the input to the output, if the do not exist at the destination
60   * OR if the file last modified date of the source is newer than the
61   * target. Needed directories are created as used.</p>
62   *
63   * <p>As a 'side effect' all class files (*.class) that match
64   * one of the patterns given in the <code>patternFile</code> get
65   * JDK14 tracing logging (entering/exiting/throwing) injected in
66   * all methods that match the given pattern.</p>
67   *
68   * <p>If you set <code>java5</code> to <code>true</code> the
69   * generated code uses the much more efficient factory methods
70   * to box native types that had been introduced with java5
71   * (<code>new Integer(int i)</code> vs.
72   * <code>Integer.valueOf(int i)</code>). Nevertheless this only affects
73   * the code that is guarded with an <code>isLoggable(..)</code> so there no
74   * runtime penalty in the generated code if logging is disabled.</p>
75   *
76   * <p>The <code>patternFile</code> is read line by line and each line
77   * is expected to be either empty, start with a '#' or '//' or hold a
78   * valid aspectJ like pattern as defined in the
79 (1) * AspectPattern according to <a href="http://aspectwerkz.codehaus.org/definition_issues.html">
80   *    aspectwerkz</a>. Call the target with '-v' to see
81   * the regular expression that is generated out of the input pattern.</p>
82   *
83   * <p>The task supports a <code>verbose</code> attribute. If set to true
84   * a detailed log will be generated about what is going on. This is done
85   * by increasing the JDK logging loglevel - be aware of possible
86   * side effects.</p>
87   *
88   * The following code fragment defines the
89   * <code>tracing-injector</code> ant task.<pre>
90   *   &lt;taskdef name="tracing-injector"
91   *       classname="org.jcoderz.commons.tracing.TracingInjectorTask"
92   *       classpath="lib/tracing-injector-0.1.jar"/>
93   * </pre>
94   *
95   * A valid usage sample is:<pre>
96   *   &lt;tracing-injector destDir="build/classes-log"
97   *       patternFile="config/tracing"
98   *       java5="false" verbose="false">
99   *       &lt;fileset dir="build/classes"/>
100   *     &lt;/tracing-injector>
101   * </pre>
102   *
103 (2) * TODO: Support different Tracers to be set.
104   *
105   * @author Andreas Mandel
106   */
1070 public class TracingInjectorTask extends Task
108  {
109  //  * <pre>
110 (3)//  * TODO: Refine Documentation
111 (4)//  * TODO: Implement validate method
112 (5)//  * TODO: Add dependency checker (AsM lib)
113 (6)//  * TODO: If required allow JAR as input and/or output
114  //  * </pre>
115  //  *
1160   private final List mSrcFiles = new ArrayList();
117    private String mDestDirName;
118    private File mDestDir;
1190   private final List mSourceFiles = new LinkedList();
120    private File mPatternFile;
121    private Matcher mMatcher;
1220   private boolean mJava5 = false;
1230   private boolean mPai = false;
1240   private boolean mVerbose = false;
125  
126    /**
127     *
128     * @param fileset files to be collected.
129     */
130 (7)  public void addFileset(FileSet fileset)
131    {
1320     mSrcFiles.add(fileset);
1330   }
134  
135 (8)(9)  public void setDestDir(String destDir)
136    {
1370     mDestDirName = destDir;
1380   }
139  
140 (10)(11)  public void setPatternFile(File patternFile)
141    {
1420     mPatternFile = patternFile;
1430   }
144  
145 (12)(13)  public void setJava5(boolean java5)
146    {
1470     mJava5 = java5;
1480   }
149  
150 (14)(15)  public void setPai(boolean pai)
151    {
1520     mPai = pai;
1530   }
154  
155 (16)(17)  public void setVerbose(boolean verbose)
156    {
1570     mVerbose = verbose;
1580   }
159  
160    /**
161     *
162     */
163 (18)  public void execute()
164    {
1650     validate();
166  
167      // BUILD MATCHER Object...
168      try
169      {
1700       mMatcher = new MethodMatcher(mPatternFile);
171        // IF loglevel??
1720       log("Read matcher from " + mPatternFile, Project.MSG_VERBOSE);
1730       log(String.valueOf(mMatcher), Project.MSG_VERBOSE);
174      }
1750     catch (IOException ex)
176      {
1770       throw new BuildException("Could not build matcher from file.", ex);
1780     }
179  
1800     for (final Iterator itFSets = mSrcFiles.iterator(); itFSets.hasNext();)
181      {
1820       final FileSet fs = (FileSet) itFSets.next();
1830       final DirectoryScanner ds = fs.getDirectoryScanner(getProject());
1840       final File base = ds.getBasedir();
1850       final String[] includedFiles = ds.getIncludedFiles();
1860       for (int i = 0; i < includedFiles.length; i++)
187        {
1880         mSourceFiles.add(new SourceFile(
189              new File(base, includedFiles[i]), includedFiles[i]));
190        }
1910     }
192      try
193      {
1940       inject();
195      }
1960     catch (IOException ex)
197      {
1980       throw new BuildException(ex);
1990     }
2000   }
201  
202    /**
203     *
204     * @throws IOException
205    */
206 (19)  public void inject()
207 (20)    throws IOException
208    {
2090     while (!mSourceFiles.isEmpty())
210      {
2110       final SourceFile mySource = (SourceFile) mSourceFiles.remove(0);
212  
2130       final File targetFile = getTargetForSource(mySource);
214  
2150       if (!targetFile.exists()
216            || mySource.getAbsoluteFile().lastModified()
217              > targetFile.lastModified())
218        {
2190         ensurePath(targetFile);
2200         if (mySource.getRelativeFileName().endsWith(".class"))
221          {
222            try
223            {
2240             log("About to work on " + mySource.getAbsoluteFile()
225                  + ".", Project.MSG_VERBOSE);
2260             TracingInjector.inject(mySource.getAbsoluteFile(), targetFile,
227                  mMatcher, mJava5, mPai);
228            }
2290           catch (RuntimeException ex)
230            {
2310             log("Failed with " + mySource.mAbsoluteFile + " got "
232                  + ex, Project.MSG_DEBUG);
2330             if (ex.getMessage() != null
234                  && ex.getMessage().startsWith("JSR/RET are not supported "))
235              {
2360               IoUtil.copy(mySource.getAbsoluteFile(), targetFile);
237              }
238              else
239              {
240                // THIS IS ANT 1.7.0 :-(
2410               log("About to only copy " + mySource.getAbsoluteFile()
242                    + " cause " + ex + ".", ex, Project.MSG_ERR);
2430               IoUtil.copy(mySource.getAbsoluteFile(), targetFile);
244              }
2450           }
246          }
247          else
248          {
2490           log("About to copy " + mySource.getAbsoluteFile()
250                + ".", Project.MSG_VERBOSE);
2510           IoUtil.copy(mySource.getAbsoluteFile(), targetFile);
252          }
253        }
2540     }
2550   }
256  
257    /**
258     *
259     * @param file
260    * @throws IOException
261    */
262 (21)  private void ensurePath(File file)
263      throws IOException
264    {
2650     if (!file.exists())
266      {
2670       if (!file.getParentFile().exists())
268        {
2690         if (!file.getParentFile().mkdirs())
270          {
2710(22)          throw new IOException("Could not create dir for target files.");
272          }
273        }
274      }
2750   }
276  
277    /**
278     *
279     * @param mySource
280    * @return
281     */
282 (23)  private File getTargetForSource(SourceFile mySource)
283    {
2840     return new File(mDestDir, mySource.getRelativeFileName());
285    }
286  
287    /**
288     *
289     */
290 (24)  private void validate()
291    {
2920     mDestDir = new File(mDestDirName);
2930     if (mVerbose)
294      {
2950       Logger.getLogger(
296 (25)          TracingInjectorTask.class.getPackage().getName()).setLevel(Level.FINEST);
2970       final Handler[] handlers = Logger.getLogger("").getHandlers();
2980       final int amountOfHandlers = handlers.length;
2990       for (int i = 0; i < amountOfHandlers; i++)
300        {
301           try
302           {
3030             handlers[i].setLevel(Level.FINEST);
304           }
3050(26)         catch (Exception ex)
306           {
307              //ignore
3080          }
309        }
310      }
3110   }
312  
313    /**
314     *
315     * @author Andreas Mandel
316     */
3170   private static class SourceFile
318    {
319      private final File mAbsoluteFile;
320      private final String mRelativeFileName;
321  
322      /**
323       *
324       * @param absoluteFile
325    * @param relativeFileName
326    */
327 (27)    public SourceFile(File absoluteFile, String relativeFileName)
3280     {
3290       mAbsoluteFile = absoluteFile;
3300       mRelativeFileName = relativeFileName;
3310     }
332  
333 (28)    public File getAbsoluteFile()
334      {
3350       return mAbsoluteFile;
336      }
337  
338 (29)    public String getRelativeFileName()
339      {
3400       return mRelativeFileName;
341      }
342    }
343  }

Findings in this File

c (1) 79 : 0 Line is longer than 80 characters.
i (2) 103 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (3) 110 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (4) 111 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (5) 112 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (6) 113 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
c (7) 130 : 25 '(' is not preceded with whitespace.
c (8) 135 : 3 Missing a Javadoc comment.
c (9) 135 : 25 '(' is not preceded with whitespace.
c (10) 140 : 3 Missing a Javadoc comment.
c (11) 140 : 29 '(' is not preceded with whitespace.
c (12) 145 : 3 Missing a Javadoc comment.
c (13) 145 : 23 '(' is not preceded with whitespace.
c (14) 150 : 3 Missing a Javadoc comment.
c (15) 150 : 21 '(' is not preceded with whitespace.
c (16) 155 : 3 Missing a Javadoc comment.
c (17) 155 : 25 '(' is not preceded with whitespace.
c (18) 163 : 22 '(' is not preceded with whitespace.
c (19) 206 : 21 '(' is not preceded with whitespace.
c (20) 207 : 12 Expected @throws tag for 'IOException'.
c (21) 262 : 26 '(' is not preceded with whitespace.
i (22) 271 : 0 method org.jcoderz.commons.tracing.TracingInjectorTask.ensurePath(File) throws exception with static message string
c (23) 282 : 34 '(' is not preceded with whitespace.
c (24) 290 : 24 '(' is not preceded with whitespace.
c (25) 296 : 0 Line is longer than 80 characters.
i (26) 305 : 0 org.jcoderz.commons.tracing.TracingInjectorTask.validate() might ignore java.lang.Exception
c (27) 327 : 22 '(' is not preceded with whitespace.
c (28) 333 : 32 '(' is not preceded with whitespace.
c (29) 338 : 38 '(' is not preceded with whitespace.