MoreThanOneLoggerRule.java
01 package net.sourceforge.pmd.lang.java.rule.logging;
02 
03 import java.util.Stack;
04 
05 import net.sourceforge.pmd.lang.ast.Node;
06 import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
07 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
08 import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
09 import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
10 import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
11 import net.sourceforge.pmd.lang.java.ast.ASTType;
12 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
13 import net.sourceforge.pmd.lang.java.ast.JavaNode;
14 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15 import net.sourceforge.pmd.util.NumericConstants;
16 
17 public class MoreThanOneLoggerRule extends AbstractJavaRule {
18 
19     private static final Class<?> LOG4J_LOGGER;
20 
21     private static final Class<?> JAVA_LOGGER;
22 
23     static {
24   Class<?> c;
25   try {
26       c = Class.forName("org.apache.log4j.Logger");
27   catch (Throwable t) {
28       c = null;
29   }
30   LOG4J_LOGGER = c;
31   try {
32       c = Class.forName("java.util.logging.Logger");
33   catch (Throwable t) {
34       c = null;
35   }
36   JAVA_LOGGER = c;
37     }
38 
39     private Stack<Integer> stack = new Stack<Integer>();
40 
41     private Integer count;
42 
43     @Override
44     public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
45   return init(node, data);
46     }
47 
48     @Override
49     public Object visit(ASTEnumDeclaration node, Object data) {
50   return init(node, data);
51     }
52 
53     @Override
54     public Object visit(ASTAnnotationTypeDeclaration node, Object data) {
55   return init(node, data);
56     }
57 
58     private Object init(JavaNode node, Object data) {
59   stack.push(count);
60   count = NumericConstants.ZERO;
61 
62   node.childrenAccept(this, data);
63 
64   if (count > 1) {
65       addViolation(data, node);
66   }
67   count = stack.pop();
68 
69   return data;
70     }
71 
72     @Override
73     public Object visit(ASTVariableDeclarator node, Object data) {
74   if (count > 1) {
75       return super.visit(node, data);
76   }
77   Node type = node.jjtGetParent().getFirstChildOfType(ASTType.class);
78   if (type != null) {
79       Node reftypeNode = type.jjtGetChild(0);
80       if (reftypeNode instanceof ASTReferenceType) {
81     Node classOrIntType = reftypeNode.jjtGetChild(0);
82     if (classOrIntType instanceof ASTClassOrInterfaceType) {
83         Class<?> clazzType = ((ASTClassOrInterfaceTypeclassOrIntType).getType();
84         if (clazzType != null && (clazzType.equals(LOG4J_LOGGER|| clazzType.equals(JAVA_LOGGER))
85           || clazzType == null && "Logger".equals(classOrIntType.getImage())) {
86       ++count;
87         }
88     }
89       }
90   }
91 
92   return super.visit(node, data);
93     }
94 
95 }