1
2
3
4
5
6
7 package net.sourceforge.pmd.rules;
8
9 import net.sourceforge.pmd.AbstractRule;
10 import net.sourceforge.pmd.RuleContext;
11 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
12 import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
13 import net.sourceforge.pmd.ast.ASTFieldDeclaration;
14 import net.sourceforge.pmd.ast.ASTMethodDeclaration;
15 import net.sourceforge.pmd.ast.ASTMethodDeclarator;
16 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
17 import org.jaxen.JaxenException;
18
19 import java.text.MessageFormat;
20 import java.util.List;
21
22 /***
23 *
24 * @author Eric Olander
25 */
26 public class SingularField extends AbstractRule {
27
28 public Object visit(ASTFieldDeclaration node, Object data) {
29 if (node.isPrivate() && !node.isStatic()) {
30 List list = node.findChildrenOfType(ASTVariableDeclaratorId.class);
31 ASTVariableDeclaratorId decl = (ASTVariableDeclaratorId)list.get(0);
32 String name = decl.getImage();
33 String path = "//MethodDeclaration[.//PrimaryExpression[.//Name[@Image = \""+name+"\" or substring-before(@Image, \".\") = \""+name+"\"] or .//PrimarySuffix[@Image = \""+name+"\"]]] |" +
34 "//ConstructorDeclaration[.//PrimaryExpression[.//Name[@Image = \""+name+"\" or substring-before(@Image, \".\") = \""+name+"\"] or .//PrimarySuffix[@Image = \""+name+"\"]]]";
35 try {
36 List nodes = node.findChildNodesWithXPath(path);
37 if (nodes.size() == 1) {
38 String method;
39 if (nodes.get(0) instanceof ASTMethodDeclaration) {
40 method = ((ASTMethodDeclarator)((ASTMethodDeclaration)nodes.get(0)).findChildrenOfType(ASTMethodDeclarator.class).get(0)).getImage();
41 } else {
42 method = ((ASTClassOrInterfaceDeclaration)((ASTConstructorDeclaration)nodes.get(0)).getFirstParentOfType(ASTClassOrInterfaceDeclaration.class)).getImage();
43 }
44 ((RuleContext)data).getReport().addRuleViolation(createRuleViolation((RuleContext) data, decl, MessageFormat.format(getMessage(), new Object[]{name, method})));
45 }
46 } catch (JaxenException je) {
47 je.printStackTrace();
48 }
49 }
50 return data;
51 }
52
53 }