01 /**
02 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03 */
04 package net.sourceforge.pmd.lang.java.rule.codesize;
05
06 import java.util.HashMap;
07 import java.util.List;
08 import java.util.Map;
09
10 import net.sourceforge.pmd.lang.ast.Node;
11 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
13 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
14 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15 import net.sourceforge.pmd.lang.rule.properties.IntegerProperty;
16 import net.sourceforge.pmd.util.NumericConstants;
17
18
19 public class TooManyFieldsRule extends AbstractJavaRule {
20
21 private static final int DEFAULT_MAXFIELDS = 15;
22
23 private Map<String, Integer> stats;
24 private Map<String, ASTClassOrInterfaceDeclaration> nodes;
25
26 private static final IntegerProperty MAX_FIELDS_DESCRIPTOR = new IntegerProperty(
27 "maxfields", "Max allowable fields",
28 1, 300, DEFAULT_MAXFIELDS, 1.0f
29 );
30
31 public TooManyFieldsRule() {
32 definePropertyDescriptor(MAX_FIELDS_DESCRIPTOR);
33 }
34
35 @Override
36 public Object visit(ASTCompilationUnit node, Object data) {
37
38 int maxFields = getProperty(MAX_FIELDS_DESCRIPTOR);
39
40 stats = new HashMap<String, Integer>(5);
41 nodes = new HashMap<String, ASTClassOrInterfaceDeclaration>(5);
42
43 List<ASTFieldDeclaration> l = node.findDescendantsOfType(ASTFieldDeclaration.class);
44
45 for (ASTFieldDeclaration fd: l) {
46 if (fd.isFinal() && fd.isStatic()) {
47 continue;
48 }
49 ASTClassOrInterfaceDeclaration clazz = fd.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
50 if (clazz != null && !clazz.isInterface()) {
51 bumpCounterFor(clazz);
52 }
53 }
54 for (String k : stats.keySet()) {
55 int val = stats.get(k);
56 Node n = nodes.get(k);
57 if (val > maxFields) {
58 addViolation(data, n);
59 }
60 }
61 return data;
62 }
63
64 private void bumpCounterFor(ASTClassOrInterfaceDeclaration clazz) {
65 String key = clazz.getImage();
66 if (!stats.containsKey(key)) {
67 stats.put(key, NumericConstants.ZERO);
68 nodes.put(key, clazz);
69 }
70 Integer i = Integer.valueOf(stats.get(key) + 1);
71 stats.put(key, i);
72 }
73 }
|