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