View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
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  }