Conform to our own Checkstyle rules in checkstyle-logging utility
[yangtools.git] / common / checkstyle-logging / src / main / java / org / opendaylight / yangtools / checkstyle / LogMessagePlaceholderCountCheck.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.yangtools.checkstyle;
10
11 import com.puppycrawl.tools.checkstyle.api.Check;
12 import com.puppycrawl.tools.checkstyle.api.DetailAST;
13 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
14
15 public class LogMessagePlaceholderCountCheck extends Check {
16
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";
20
21     @Override
22     public int[] getDefaultTokens() {
23         return new int[]{TokenTypes.METHOD_CALL};
24     }
25
26     @Override
27     public void visitToken(DetailAST ast) {
28         final String methodName = CheckLoggingUtil.getMethodName(ast);
29         if (CheckLoggingUtil.isLogMethod(methodName)) {
30             final String logMessage = ast.findFirstToken(TokenTypes.ELIST).getFirstChild().getFirstChild().getText();
31             int placeholdersCount = placeholdersCount(logMessage);
32             int argumentsCount = ast.findFirstToken(TokenTypes.ELIST).getChildCount(TokenTypes.EXPR) - 1;
33             final String lastArg = ast.findFirstToken(TokenTypes.ELIST).getLastChild().getFirstChild().getText();
34             if (hasCatchBlockParentWithArgument(lastArg, ast) || hasMethodDefinitionWithExceptionArgument(lastArg,
35                     ast)) {
36                 argumentsCount--;
37             }
38             if (placeholdersCount > argumentsCount) {
39                 log(ast.getLineNo(), LOG_MESSAGE);
40             }
41         }
42     }
43
44     private int placeholdersCount(final String message) {
45         return (message.length() - message.replace(PLACEHOLDER, "").length()) / PLACEHOLDER.length();
46     }
47
48     private boolean hasCatchBlockParentWithArgument(final String argumentName, final DetailAST ast) {
49         DetailAST parent = ast.getParent();
50         while (parent != null && parent.getType() != TokenTypes.LITERAL_CATCH) {
51             parent = parent.getParent();
52         }
53         if (parent != null && parent.findFirstToken(TokenTypes.PARAMETER_DEF) != null
54                 && parent.findFirstToken(TokenTypes.PARAMETER_DEF).findFirstToken(TokenTypes.IDENT).getText()
55                         .equals(argumentName)) {
56             return true;
57         }
58         return false;
59     }
60
61     private boolean hasMethodDefinitionWithExceptionArgument(final String argumentName, final DetailAST ast) {
62         DetailAST parent = ast.getParent();
63         while (parent != null && parent.getType() != TokenTypes.METHOD_DEF) {
64             parent = parent.getParent();
65         }
66         if (parent != null && parent.findFirstToken(TokenTypes.PARAMETERS).findFirstToken(TokenTypes.PARAMETER_DEF)
67                 != null) {
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)) {
73                         return true;
74                     }
75                 }
76                 paramDef = paramDef.getNextSibling();
77             }
78         }
79         return false;
80     }
81
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)) {
88                     return true;
89                 }
90             }
91         }
92         return false;
93     }
94
95 }