1 package net.sourceforge.pmd.rules;
2
3 import net.sourceforge.pmd.AbstractRule;
4 import net.sourceforge.pmd.RuleContext;
5 import net.sourceforge.pmd.ast.ASTArgumentList;
6 import net.sourceforge.pmd.ast.ASTCompilationUnit;
7 import net.sourceforge.pmd.ast.ASTLiteral;
8 import net.sourceforge.pmd.ast.Node;
9 import net.sourceforge.pmd.ast.SimpleNode;
10
11 import java.text.MessageFormat;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17
18 public class AvoidDuplicateLiteralsRule extends AbstractRule {
19
20 private Map literals = new HashMap();
21
22 public Object visit(ASTCompilationUnit node, Object data) {
23 literals.clear();
24 super.visit(node, data);
25 int threshold = getIntProperty("threshold");
26 for (Iterator i = literals.keySet().iterator(); i.hasNext();) {
27 String key = (String) i.next();
28 List occurrences = (List) literals.get(key);
29 if (occurrences.size() >= threshold) {
30 Object[] args = new Object[]{new Integer(occurrences.size()), new Integer(((SimpleNode) occurrences.get(0)).getBeginLine())};
31 String msg = MessageFormat.format(getMessage(), args);
32 RuleContext ctx = (RuleContext) data;
33 ctx.getReport().addRuleViolation(createRuleViolation(ctx, ((SimpleNode) occurrences.get(0)).getBeginLine(), msg));
34 }
35 }
36 return data;
37 }
38
39 public Object visit(ASTLiteral node, Object data) {
40 if (!hasAtLeastSixParents(node)) {
41 return data;
42 }
43
44 if (!(node.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTArgumentList)) {
45 return data;
46 }
47
48 // just catching strings for now
49 if (node.getImage() == null || node.getImage().indexOf('\"') == -1) {
50 return data;
51 }
52
53 if (literals.containsKey(node.getImage())) {
54 List occurrences = (List) literals.get(node.getImage());
55 occurrences.add(node);
56 } else {
57 List occurrences = new ArrayList();
58 occurrences.add(node);
59 literals.put(node.getImage(), occurrences);
60 }
61
62 return data;
63 }
64
65 private boolean hasAtLeastSixParents(Node node) {
66 Node currentNode = node;
67 for (int i = 0; i < 6; i++) {
68 if (currentNode instanceof ASTCompilationUnit) {
69 return false;
70 }
71 currentNode = currentNode.jjtGetParent();
72 }
73 return true;
74 }
75 }
76
This page was automatically generated by Maven