1
2
3
4 package net.sourceforge.pmd.lang.java.rule.logging;
5
6 import java.util.List;
7 import java.util.logging.Level;
8
9 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
10 import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
11
12 public class GuardLogStatementJavaUtilRule extends GuardLogStatementRule {
13
14 private static final String GUARD_METHOD_NAME = "isLoggable";
15
16 private static String extendedXPath = "//PrimaryPrefix[ends-with(Name/@Image, '.log')]\n" +
17 "[following-sibling::PrimarySuffix\n" +
18 " [ends-with(.//PrimaryPrefix/Name/@Image, 'LOG_LEVEL_UPPERCASE')]\n" +
19 " [count(../descendant::AdditiveExpression) > 0]\n" +
20 "]\n" +
21 "[count(ancestor::IfStatement/Expression/descendant::PrimaryExpression\n" +
22 " [ends-with(descendant::PrimaryPrefix[1]/Name/@Image,'GUARD')]) = 0\n" +
23 "or\n" +
24 "count(ancestor::IfStatement/Expression/descendant::PrimaryExpression\n" +
25 " [ends-with(descendant::PrimaryPrefix[2]/Name/@Image,'LOG_LEVEL_UPPERCASE')]) = 0]";
26
27 @Override
28 public Object visit(ASTCompilationUnit unit, Object data) {
29 if (isSlf4jImported(unit)) {
30 return data;
31 }
32
33 String[] logLevels = getProperty(LOG_LEVELS);
34 String[] guardMethods = getProperty(GUARD_METHODS);
35
36 if (super.guardStmtByLogLevel.isEmpty() && logLevels.length > 0 && guardMethods.length > 0) {
37 configureGuards(logLevels, guardMethods);
38 } else if ( super.guardStmtByLogLevel.isEmpty() ) {
39 configureDefaultGuards();
40 }
41
42 findViolationForEachLogStatement(unit, data, extendedXPath);
43 return super.visit(unit,data);
44 }
45
46 private boolean isSlf4jImported(ASTCompilationUnit unit) {
47 List<ASTImportDeclaration> imports = unit.findChildrenOfType(ASTImportDeclaration.class);
48 for (ASTImportDeclaration i : imports) {
49 if (i.getImportedName().startsWith("org.slf4j")) {
50 return true;
51 }
52 }
53 return false;
54 }
55
56 private void configureGuards(String[] logLevels, String[] guardMethods) {
57 String[] methods = guardMethods;
58 if (methods.length != logLevels.length) {
59 String firstMethodName = guardMethods[0];
60 methods = new String[logLevels.length];
61 for (int i = 0; i < logLevels.length; i++) {
62 methods[i] = firstMethodName;
63 }
64 }
65 for (int i = 0; i < logLevels.length; i++) {
66 super.guardStmtByLogLevel.put("." + logLevels[i], methods[i]);
67 }
68 }
69
70 private void configureDefaultGuards() {
71 super.guardStmtByLogLevel.put(formatLogLevelString(Level.FINEST), GUARD_METHOD_NAME);
72 super.guardStmtByLogLevel.put(formatLogLevelString(Level.FINER), GUARD_METHOD_NAME);
73 super.guardStmtByLogLevel.put(formatLogLevelString(Level.FINE), GUARD_METHOD_NAME);
74 super.guardStmtByLogLevel.put(formatLogLevelString(Level.INFO), GUARD_METHOD_NAME);
75 super.guardStmtByLogLevel.put(formatLogLevelString(Level.WARNING), GUARD_METHOD_NAME);
76 super.guardStmtByLogLevel.put(formatLogLevelString(Level.SEVERE), GUARD_METHOD_NAME);
77 }
78
79 private String formatLogLevelString(Level logLevel) {
80 return "." + logLevel.toString().toLowerCase();
81 }
82 }