KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > header > RegexpHeaderCheck


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.header;
20
21 import java.util.Arrays JavaDoc;
22 import java.util.regex.Pattern JavaDoc;
23 import java.util.regex.PatternSyntaxException JavaDoc;
24
25 import org.apache.commons.beanutils.ConversionException;
26
27 import com.puppycrawl.tools.checkstyle.api.DetailAST;
28 import com.puppycrawl.tools.checkstyle.api.Utils;
29 import com.puppycrawl.tools.checkstyle.checks.AbstractHeaderCheck;
30
31 /**
32  * Checks the header of the source against a header file that contains a
33  * {@link java.util.regex.Pattern regular expression}
34  * for each line of the source header.
35  *
36  * @author Lars Kühne
37  * @author o_sukhodolsky
38  */

39 public class RegexpHeaderCheck extends AbstractHeaderCheck
40 {
41     /** empty array to avoid instantiations. */
42     private static final int[] EMPTY_INT_ARRAY = new int[0];
43
44     /** the header lines to repeat (0 or more) in the check, sorted. */
45     private int[] mMultiLines = EMPTY_INT_ARRAY;
46
47     /** the compiled regular expressions */
48     private Pattern JavaDoc[] mHeaderRegexps;
49
50     /**
51      * @param aLineNo a line number
52      * @return if <code>aLineNo</code> is one of the repeat header lines.
53      */

54     private boolean isMultiLine(int aLineNo)
55     {
56         return (Arrays.binarySearch(mMultiLines, aLineNo + 1) >= 0);
57     }
58
59     /**
60      * Set the lines numbers to repeat in the header check.
61      * @param aList comma separated list of line numbers to repeat in header.
62      */

63     public void setMultiLines(int[] aList)
64     {
65         if ((aList == null) || (aList.length == 0)) {
66             mMultiLines = EMPTY_INT_ARRAY;
67             return;
68         }
69
70         mMultiLines = new int[aList.length];
71         System.arraycopy(aList, 0, mMultiLines, 0, aList.length);
72         Arrays.sort(mMultiLines);
73     }
74
75     /**
76      * Sets the file that contains the header to check against.
77      * @param aFileName the file that contains the header to check against.
78      * @throws org.apache.commons.beanutils.ConversionException if the file
79      * cannot be loaded or one line is not a regexp.
80      */

81     public void setHeaderFile(String JavaDoc aFileName)
82         throws ConversionException
83     {
84         super.setHeaderFile(aFileName);
85         initHeaderRegexps();
86     }
87
88     /**
89      * Set the header to check against. Individual lines in the header
90      * must be separated by '\n' characters.
91      * @param aHeader header content to check against.
92      * @throws org.apache.commons.beanutils.ConversionException if the header
93      * cannot be loaded or one line is not a regexp.
94      */

95     public void setHeader(String JavaDoc aHeader)
96     {
97         super.setHeader(aHeader);
98         initHeaderRegexps();
99     }
100
101     /**
102      * Initializes {@link #mHeaderRegexps} from
103      * {@link AbstractHeaderCheck#getHeaderLines()}.
104      */

105     private void initHeaderRegexps()
106     {
107         final String JavaDoc[] headerLines = getHeaderLines();
108         if (headerLines != null) {
109             mHeaderRegexps = new Pattern JavaDoc[headerLines.length];
110             for (int i = 0; i < headerLines.length; i++) {
111                 try {
112                     // TODO: Not sure if chache in Utils is still necessary
113
mHeaderRegexps[i] = Utils.getPattern(headerLines[i]);
114                 }
115                 catch (final PatternSyntaxException JavaDoc ex) {
116                     throw new ConversionException(
117                             "line " + i + " in header specification"
118                             + " is not a regular expression");
119                 }
120             }
121         }
122     }
123
124     /**
125      * Checks if a code line matches the required header line.
126      * @param aLineNo the linenumber to check against the header
127      * @param aHeaderLineNo the header line number.
128      * @return true if and only if the line matches the required header line.
129      */

130     private boolean isMatch(int aLineNo, int aHeaderLineNo)
131     {
132         final String JavaDoc line = getLines()[aLineNo];
133         return mHeaderRegexps[aHeaderLineNo].matcher(line).find();
134     }
135
136     /** {@inheritDoc} */
137     public void beginTree(DetailAST aRootAST)
138     {
139         final int headerSize = getHeaderLines().length;
140         final int fileSize = getLines().length;
141
142         if (headerSize - mMultiLines.length > fileSize) {
143             log(1, "header.missing");
144         }
145         else {
146             int headerLineNo = 0;
147             int i;
148             for (i = 0; (headerLineNo < headerSize) && (i < fileSize); i++) {
149                 boolean isMatch = isMatch(i, headerLineNo);
150                 while (!isMatch && isMultiLine(headerLineNo)) {
151                     headerLineNo++;
152                     isMatch = (headerLineNo == headerSize)
153                         || isMatch(i, headerLineNo);
154                 }
155                 if (!isMatch) {
156                     log(i + 1, "header.mismatch",
157                         getHeaderLines()[headerLineNo]);
158                     break; // stop checking
159
}
160                 if (!isMultiLine(headerLineNo)) {
161                     headerLineNo++;
162                 }
163             }
164             if (i == fileSize) {
165                 // if file finished, but we have at least one non-multi-line
166
// header isn't completed
167
for (; headerLineNo < headerSize; headerLineNo++) {
168                     if (!isMultiLine(headerLineNo)) {
169                         log(1, "header.missing");
170                         break;
171                     }
172                 }
173             }
174         }
175     }
176 }
177
Popular Tags