View Javadoc

1   package net.sourceforge.pmd.lang.java.rule.logging;
2   
3   import java.util.Stack;
4   
5   import net.sourceforge.pmd.lang.ast.Node;
6   import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
7   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
8   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
9   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 = ((ASTClassOrInterfaceType) classOrIntType).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  }