001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 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//////////////////////////////////////////////////////////////////////////////// 019package com.puppycrawl.tools.checkstyle.api; 020 021import com.google.common.collect.Sets; 022import java.util.Set; 023 024/** 025 * The base class for checks. 026 * 027 * @author Oliver Burn 028 * @version 1.0 029 * @see <a href="{@docRoot}/../writingchecks.html" target="_top">Writing 030 * your own checks</a> 031 */ 032public abstract class Check extends AbstractViolationReporter 033{ 034 /** default tab width for column reporting */ 035 private static final int DEFAULT_TAB_WIDTH = 8; 036 037 /** the current file contents */ 038 private FileContents mFileContents; 039 040 /** the tokens the check is interested in */ 041 private final Set<String> mTokens = Sets.newHashSet(); 042 043 /** the object for collecting messages. */ 044 private LocalizedMessages mMessages; 045 046 /** the tab width for column reporting */ 047 private int mTabWidth = DEFAULT_TAB_WIDTH; // meaningful default 048 049 /** 050 * The class loader to load external classes. Not initialised as this must 051 * be set by my creator. 052 */ 053 private ClassLoader mLoader; 054 055 /** 056 * Returns the default token a check is interested in. Only used if the 057 * configuration for a check does not define the tokens. 058 * @return the default tokens 059 * @see TokenTypes 060 */ 061 public abstract int[] getDefaultTokens(); 062 063 /** 064 * The configurable token set. 065 * Used to protect Checks against malicious users who specify an 066 * unacceptable token set in the configuration file. 067 * The default implementation returns the check's default tokens. 068 * @return the token set this check is designed for. 069 * @see TokenTypes 070 */ 071 public int[] getAcceptableTokens() 072 { 073 final int[] defaultTokens = getDefaultTokens(); 074 final int[] copy = new int[defaultTokens.length]; 075 System.arraycopy(defaultTokens, 0, copy, 0, defaultTokens.length); 076 return copy; 077 } 078 079 /** 080 * The tokens that this check must be registered for. 081 * @return the token set this must be registered for. 082 * @see TokenTypes 083 */ 084 public int[] getRequiredTokens() 085 { 086 return new int[] {}; 087 } 088 089 /** 090 * Adds a set of tokens the check is interested in. 091 * @param aStrRep the string representation of the tokens interested in 092 */ 093 public final void setTokens(String[] aStrRep) 094 { 095 for (final String s : aStrRep) { 096 mTokens.add(s); 097 } 098 } 099 100 /** 101 * Returns the tokens registered for the check. 102 * @return the set of token names 103 */ 104 public final Set<String> getTokenNames() 105 { 106 return mTokens; 107 } 108 109 /** 110 * Set the global object used to collect messages. 111 * @param aMessages the messages to log with 112 */ 113 public final void setMessages(LocalizedMessages aMessages) 114 { 115 mMessages = aMessages; 116 } 117 118 /** 119 * Initialise the check. This is the time to verify that the check has 120 * everything required to perform it job. 121 */ 122 public void init() 123 { 124 } 125 126 /** 127 * Destroy the check. It is being retired from service. 128 */ 129 public void destroy() 130 { 131 } 132 133 /** 134 * Called before the starting to process a tree. Ideal place to initialise 135 * information that is to be collected whilst processing a tree. 136 * @param aRootAST the root of the tree 137 */ 138 public void beginTree(DetailAST aRootAST) 139 { 140 } 141 142 /** 143 * Called after finished processing a tree. Ideal place to report on 144 * information collected whilst processing a tree. 145 * @param aRootAST the root of the tree 146 */ 147 public void finishTree(DetailAST aRootAST) 148 { 149 } 150 151 /** 152 * Called to process a token. 153 * @param aAST the token to process 154 */ 155 public void visitToken(DetailAST aAST) 156 { 157 } 158 159 /** 160 * Called after all the child nodes have been process. 161 * @param aAST the token leaving 162 */ 163 public void leaveToken(DetailAST aAST) 164 { 165 } 166 167 /** 168 * Returns the lines associated with the tree. 169 * @return the file contents 170 */ 171 public final String[] getLines() 172 { 173 return getFileContents().getLines(); 174 } 175 176 /** 177 * Set the file contents associated with the tree. 178 * @param aContents the manager 179 */ 180 public final void setFileContents(FileContents aContents) 181 { 182 mFileContents = aContents; 183 } 184 185 /** 186 * Returns the file contents associated with the tree. 187 * @return the file contents 188 */ 189 public final FileContents getFileContents() 190 { 191 return mFileContents; 192 } 193 194 /** 195 * Set the class loader associated with the tree. 196 * @param aLoader the class loader 197 */ 198 public final void setClassLoader(ClassLoader aLoader) 199 { 200 mLoader = aLoader; 201 } 202 203 /** 204 * Returns the class loader associated with the tree. 205 * @return the class loader 206 */ 207 public final ClassLoader getClassLoader() 208 { 209 return mLoader; 210 } 211 212 /** @return the tab width to report errors with */ 213 protected final int getTabWidth() 214 { 215 return mTabWidth; 216 } 217 218 /** 219 * Set the tab width to report errors with. 220 * @param aTabWidth an <code>int</code> value 221 */ 222 public final void setTabWidth(int aTabWidth) 223 { 224 mTabWidth = aTabWidth; 225 } 226 227 @Override 228 public final void log(int aLine, String aKey, Object... aArgs) 229 { 230 mMessages.add( 231 new LocalizedMessage( 232 aLine, 233 getMessageBundle(), 234 aKey, 235 aArgs, 236 getSeverityLevel(), 237 getId(), 238 this.getClass(), 239 this.getCustomMessages().get(aKey))); 240 } 241 242 243 @Override 244 public final void log(int aLineNo, int aColNo, String aKey, 245 Object... aArgs) 246 { 247 final int col = 1 + Utils.lengthExpandedTabs( 248 getLines()[aLineNo - 1], aColNo, getTabWidth()); 249 mMessages.add( 250 new LocalizedMessage( 251 aLineNo, 252 col, 253 getMessageBundle(), 254 aKey, 255 aArgs, 256 getSeverityLevel(), 257 getId(), 258 this.getClass(), 259 this.getCustomMessages().get(aKey))); 260 } 261}