2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.yangtools.checkstyle;
11 import com.puppycrawl.tools.checkstyle.api.Check;
12 import com.puppycrawl.tools.checkstyle.api.DetailAST;
13 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
15 public class LogMessagePlaceholderCountCheck extends Check {
17 private static final String LOG_MESSAGE = "Log message placeholders count is incorrect.";
18 private static final String PLACEHOLDER = "{}";
19 private static final String EXCEPTION_TYPE = "Exception";
22 public int[] getDefaultTokens() {
23 return new int[]{TokenTypes.METHOD_CALL};
27 public void visitToken(DetailAST aAST) {
28 final String methodName = CheckLoggingUtil.getMethodName(aAST);
29 if (CheckLoggingUtil.isLogMethod(methodName)) {
30 final String logMessage = aAST.findFirstToken(TokenTypes.ELIST).getFirstChild().getFirstChild().getText();
31 int placeholdersCount = placeholdersCount(logMessage);
32 int argumentsCount = aAST.findFirstToken(TokenTypes.ELIST).getChildCount(TokenTypes.EXPR) - 1;
33 final String lastArg = aAST.findFirstToken(TokenTypes.ELIST).getLastChild().getFirstChild().getText();
34 if (hasCatchBlockParentWithArgument(lastArg, aAST) || hasMethodDefinitionWithExceptionArgument(lastArg,
38 if (placeholdersCount > argumentsCount) {
39 log(aAST.getLineNo(), LOG_MESSAGE);
44 private int placeholdersCount(final String message) {
45 return (message.length() - message.replace(PLACEHOLDER, "").length()) / PLACEHOLDER.length();
48 private boolean hasCatchBlockParentWithArgument(final String argumentName, final DetailAST aAST) {
49 DetailAST parent = aAST.getParent();
50 while(parent != null && parent.getType() != TokenTypes.LITERAL_CATCH) {
51 parent = parent.getParent();
53 if (parent != null && parent.findFirstToken(TokenTypes.PARAMETER_DEF) != null &&
54 parent.findFirstToken(TokenTypes.PARAMETER_DEF).findFirstToken(TokenTypes.IDENT).getText().equals
61 private boolean hasMethodDefinitionWithExceptionArgument(final String argumentName, final DetailAST aAST) {
62 DetailAST parent = aAST.getParent();
63 while(parent != null && parent.getType() != TokenTypes.METHOD_DEF) {
64 parent = parent.getParent();
66 if (parent != null && parent.findFirstToken(TokenTypes.PARAMETERS).findFirstToken(TokenTypes.PARAMETER_DEF)
68 DetailAST paramDef = parent.findFirstToken(TokenTypes.PARAMETERS).getFirstChild();
69 while(paramDef != null) {
70 if (paramDef.getType() == TokenTypes.PARAMETER_DEF) {
71 final String paramName = paramDef.findFirstToken(TokenTypes.IDENT).getText();
72 if (paramName.equals(argumentName) && isExceptionType(paramDef)) {
76 paramDef = paramDef.getNextSibling();
82 private boolean isExceptionType(final DetailAST parameterDef) {
83 if (parameterDef != null) {
84 final DetailAST type = parameterDef.findFirstToken(TokenTypes.TYPE);
85 if (type != null && type.findFirstToken(TokenTypes.IDENT) != null) {
86 final String argumentType = type.findFirstToken(TokenTypes.IDENT).getText();
87 if (argumentType.contains(EXCEPTION_TYPE)) {