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