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 private static final Class<?> SLF4J_LOGGER;
27
28 static {
29 Class<?> c;
30 try {
31 c = Class.forName("org.apache.log4j.Logger");
32 } catch (Throwable t) {
33 c = null;
34 }
35 LOG4J_LOGGER = c;
36 try {
37 c = Class.forName("java.util.logging.Logger");
38 } catch (Throwable t) {
39 c = null;
40 }
41 JAVA_LOGGER = c;
42 try {
43 c = Class.forName("org.slf4j.Logger");
44 } catch (Throwable t) {
45 c = null;
46 }
47 SLF4J_LOGGER = c;
48 }
49
50 private Stack<Integer> stack = new Stack<Integer>();
51
52 private Integer count;
53
54 @Override
55 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
56 return init(node, data);
57 }
58
59 @Override
60 public Object visit(ASTEnumDeclaration node, Object data) {
61 return init(node, data);
62 }
63
64 @Override
65 public Object visit(ASTAnnotationTypeDeclaration node, Object data) {
66 return init(node, data);
67 }
68
69 private Object init(JavaNode node, Object data) {
70 stack.push(count);
71 count = NumericConstants.ZERO;
72
73 node.childrenAccept(this, data);
74
75 if (count > 1) {
76 addViolation(data, node);
77 }
78 count = stack.pop();
79
80 return data;
81 }
82
83 @Override
84 public Object visit(ASTVariableDeclarator node, Object data) {
85 if (count > 1) {
86 return super.visit(node, data);
87 }
88 Node type = node.jjtGetParent().getFirstChildOfType(ASTType.class);
89 if (type != null) {
90 Node reftypeNode = type.jjtGetChild(0);
91 if (reftypeNode instanceof ASTReferenceType) {
92 Node classOrIntType = reftypeNode.jjtGetChild(0);
93 if (classOrIntType instanceof ASTClassOrInterfaceType) {
94 Class<?> clazzType = ((ASTClassOrInterfaceType) classOrIntType).getType();
95 if (clazzType != null && (clazzType.equals(LOG4J_LOGGER)
96 || clazzType.equals(JAVA_LOGGER)
97 || clazzType.equals(SLF4J_LOGGER))
98 || clazzType == null && "Logger".equals(classOrIntType.getImage())) {
99 ++count;
100 }
101 }
102 }
103 }
104
105 return super.visit(node, data);
106 }
107
108 }