UseSingletonRule.java
01 /**
02  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03  */
04 package net.sourceforge.pmd.lang.java.rule.design;
05 
06 import net.sourceforge.pmd.lang.ast.Node;
07 import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
08 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody;
09 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
10 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
11 import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
12 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
13 import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
14 import net.sourceforge.pmd.lang.java.ast.ASTResultType;
15 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
16 
17 public class UseSingletonRule extends AbstractJavaRule {
18 
19     @Override
20     public Object visit(ASTClassOrInterfaceBody decl, Object data) {
21         if (decl.jjtGetParent() instanceof ASTClassOrInterfaceDeclaration) {
22             ASTClassOrInterfaceDeclaration parent = (ASTClassOrInterfaceDeclarationdecl.jjtGetParent();
23             if (parent.isAbstract() || parent.isInterface()) {
24                 return super.visit(decl, data);
25             }
26             int i = decl.jjtGetNumChildren();
27             int methodCount = 0;
28             boolean isOK = false;
29             while (i > 0) {
30                 Node p = decl.jjtGetChild(--i);
31                 if (p.jjtGetNumChildren() == 0) {
32                     continue;
33                 }
34                 Node n = p.jjtGetChild(0);
35                 if (instanceof ASTAnnotation) {
36                     n = p.jjtGetChild(1);
37                 }
38                 if (instanceof ASTFieldDeclaration) {
39                     if (!((ASTFieldDeclarationn).isStatic()) {
40                         isOK = true;
41                         break;
42                     }
43                 else if (instanceof ASTConstructorDeclaration) {
44                     if (((ASTConstructorDeclarationn).isPrivate()) {
45                         isOK = true;
46                         break;
47                     }
48                 else if (instanceof ASTMethodDeclaration) {
49                     ASTMethodDeclaration m = (ASTMethodDeclarationn;
50                     if (!m.isPrivate()) {
51                         methodCount++;
52                     }
53                     if (!m.isStatic()) {
54                         isOK = true;
55                         break;
56                     }
57 
58                     // TODO use symbol table
59                     if (m.getMethodName().equals("suite")) {
60                         ASTResultType res = m.getResultType();
61                         ASTClassOrInterfaceType c = res.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
62                         if (c != null && c.hasImageEqualTo("Test")) {
63                             isOK = true;
64                             break;
65                         }
66                     }
67 
68                 }
69             }
70             if (!isOK && methodCount > 0) {
71                 addViolation(data, decl);
72             }
73         }
74         return super.visit(decl, data);
75     }
76 
77 }