KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > rules > strings > AvoidDuplicateLiteralsRule


1 /**
2  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3  */

4 package net.sourceforge.pmd.rules.strings;
5
6 import net.sourceforge.pmd.AbstractRule;
7 import net.sourceforge.pmd.ast.ASTCompilationUnit;
8 import net.sourceforge.pmd.ast.ASTLiteral;
9 import net.sourceforge.pmd.ast.SimpleNode;
10
11 import java.io.BufferedReader JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.FileReader JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.LineNumberReader JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Set JavaDoc;
23
24 public class AvoidDuplicateLiteralsRule extends AbstractRule {
25
26     public static class ExceptionParser {
27
28         private static final char ESCAPE_CHAR = '\\';
29         private char delimiter;
30
31         public ExceptionParser(char delimiter) {
32             this.delimiter = delimiter;
33         }
34
35         public Set JavaDoc parse(String JavaDoc in) {
36             Set JavaDoc result = new HashSet JavaDoc();
37             StringBuffer JavaDoc currentToken = new StringBuffer JavaDoc();
38             boolean inEscapeMode = false;
39             for (int i = 0; i < in.length(); i++) {
40                 if (inEscapeMode) {
41                     inEscapeMode = false;
42                     currentToken.append(in.charAt(i));
43                     continue;
44                 }
45                 if (in.charAt(i) == ESCAPE_CHAR) {
46                     inEscapeMode = true;
47                     continue;
48                 }
49                 if (in.charAt(i) == delimiter) {
50                     result.add(currentToken.toString());
51                     currentToken = new StringBuffer JavaDoc();
52                 } else {
53                     currentToken.append(in.charAt(i));
54                 }
55             }
56             if (currentToken.length() > 0) {
57                 result.add(currentToken.toString());
58             }
59             return result;
60         }
61     }
62
63     private static final char DEFAULT_SEPARATOR = ',';
64     private static final String JavaDoc EXCEPTION_LIST_PROPERTY = "exceptionlist";
65     private static final String JavaDoc SEPARATOR_PROPERTY = "separator";
66     private static final String JavaDoc EXCEPTION_FILE_NAME_PROPERTY = "exceptionfile";
67
68     private Map JavaDoc literals = new HashMap JavaDoc();
69     private Set JavaDoc exceptions = new HashSet JavaDoc();
70
71     public Object JavaDoc visit(ASTCompilationUnit node, Object JavaDoc data) {
72         literals.clear();
73
74         if (hasProperty(EXCEPTION_LIST_PROPERTY)) {
75             ExceptionParser p;
76             if (hasProperty(SEPARATOR_PROPERTY)) {
77                 p = new ExceptionParser(getStringProperty(SEPARATOR_PROPERTY).charAt(0));
78             } else {
79                 p = new ExceptionParser(DEFAULT_SEPARATOR);
80             }
81             exceptions = p.parse(getStringProperty(EXCEPTION_LIST_PROPERTY));
82         } else if (hasProperty(EXCEPTION_FILE_NAME_PROPERTY)) {
83             exceptions = new HashSet JavaDoc();
84             LineNumberReader JavaDoc reader = null;
85             try {
86                 reader = new LineNumberReader JavaDoc(new BufferedReader JavaDoc(new FileReader JavaDoc(new File JavaDoc(getStringProperty(EXCEPTION_FILE_NAME_PROPERTY)))));
87                 String JavaDoc line;
88                 while ((line = reader.readLine()) != null) {
89                     exceptions.add(line);
90                 }
91             } catch (IOException JavaDoc ioe) {
92                 ioe.printStackTrace();
93             } finally {
94                 try {
95                     if (reader != null)
96                         reader.close();
97                 } catch (IOException JavaDoc ioe) {
98                     ioe.printStackTrace();
99                 }
100             }
101         }
102
103         super.visit(node, data);
104
105         int threshold = getIntProperty("threshold");
106         for (Iterator JavaDoc i = literals.keySet().iterator(); i.hasNext();) {
107             String JavaDoc key = (String JavaDoc) i.next();
108             List JavaDoc occurrences = (List JavaDoc) literals.get(key);
109             if (occurrences.size() >= threshold) {
110                 Object JavaDoc[] args = new Object JavaDoc[]{key, new Integer JavaDoc(occurrences.size()), new Integer JavaDoc(((SimpleNode) occurrences.get(0)).getBeginLine())};
111                 addViolation(data, (SimpleNode) occurrences.get(0), args);
112             }
113         }
114         return data;
115     }
116
117     public Object JavaDoc visit(ASTLiteral node, Object JavaDoc data) {
118         // just catching strings of 5 chars or more (including the enclosing quotes) for now - no numbers
119
if (node.getImage() == null || node.getImage().indexOf('\"') == -1 || node.getImage().length() < 5) {
120             return data;
121         }
122
123         // skip any exceptions
124
if (exceptions.contains(node.getImage().substring(1, node.getImage().length() - 1))) {
125             return data;
126         }
127
128         if (literals.containsKey(node.getImage())) {
129             List JavaDoc occurrences = (List JavaDoc) literals.get(node.getImage());
130             occurrences.add(node);
131         } else {
132             List JavaDoc occurrences = new ArrayList JavaDoc();
133             occurrences.add(node);
134             literals.put(node.getImage(), occurrences);
135         }
136
137         return data;
138     }
139 }
140
141
Popular Tags