001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2015 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.api; 021 022import java.util.Map; 023 024import com.google.common.annotations.VisibleForTesting; 025 026/** 027 * Serves as an abstract base class for all modules that report inspection 028 * findings. Such modules have a Severity level which is used for the 029 * {@link LocalizedMessage localized messages} that are created by the module. 030 * 031 * @author lkuehne 032 */ 033public abstract class AbstractViolationReporter 034 extends AutomaticBean { 035 /** The severity level of any violations found. */ 036 private SeverityLevel severityLevel = SeverityLevel.ERROR; 037 038 /** The identifier of the reporter. */ 039 private String id; 040 041 /** 042 * Returns the severity level of the messages generated by this module. 043 * @return the severity level 044 * @see SeverityLevel 045 * @see LocalizedMessage#getSeverityLevel 046 */ 047 public final SeverityLevel getSeverityLevel() { 048 return severityLevel; 049 } 050 051 /** 052 * Sets the severity level. The string should be one of the names 053 * defined in the {@code SeverityLevel} class. 054 * 055 * @param severity The new severity level 056 * @see SeverityLevel 057 */ 058 public final void setSeverity(String severity) { 059 severityLevel = SeverityLevel.getInstance(severity); 060 } 061 062 /** 063 * Get the severity level's name. 064 * 065 * @return the check's severity level name. 066 */ 067 public final String getSeverity() { 068 return severityLevel.getName(); 069 } 070 071 /** 072 * Returns the identifier of the reporter. Can be null. 073 * @return the id 074 */ 075 public final String getId() { 076 return id; 077 } 078 079 /** 080 * Sets the identifier of the reporter. Can be null. 081 * @param id the id 082 */ 083 public final void setId(final String id) { 084 this.id = id; 085 } 086 087 /** 088 * Returns the message bundle name resource bundle that contains the messages 089 * used by this module. 090 * <p> 091 * The default implementation expects the resource files to be named 092 * messages.properties, messages_de.properties, etc. The file must 093 * be placed in the same package as the module implementation. 094 * </p> 095 * <p> 096 * Example: If you write com/foo/MyCoolCheck, create resource files 097 * com/foo/messages.properties, com/foo/messages_de.properties, etc. 098 * </p> 099 * 100 * @return name of a resource bundle that contains the messages 101 * used by this module. 102 */ 103 protected String getMessageBundle() { 104 final String className = getClass().getName(); 105 return getMessageBundle(className); 106 } 107 108 /** 109 * For unit tests, especially with a class with no package name. 110 * @param className class name of the module. 111 * @return name of a resource bundle that contains the messages 112 * used by the module. 113 */ 114 @VisibleForTesting 115 static String getMessageBundle(final String className) { 116 final int endIndex = className.lastIndexOf('.'); 117 final String messages = "messages"; 118 if (endIndex < 0) { 119 return messages; 120 } 121 final String packageName = className.substring(0, endIndex); 122 return packageName + "." + messages; 123 } 124 125 /** 126 * Returns an unmodifiable map instance containing the custom messages 127 * for this configuration. 128 * @return unmodifiable map containing custom messages 129 */ 130 protected Map<String, String> getCustomMessages() { 131 return getConfiguration().getMessages(); 132 } 133 134 /** 135 * Helper method to log a LocalizedMessage. 136 * 137 * @param ast a node to get line id column numbers associated 138 * with the message 139 * @param key key to locale message format 140 * @param args arguments to format 141 */ 142 protected final void log(DetailAST ast, String key, Object... args) { 143 log(ast.getLineNo(), ast.getColumnNo(), key, args); 144 } 145 146 /** 147 * Log a message that has no column information. 148 * 149 * @param line the line number where the error was found 150 * @param key the message that describes the error 151 * @param args the details of the message 152 * 153 * @see java.text.MessageFormat 154 */ 155 public abstract void log(int line, String key, Object... args); 156 157 /** 158 * Log a message that has column information. 159 * 160 * @param line the line number where the error was found 161 * @param col the column number where the error was found 162 * @param key the message that describes the error 163 * @param args the details of the message 164 * 165 * @see java.text.MessageFormat 166 */ 167 public abstract void log(int line, int col, String key, 168 Object... args); 169}