/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.logging;
import java.util.List;
import java.util.logging.Level;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
public class GuardLogStatementJavaUtilRule extends GuardLogStatementRule {
private static final String GUARD_METHOD_NAME = "isLoggable";
private static String extendedXPath = "//PrimaryPrefix[ends-with(Name/@Image, '.log')]\n"
+ "[following-sibling::PrimarySuffix\n"
+ " [ends-with(.//PrimaryPrefix/Name/@Image, 'LOG_LEVEL_UPPERCASE')]\n"
+ " [count(../descendant::AdditiveExpression) > 0]\n" + "]\n"
+ "[count(ancestor::IfStatement/Expression/descendant::PrimaryExpression\n"
+ " [ends-with(descendant::PrimaryPrefix[1]/Name/@Image,'GUARD')]) = 0\n" + "or\n"
+ "count(ancestor::IfStatement/Expression/descendant::PrimaryExpression\n"
+ " [ends-with(descendant::PrimaryPrefix[2]/Name/@Image,'LOG_LEVEL_UPPERCASE')]) = 0]";
@Override
public Object visit(ASTCompilationUnit unit, Object data) {
if (isSlf4jOrLog4jImported(unit)) {
return data;
}
String[] logLevels = getProperty(LOG_LEVELS);
String[] guardMethods = getProperty(GUARD_METHODS);
if (super.guardStmtByLogLevel.isEmpty() && logLevels.length > 0 && guardMethods.length > 0) {
configureGuards(logLevels, guardMethods);
} else if (super.guardStmtByLogLevel.isEmpty()) {
configureDefaultGuards();
}
findViolationForEachLogStatement(unit, data, extendedXPath);
return super.visit(unit, data);
}
private boolean isSlf4jOrLog4jImported(ASTCompilationUnit unit) {
List<ASTImportDeclaration> imports = unit.findChildrenOfType(ASTImportDeclaration.class);
for (ASTImportDeclaration i : imports) {
if (i.getImportedName().startsWith("org.slf4j") || i.getImportedName().startsWith("org.apache.log4j")) {
return true;
}
}
return false;
}
private void configureGuards(String[] logLevels, String[] guardMethods) {
String[] methods = guardMethods;
if (methods.length != logLevels.length) {
String firstMethodName = guardMethods[0];
methods = new String[logLevels.length];
for (int i = 0; i < logLevels.length; i++) {
methods[i] = firstMethodName;
}
}
for (int i = 0; i < logLevels.length; i++) {
super.guardStmtByLogLevel.put("." + logLevels[i], methods[i]);
}
}
private void configureDefaultGuards() {
super.guardStmtByLogLevel.put(formatLogLevelString(Level.FINEST), GUARD_METHOD_NAME);
super.guardStmtByLogLevel.put(formatLogLevelString(Level.FINER), GUARD_METHOD_NAME);
super.guardStmtByLogLevel.put(formatLogLevelString(Level.FINE), GUARD_METHOD_NAME);
super.guardStmtByLogLevel.put(formatLogLevelString(Level.INFO), GUARD_METHOD_NAME);
super.guardStmtByLogLevel.put(formatLogLevelString(Level.WARNING), GUARD_METHOD_NAME);
super.guardStmtByLogLevel.put(formatLogLevelString(Level.SEVERE), GUARD_METHOD_NAME);
}
private String formatLogLevelString(Level logLevel) {
return "." + logLevel.toString().toLowerCase();
}
}