/*
* Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.yangtools.checkstyle;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
public class LogMessagePlaceholderCountCheck extends AbstractLogMessageCheck {
private static final String LOG_MESSAGE = "Log message placeholders count is incorrect.";
private static final String PLACEHOLDER = "{}";
private static final String EXCEPTION_TYPE = "Exception";
@Override
protected void visitLogMessage(DetailAST ast, String logMessage) {
int placeholdersCount = placeholdersCount(logMessage);
int argumentsCount = ast.findFirstToken(TokenTypes.ELIST).getChildCount(TokenTypes.EXPR) - 1;
final String lastArg = ast.findFirstToken(TokenTypes.ELIST).getLastChild().getFirstChild().getText();
if (hasCatchBlockParentWithArgument(lastArg, ast) || hasMethodDefinitionWithExceptionArgument(lastArg, ast)) {
argumentsCount--;
}
if (placeholdersCount > argumentsCount) {
log(ast.getLineNo(), LOG_MESSAGE);
}
}
private int placeholdersCount(final String message) {
return (message.length() - message.replace(PLACEHOLDER, "").length()) / PLACEHOLDER.length();
}
private boolean hasCatchBlockParentWithArgument(final String argumentName, final DetailAST ast) {
DetailAST parent = ast.getParent();
while (parent != null && parent.getType() != TokenTypes.LITERAL_CATCH) {
parent = parent.getParent();
}
if (parent != null && parent.findFirstToken(TokenTypes.PARAMETER_DEF) != null
&& parent.findFirstToken(TokenTypes.PARAMETER_DEF).findFirstToken(TokenTypes.IDENT).getText()
.equals(argumentName)) {
return true;
}
return false;
}
private boolean hasMethodDefinitionWithExceptionArgument(final String argumentName, final DetailAST ast) {
DetailAST parent = ast.getParent();
while (parent != null && parent.getType() != TokenTypes.METHOD_DEF) {
parent = parent.getParent();
}
if (parent != null && parent.findFirstToken(TokenTypes.PARAMETERS).findFirstToken(TokenTypes.PARAMETER_DEF)
!= null) {
DetailAST paramDef = parent.findFirstToken(TokenTypes.PARAMETERS).getFirstChild();
while (paramDef != null) {
if (paramDef.getType() == TokenTypes.PARAMETER_DEF) {
final String paramName = paramDef.findFirstToken(TokenTypes.IDENT).getText();
if (paramName.equals(argumentName) && isExceptionType(paramDef)) {
return true;
}
}
paramDef = paramDef.getNextSibling();
}
}
return false;
}
private boolean isExceptionType(final DetailAST parameterDef) {
if (parameterDef != null) {
final DetailAST type = parameterDef.findFirstToken(TokenTypes.TYPE);
if (type != null && type.findFirstToken(TokenTypes.IDENT) != null) {
final String argumentType = type.findFirstToken(TokenTypes.IDENT).getText();
if (argumentType.contains(EXCEPTION_TYPE)) {
return true;
}
}
}
return false;
}
}