View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.rules.design;
5   
6   import net.sourceforge.pmd.AbstractRule;
7   import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
8   import net.sourceforge.pmd.ast.ASTCompilationUnit;
9   import net.sourceforge.pmd.ast.ASTFieldDeclaration;
10  import net.sourceforge.pmd.ast.SimpleNode;
11  
12  import java.util.HashMap;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Map;
16  
17  
18  public class TooManyFields extends AbstractRule {
19  
20      private static final int DEFAULT_MAXFIELDS = 15;
21  
22      private Map stats;
23      private Map nodes;
24      private int maxFields;
25  
26      public Object visit(ASTCompilationUnit node, Object data) {
27          maxFields = hasProperty("maxfields") ? getIntProperty("maxfields") : DEFAULT_MAXFIELDS;
28  
29          stats = new HashMap(5);
30          nodes = new HashMap(5);
31  
32          List l = node.findChildrenOfType(ASTFieldDeclaration.class);
33  
34          for (Iterator it = l.iterator(); it.hasNext();) {
35              ASTFieldDeclaration fd = (ASTFieldDeclaration) it.next();
36              if (fd.isFinal() && fd.isStatic()) {
37                  continue;
38              }
39              ASTClassOrInterfaceDeclaration clazz = (ASTClassOrInterfaceDeclaration) fd.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
40              if (clazz != null && !clazz.isInterface()) {
41                  bumpCounterFor(clazz);
42              }
43          }
44          for (Iterator it = stats.keySet().iterator(); it.hasNext();) {
45              String k = (String) it.next();
46              int val = ((Integer) stats.get(k)).intValue();
47              SimpleNode n = (SimpleNode) nodes.get(k);
48              if (val > maxFields) {
49                  addViolation(data, n);
50              }
51          }
52          return data;
53      }
54  
55      private void bumpCounterFor(ASTClassOrInterfaceDeclaration clazz) {
56          String key = clazz.getImage();
57          if (!stats.containsKey(key)) {
58              stats.put(key, new Integer(0));
59              nodes.put(key, clazz);
60          }
61          Integer i = new Integer(((Integer) stats.get(key)).intValue() + 1);
62          stats.put(key, i);
63      }
64  
65  }