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.RuleContext;
8 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
9 import net.sourceforge.pmd.ast.ASTCompilationUnit;
10 import net.sourceforge.pmd.ast.ASTFieldDeclaration;
11 import net.sourceforge.pmd.ast.SimpleNode;
12
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17
18
19 public class TooManyFields extends AbstractRule {
20
21 private static final int DEFAULT_MAXFIELDS = 15;
22
23 private Map stats;
24 private Map nodes;
25 private int maxFields;
26
27 public Object visit(ASTCompilationUnit node, Object data) {
28 maxFields = hasProperty("maxfields") ? getIntProperty("maxfields") : DEFAULT_MAXFIELDS;
29
30 stats = new HashMap(5);
31 nodes = new HashMap(5);
32
33 List l = node.findChildrenOfType(ASTFieldDeclaration.class);
34
35 if (l!=null && !l.isEmpty()) {
36 for (Iterator it = l.iterator() ; it.hasNext() ; ) {
37 ASTFieldDeclaration fd = (ASTFieldDeclaration) it.next();
38 ASTClassOrInterfaceDeclaration p = (ASTClassOrInterfaceDeclaration)fd.jjtGetParent().jjtGetParent().jjtGetParent();
39 if (!p.isInterface()) {
40 processField(fd);
41 }
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
50
51
52
53 addViolation((RuleContext) data, n);
54
55 }
56 }
57 return data;
58 }
59
60 private void processField(ASTFieldDeclaration fd) {
61 ASTClassOrInterfaceDeclaration clazz = (ASTClassOrInterfaceDeclaration) fd.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
62 String key = clazz.getImage();
63 if (!stats.containsKey(key)) {
64 stats.put(key, new Integer(0));
65 nodes.put(key, clazz);
66 }
67 Integer i = new Integer(((Integer) stats.get(key)).intValue()+1);
68 stats.put(key,i);
69 }
70
71 }