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