Project Report: fawkez

Packagesummary org.jcoderz.phoenix.report

org.jcoderz.phoenix.report.JDepend

LineHitsNoteSource
1  /*
2   * $Id: JDepend.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.phoenix.report;
34  
35  import java.io.File;
36  import java.io.FileNotFoundException;
37  import java.io.FileOutputStream;
38  import java.io.PrintWriter;
39  import java.util.ArrayList;
40  import java.util.Iterator;
41  import java.util.List;
42  
43  import org.apache.bcel.classfile.Constant;
44  import org.apache.bcel.classfile.ConstantClass;
45  import org.apache.bcel.classfile.ConstantPool;
46  import org.apache.bcel.classfile.JavaClass;
47  import org.apache.bcel.util.ClassLoader;
48  import org.apache.bcel.util.ClassLoaderRepository;
49  
50  /**
51   * @author Michael Griffel
52   */
53  public final class JDepend
54  {
550(1)   private static final ClassLoaderRepository REPOSITORY
56           = new ClassLoaderRepository(new ClassLoader());
57  
580    private static final char[] PROPELLER_CHARS
59           = new char[]{'\\', '|', '/', '-'};
60     
610    private final List mClassDependencies = new ArrayList();
620    private final List mAllClasses = new ArrayList();
630    private final List mPackageDependency = new ArrayList();
64  
650    private String mOutputFilename = "out.dot";
660    private File mClassDir = new File("build/classes");
670    private String mIncludePattern = ".*";
680    private String mExcludePattern = "";
69  
700    private int mPropellerIndex = 0;
71     
72     private JDepend ()
730    {
740    }
75  
76 (2)   public static void main (String[] args)
77           throws ClassNotFoundException, FileNotFoundException
78     {
790       final JDepend main = new JDepend();
800       main.parseArgs(args);
810       main.findClasses();
820       main.writeDotFile();
830    }
84  
85     private void parseArgs (String[] args)
86     {
870       for (int i = 0; i < args.length; i++)
88        {
890(3)         if (args[i].equals("-out"))
90           {
910             mOutputFilename = args[i + 1];
92           }
930(4)         else if (args[i].equals("-classes"))
94           {
950             mClassDir = new File(args[i + 1]);
960             if (! mClassDir.isDirectory())
97              {
980                throw new IllegalArgumentException("The argument '" + mClassDir
99                       + "' for parameter classdir is not a valid directory");
100              }
101           }
1020(5)         else if (args[i].equals("-include"))
103           {
1040             mIncludePattern = args[i + 1];
105           }
1060(6)         else if (args[i].equals("-exclude"))
107           {
1080             mExcludePattern = args[i + 1];
109           }
1100          else if (args[i].startsWith("-h")
111                    || args[i].startsWith("--h")
112                    || args[i].indexOf('?') != -1)
113           {
1140             help();
115           }
116           else
117           {
1180             throw new IllegalArgumentException(
119                      "Unknown parameter '" + args[i] + "'");
120           }
1210          ++i;
122        }
1230    }
124  
125     private static void help ()
126     {
1270       System.err.println(" _ ____ _");
1280       System.err.println(" | | _ \\ ___ _ __ ___ _ __ __| |");
1290       System.err.println(" _ | | | | |/ _ \\ \'_ \\ / _ \\ \'_ \\ / _` |");
1300       System.err.println("| |_| | |_| | __/ |_) | __/ | | | (_| |");
1310       System.err.println(" \\___/|____/ \\___| .__/ \\___|_| |_|\\__,_|");
1320       System.err.println(" |_|");
1330       System.err.println(" )=- The Java Dependency Checker -=(");
1340       System.err.println();
1350       System.err.println("Usage:");
1360       System.err.println(
137                " -classes DIR ... path to class directory [build/classes]");
1380       System.err.println(
139                " -out FILE ... path to the output file [out.dot]");
1400       System.err.println(
141                " -include PATTERN ... regex for include packages [.*]");
1420       System.err.println(
143                " -exclude PATTERN ... regex for exclude packages []");
1440       System.err.println("");
1450(7)      System.exit(-1);
1460    }
147  
148 (8)   public void writeDotFile ()
149           throws FileNotFoundException
150     {
1510       final PrintWriter out
152            = new PrintWriter(new FileOutputStream(mOutputFilename));
1530       out.println("digraph G {\n"
154              + " center=\"\"\n"
155              + " node[width=.25,hight=.375,fontsize=10,shape=box]");
1560       for (final Iterator iterator = mPackageDependency.iterator();
1570           iterator.hasNext();)
158        {
1590          final PackageDependency d = (PackageDependency) iterator.next();
1600          out.println(" " + d.toDotString()
161               + " [fontname=\"verdana\", fontcolor=\"black\", fontsize=10.0];");
1620       }
1630       out.println("}");
1640       out.close();
1650    }
166  
167     private void visit (String clazz)
168           throws ClassNotFoundException
169     {
1700       final JavaClass javaClass = REPOSITORY.loadClass(clazz);
1710       final ConstantPool constantPool = javaClass.getConstantPool();
1720(9)      mAllClasses.add(clazz);
1730       propeller();
1740       final Constant[] constant = constantPool.getConstantPool();
1750       for (int i = 0; i < constant.length; i++)
176        {
1770          final Constant c = constant[i];
1780          if (c instanceof ConstantClass)
179           {
1800              final ConstantClass constantClass = (ConstantClass) c;
181             
1820             String newClazz 
183                 = (String) constantClass.getConstantValue(constantPool);
1840             newClazz = newClazz.replace('/', '.');
185              
1860(10)            if (mAllClasses.contains(newClazz))
187              {
1880                continue;
189              }
190              
191     
1920             if (!newClazz.matches(mIncludePattern)
193 (11)                || newClazz.startsWith("[")
194                  || newClazz.matches(mExcludePattern))
195              {
196                 //System.out.println("Skipping '" + newClazz + "'");
1970                continue;
198              }
199              
2000             final JDepend.ClassDependency x
201                    = new JDepend.ClassDependency(clazz, newClazz);
2020             final JDepend.PackageDependency p
203                    = new JDepend.PackageDependency(clazz, newClazz);
2040(12)            if (! mPackageDependency.contains(p))
205              {
2060(13)               mPackageDependency.add(p);
207              }
208              
2090(14)            if (! mClassDependencies.contains(x))
210              {
2110(15)               mClassDependencies.add(x);
212                 //System.out.println("visit: " + newClazz);
2130                visit(newClazz);
214              }
215           }
216        }
217  
2180    }
219  
220     /**
221      * 
222      */
223     private void propeller ()
224     {
2250(16)      System.out.print("\b");
2260       System.out.print(
227                PROPELLER_CHARS[mPropellerIndex++ % PROPELLER_CHARS.length]);
2280    }
229  
230 (17)   public void findClasses ()
231     {
2320       System.out.print("Scanning classpath ... ");
2330       findClasses(mClassDir, null);
2340       System.out.println();
2350       System.out.println("Scanned " + mAllClasses.size() + " classes.");
2360    }
237  
238     private void findClasses (File dir, String pkg)
239     {
2400       final File[] files = dir.listFiles();
2410       for (int i = 0; i < files.length; i++)
242        {
2430          if (files[i].isDirectory())
244           {
245              final String newpkg;
2460             if (pkg == null)
247              {
2480                newpkg = files[i].getName();
249              }
250              else
251              {
2520                newpkg = pkg + "." + files[i].getName();
253              }
2540             findClasses(files[i], newpkg);
2550          }
2560          else if (files[i].getName().endsWith(".class")
257                    && files[i].getName().indexOf('$') == -1)
258           {
2590             final String filename = files[i].getName();
2600             final String clazz = pkg + "."
261                    + filename.substring(0,
262                            filename.length() - ".class".length());
263              try
264              {
2650                visit(clazz);
266              }
2670             catch (ClassNotFoundException ignore)
268              {
269                 // classes that are not on the classpath are ignored.
2700             }
271           }
272        }
2730    }
274     
275     
276 (18)   public static final class ClassDependency
277     {
278        private final String mClazz;
279        private final String mDependsClazz;
280  
281        ClassDependency (String c, String dc)
2820       {
2830          mClazz = c;
2840          mDependsClazz = dc;
2850       }
286        
287 (19)      public String toString ()
288        {
2890(20)         return mClazz + " -> " + mDependsClazz;
290        }
291  
292 (21)      public String toDotString ()
293        {
2940          return "\"" + mClazz + "\"" + " -> " + "\"" + mDependsClazz + "\"";
295        }
296  
297        /** {@inheritDoc} */
298        public boolean equals (Object obj)
299        {
3000          if (! (obj instanceof JDepend.ClassDependency))
301           {
3020             return false;
303           }
3040          final JDepend.ClassDependency o = (JDepend.ClassDependency) obj;
305           
3060          return o.mClazz.equals(mClazz)
307                   && o.mDependsClazz.equals(mDependsClazz);
308        }
309        
310        /** {@inheritDoc} */
311        public int hashCode ()
312        {
3130          return mClazz.hashCode() + mDependsClazz.hashCode();
314        }
315     }
316  
317 (22)   public static final class PackageDependency
318     {
319        private final String mPackage;
320        private final String mDependsPackage;
321  
322        PackageDependency (String c, String dc)
3230       {
3240          mPackage = c.substring(0, c.lastIndexOf('.'));
3250          mDependsPackage = dc.substring(0, dc.lastIndexOf('.'));
3260       }
327        
328 (23)      public String toString ()
329        {
3300          return mPackage + " -> " + mDependsPackage;
331        }
332  
333 (24)      public String toDotString ()
334        {
3350          return "\"" + mPackage + "\"" + " -> " + "\""
336                   + mDependsPackage + "\"";
337        }
338  
339        /** {@inheritDoc} */
340        public boolean equals (Object obj)
341        {
3420          if (! (obj instanceof JDepend.PackageDependency))
343           {
3440             return false;
345           }
3460          final JDepend.PackageDependency o = (JDepend.PackageDependency) obj;
347           
3480          return o.mPackage.equals(mPackage)
349               && o.mDependsPackage.equals(mDependsPackage);
350        }
351        
352        /** {@inheritDoc} */
353        public int hashCode ()
354        {
3550          return mPackage.hashCode() + mDependsPackage.hashCode();
356        }
357     }
358  }

Findings in this File

f (25) System.out.print is used main class
f (26) System.out.print is used main class
f (27) System.out.print is used main class
f (28) System.out.print is used main class
f (29) System.out.print is used main class
f (30) System.out.print is used main class
f (31) System.out.print is used main class
f (32) System.out.print is used main class
f (33) System.out.print is used main class
f (34) System.out.print is used main class
f (35) System.out.print is used main class
f (36) System.out.print is used main class
f (37) System.out.print is used main class
f (38) System.out.print is used main class
f (39) System.out.print is used main class
f (40) System.out.print is used main class
f (41) System.out.print is used main class
f (42) System.out.print is used main class
f (43) System.out.print is used main class
w (1) 55 : 0 org.jcoderz.phoenix.report.JDepend.<static initializer>() creates a org.apache.bcel.util.ClassLoader classloader, which should be performed within a doPrivileged block
c (2) 76 : 4 Missing a Javadoc comment.
i (3) 89 : 0 method org.jcoderz.phoenix.report.JDepend.parseArgs(String[]) makes literal string comparisons passing the literal as an argument
i (4) 93 : 0 method org.jcoderz.phoenix.report.JDepend.parseArgs(String[]) makes literal string comparisons passing the literal as an argument
i (5) 102 : 0 method org.jcoderz.phoenix.report.JDepend.parseArgs(String[]) makes literal string comparisons passing the literal as an argument
i (6) 106 : 0 method org.jcoderz.phoenix.report.JDepend.parseArgs(String[]) makes literal string comparisons passing the literal as an argument
i (7) 145 : 0 org.jcoderz.phoenix.report.JDepend.help() invokes System.exit(...), which shuts down the entire virtual machine
c (8) 148 : 4 Missing a Javadoc comment.
d (9) 172 : 22 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
w (10) 186 : 0 class org.jcoderz.phoenix.report.JDepend defines List based fields but uses them like Sets
c (11) 193 : 20 This call to String.startsWith can be rewritten using String.charAt(0)
w (12) 204 : 0 class org.jcoderz.phoenix.report.JDepend defines List based fields but uses them like Sets
d (13) 206 : 38 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
w (14) 209 : 0 class org.jcoderz.phoenix.report.JDepend defines List based fields but uses them like Sets
d (15) 211 : 38 [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
w (16) 225 : 0 Method org.jcoderz.phoenix.report.JDepend.propeller() passes constant String of length 1 to character overridden method
c (17) 230 : 4 Missing a Javadoc comment.
c (18) 276 : 0 Missing a Javadoc comment.
c (19) 287 : 7 Missing a Javadoc comment.
i (20) 289 : 26 The String literal " -> " appears 4 times in this file; the first occurrence is on line 289
c (21) 292 : 7 Missing a Javadoc comment.
c (22) 317 : 0 Missing a Javadoc comment.
c (23) 328 : 7 Missing a Javadoc comment.
c (24) 333 : 7 Missing a Javadoc comment.