KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > RegexpCheck


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle.checks;
20
21 import com.puppycrawl.tools.checkstyle.api.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.FileContents;
23 import java.util.ArrayList JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.regex.Matcher JavaDoc;
26 import java.util.regex.Pattern JavaDoc;
27
28 /**
29  * <p>
30  * A check that makes sure that a specified pattern exists (or not) in the file.
31  * </p>
32  * <p>
33  * An example of how to configure the check to make sure a copyright statement
34  * is included in the file (but without requirements on where in the file
35  * it should be):
36  * </p>
37  * <pre>
38  * &lt;module name="RequiredRegexp"&gt;
39  * &lt;property name="format" value="This code is copyrighted"/&gt;
40  * &lt;/module&gt;
41  * </pre>
42  * <p>
43  * And to make sure the same statement appears at the beginning of the file.
44  * </p>
45  * <pre>
46  * &lt;module name="RequiredRegexp"&gt;
47  * &lt;property name="format" value="\AThis code is copyrighted"/&gt;
48  * &lt;/module&gt;
49  * </pre>
50  * @author Stan Quinn
51  */

52 public class RegexpCheck extends AbstractFormatCheck
53 {
54     /** Default duplicate limit */
55     private static final int DEFAULT_DUPLICATE_LIMIT = -1;
56
57     /** Default error report limit */
58     private static final int DEFAULT_ERROR_LIMIT = 100;
59
60     /** Error count exceeded message */
61     private static final String JavaDoc ERROR_LIMIT_EXCEEDED_MESSAGE =
62         "The error limit has been exceeded, "
63         + "the check is aborting, there may be more unreported errors.";
64
65     /** Custom message for report. */
66     private String JavaDoc mMessage = "";
67
68     /** Ignore matches within comments? **/
69     private boolean mIgnoreComments;
70
71     /** Pattern illegal? */
72     private boolean mIllegalPattern;
73
74     /** Error report limit */
75     private int mErrorLimit = DEFAULT_ERROR_LIMIT;
76
77     /** Disallow more than x duplicates? */
78     private int mDuplicateLimit;
79
80     /** Boolean to say if we should check for duplicates. */
81     private boolean mCheckForDuplicates;
82
83     /** Tracks number of matches made */
84     private int mMatchCount;
85
86     /** Tracks number of errors */
87     private int mErrorCount;
88
89     /** Relates StringBuffer positions to line # and column */
90     private final List JavaDoc mCharacters = new ArrayList JavaDoc();
91
92     /** The mMatcher */
93     private Matcher JavaDoc mMatcher;
94
95     /**
96      * Instantiates an new RegexpCheck.
97      */

98     public RegexpCheck()
99     {
100         super("$^", Pattern.MULTILINE); // the empty language
101
}
102
103     /**
104      * Setter for message property.
105      * @param aMessage custom message which should be used in report.
106      */

107     public void setMessage(String JavaDoc aMessage)
108     {
109         mMessage = (aMessage == null) ? "" : aMessage;
110     }
111
112     /**
113      * Getter for message property.
114      * I'm not sure if this gets used by anything outside,
115      * I just included it because GenericIllegalRegexp had it,
116      * it's being used in logMessage() so it's covered in EMMA.
117      * @return custom message to be used in report.
118      */

119     public String JavaDoc getMessage()
120     {
121         return mMessage;
122     }
123
124     /**
125      * Sets if matches within comments should be ignored.
126      * @param aIgnoreComments True if comments should be ignored.
127      */

128     public void setIgnoreComments(boolean aIgnoreComments)
129     {
130         mIgnoreComments = aIgnoreComments;
131     }
132
133     /**
134      * Sets if pattern is illegal, otherwise pattern is required.
135      * @param aIllegalPattern True if pattern is not allowed.
136      */

137     public void setIllegalPattern(boolean aIllegalPattern)
138     {
139         mIllegalPattern = aIllegalPattern;
140     }
141
142     /**
143      * Sets the limit on the number of errors to report.
144      * @param aErrorLimit the number of errors to report.
145      */

146     public void setErrorLimit(int aErrorLimit)
147     {
148         mErrorLimit = aErrorLimit;
149     }
150
151     /**
152      * Sets the maximum number of instances of required pattern allowed.
153      * @param aDuplicateLimit negative values mean no duplicate checking,
154      * any positive value is used as the limit.
155      */

156     public void setDuplicateLimit(int aDuplicateLimit)
157     {
158         mDuplicateLimit = aDuplicateLimit;
159         mCheckForDuplicates = (mDuplicateLimit > DEFAULT_DUPLICATE_LIMIT);
160     }
161
162     /** {@inheritDoc} */
163     public int[] getDefaultTokens()
164     {
165         return new int[0];
166     }
167
168     /** {@inheritDoc} */
169     public void beginTree(DetailAST aRootAST)
170     {
171         mCharacters.clear();
172         final Pattern JavaDoc pattern = getRegexp();
173         final String JavaDoc[] lines = getLines();
174         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
175         for (int i = 0; i < lines.length; i++) {
176             sb.append(lines[i]);
177             sb.append('\n');
178             for (int j = 0; j < (lines[i].length() + 1); j++) {
179                 mCharacters.add(new Integer JavaDoc[] {
180                     new Integer JavaDoc(i + 1), new Integer JavaDoc(j), });
181             }
182         }
183         mMatcher = pattern.matcher(sb.toString());
184         mMatchCount = 0;
185         mErrorCount = 0;
186         findMatch();
187     }
188
189     /** recursive method that finds the matches. */
190     private void findMatch()
191     {
192         int startLine;
193         int startColumn;
194         int endLine;
195         int endColumn;
196         boolean foundMatch;
197         boolean ignore = false;
198
199         foundMatch = mMatcher.find();
200         if (!foundMatch && !mIllegalPattern && (mMatchCount == 0)) {
201             logMessage(0);
202         }
203         else if (foundMatch) {
204             startLine = ((Integer JavaDoc[]) mCharacters.get(mMatcher.start()))[0].
205                     intValue();
206             startColumn = ((Integer JavaDoc[]) mCharacters.get(mMatcher.start()))[1].
207                     intValue();
208             endLine = ((Integer JavaDoc[]) mCharacters.get(mMatcher.end() - 1))[0].
209                     intValue();
210             endColumn = ((Integer JavaDoc[]) mCharacters.get(mMatcher.end() - 1))[1].
211                     intValue();
212             if (mIgnoreComments) {
213                 final FileContents theFileContents = getFileContents();
214                 ignore = theFileContents.hasIntersectionWithComment(startLine,
215                     startColumn, endLine, endColumn);
216             }
217             if (!ignore) {
218                 mMatchCount++;
219                 if (mIllegalPattern || (mCheckForDuplicates
220                         && ((mMatchCount - 1) > mDuplicateLimit)))
221                 {
222                     mErrorCount++;
223                     logMessage(startLine);
224                 }
225             }
226             if ((mErrorCount < mErrorLimit)
227                     && (ignore || mIllegalPattern || mCheckForDuplicates))
228             {
229                 findMatch();
230             }
231         }
232     }
233
234     /**
235      * Displays the right message.
236      * @param aLineNumber the line number the message relates to.
237      */

238     private void logMessage(int aLineNumber)
239     {
240         String JavaDoc message = "".equals(getMessage()) ? getFormat() : mMessage;
241         if (mErrorCount >= mErrorLimit) {
242             message = ERROR_LIMIT_EXCEEDED_MESSAGE + message;
243         }
244         if (mIllegalPattern) {
245             log(aLineNumber, "illegal.regexp", message);
246         }
247         else {
248             if (aLineNumber > 0) {
249                 log(aLineNumber, "duplicate.regexp", message);
250             }
251             else {
252                 log(aLineNumber, "required.regexp", message);
253             }
254         }
255     }
256 }
257
258
Popular Tags