1
2
3
4 package net.sourceforge.pmd.lang.plsql.rule.codesize;
5
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import net.sourceforge.pmd.lang.ast.Node;
11 import net.sourceforge.pmd.lang.plsql.ast.ASTInput;
12 import net.sourceforge.pmd.lang.plsql.ast.ASTPackageSpecification;
13 import net.sourceforge.pmd.lang.plsql.ast.ASTTypeSpecification;
14 import net.sourceforge.pmd.lang.plsql.ast.ASTVariableOrConstantDeclaration;
15 import net.sourceforge.pmd.lang.plsql.ast.PLSQLNode;
16 import net.sourceforge.pmd.lang.plsql.rule.AbstractPLSQLRule;
17 import net.sourceforge.pmd.lang.rule.properties.IntegerProperty;
18 import net.sourceforge.pmd.util.NumericConstants;
19
20 public class TooManyFieldsRule extends AbstractPLSQLRule {
21
22 private static final int DEFAULT_MAXFIELDS = 15;
23
24 private Map<String, Integer> stats;
25 private Map<String, PLSQLNode> nodes;
26
27 private static final IntegerProperty MAX_FIELDS_DESCRIPTOR = new IntegerProperty("maxfields",
28 "Max allowable fields", 1, 300, DEFAULT_MAXFIELDS, 1.0f);
29
30 public TooManyFieldsRule() {
31 definePropertyDescriptor(MAX_FIELDS_DESCRIPTOR);
32 }
33
34 @Override
35 public Object visit(ASTInput node, Object data) {
36
37 stats = new HashMap<String, Integer>(5);
38 nodes = new HashMap<String, PLSQLNode>(5);
39
40 return super.visit(node, data);
41 }
42
43 @Override
44 public Object visit(ASTPackageSpecification node, Object data) {
45
46 int maxFields = getProperty(MAX_FIELDS_DESCRIPTOR);
47
48 List<ASTVariableOrConstantDeclaration> l = node.findDescendantsOfType(ASTVariableOrConstantDeclaration.class);
49
50 for (ASTVariableOrConstantDeclaration fd : l) {
51 bumpCounterFor(fd);
52 }
53 for (String k : stats.keySet()) {
54 int val = stats.get(k);
55 Node n = nodes.get(k);
56 if (val > maxFields) {
57 addViolation(data, n);
58 }
59 }
60 return data;
61 }
62
63 @Override
64 public Object visit(ASTTypeSpecification node, Object data) {
65
66 int maxFields = getProperty(MAX_FIELDS_DESCRIPTOR);
67
68 List<ASTVariableOrConstantDeclaration> l = node.findDescendantsOfType(ASTVariableOrConstantDeclaration.class);
69
70 for (ASTVariableOrConstantDeclaration fd : l) {
71 bumpCounterFor(fd);
72 }
73 for (String k : stats.keySet()) {
74 int val = stats.get(k);
75 Node n = nodes.get(k);
76 if (val > maxFields) {
77 addViolation(data, n);
78 }
79 }
80 return data;
81 }
82
83 private void bumpCounterFor(PLSQLNode clazz) {
84 String key = clazz.getImage();
85 if (!stats.containsKey(key)) {
86 stats.put(key, NumericConstants.ZERO);
87 nodes.put(key, clazz);
88 }
89 Integer i = Integer.valueOf(stats.get(key) + 1);
90 stats.put(key, i);
91 }
92 }