implemented header checks, still need to remove old code

This commit is contained in:
Lars Kühne 2002-09-28 19:09:34 +00:00
parent c2afeecbf7
commit f24c8ee834
3 changed files with 216 additions and 4 deletions

View File

@ -18,20 +18,34 @@
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.checks;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.TreeSet;
import com.puppycrawl.tools.checkstyle.api.Check;
import org.apache.commons.beanutils.ConversionException;
/**
* Checks that the header of the source file is correct.
* Checks the header of the source against a fixed header file.
*
* <p>
* Rationale: In most projects each file must have a fixed header,
* usually the header contains copyright information.
* since usually the header contains copyright information.
* </p>
*
* @author Lars Kühne
*/
public class HeaderCheck extends Check
{
/** the lines of the header file */
private String[] mHeaderLines = null;
/** the header lines to ignore in the check */
private TreeSet mIgnoreLines = new TreeSet();
/** @see com.puppycrawl.tools.checkstyle.api.Check */
public int[] getDefaultTokens()
{
@ -41,7 +55,105 @@ public class HeaderCheck extends Check
/** @see com.puppycrawl.tools.checkstyle.api.Check */
public void beginTree()
{
String[] lines = getLines();
log(0, "file has " + lines.length + " lines");
System.out.println("HeaderCheck.beginTree");
if (mHeaderLines != null) {
final String[] lines = getLines();
if (mHeaderLines.length > lines.length) {
log(1, "header.missing");
}
else {
for (int i = 0; i < mHeaderLines.length; i++) {
// skip lines we are meant to ignore
if (isIgnoreLine(i + 1)) {
continue;
}
if (!isMatch(i)) {
log(i + 1, "header.mismatch", mHeaderLines[i]);
break; // stop checking
}
}
}
}
}
/**
* @param aLineNo a line number
* @return if <code>aLineNo</code> is one of the ignored header lines.
*/
private boolean isIgnoreLine(int aLineNo)
{
return mIgnoreLines.contains(new Integer(aLineNo));
}
/**
* Checks if a code line matches the required header line.
* @param lineNumber the linenumber to check against the header
* @return true if and only if the line matches the required header line
* TODO: override this in RegexpHeaderCheck
*/
protected boolean isMatch(int lineNumber)
{
final String[] lines = getLines();
return mHeaderLines[lineNumber].equals(lines[lineNumber]);
}
/**
* Set the header file to check against.
* @throws org.apache.commons.beanutils.ConversionException if
* the file cannot be loaded
*/
public void setHeaderFile(String aFileName)
{
// Handle empty param
if ((aFileName == null) || (aFileName.trim().length() == 0)) {
return;
}
// load the file
try {
final LineNumberReader lnr =
new LineNumberReader(new FileReader(aFileName));
final ArrayList lines = new ArrayList();
while (true) {
final String l = lnr.readLine();
if (l == null) {
break;
}
lines.add(l);
}
mHeaderLines = (String[]) lines.toArray(new String[0]);
}
catch (IOException ex) {
throw new ConversionException(
"unable to load header file " + aFileName, ex);
}
}
/**
* Set the lines numbers to ignore in the header check.
* @param aList comma separated list of line numbers to ignore in header.
* TODO: This should really be of type int[]
* and beanutils should do the parsing for us!
*/
public void setIgnoreLines(String aList)
{
mIgnoreLines.clear();
if (aList != null) {
final StringTokenizer tokens = new StringTokenizer(aList, ",");
while (tokens.hasMoreTokens()) {
final String ignoreLine = tokens.nextToken();
mIgnoreLines.add(new Integer(ignoreLine));
}
}
}
protected String[] getHeaderLines()
{
return mHeaderLines;
}
}

View File

@ -0,0 +1,57 @@
package com.puppycrawl.tools.checkstyle.checks;
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
import org.apache.commons.beanutils.ConversionException;
import com.puppycrawl.tools.checkstyle.api.Utils;
/**
* Checks the header of the source against a header file that contains a
* regular expression for each line of the source header.
*
* <p>
* Rationale: In some projects checking against a fixed header
* is not sufficient (see {@link HeaderCheck}), e.g.
* the header might require a copyright line where the year information
* is not static.
* </p>
*
* <p>
* TODO: RFE 597676
* </p>
*
* @author Lars Kühne
*/
public class RegexpHeaderCheck extends HeaderCheck
{
/** the compiled regular expressions */
private RE[] mHeaderRegexps = null;
/** */
public void setHeaderFile(String aFileName)
{
super.setHeaderFile(aFileName);
final String[] headerLines = getHeaderLines();
if (headerLines != null) {
mHeaderRegexps = new RE[headerLines.length];
for (int i = 0; i < headerLines.length; i++) {
try {
// TODO: Not sure if chache in Utils is still necessary
mHeaderRegexps[i] = Utils.getRE(headerLines[i]);
}
catch (RESyntaxException ex) {
throw new ConversionException(
"line " + i + " in header file is not a regexp");
}
}
}
}
/** @see HeaderCheck */
protected boolean isMatch(int lineNumber)
{
final String[] lines = getLines();
return mHeaderRegexps[lineNumber].match(lines[lineNumber]);
}
}

View File

@ -0,0 +1,43 @@
package com.puppycrawl.tools.checkstyle;
import com.puppycrawl.tools.checkstyle.checks.HeaderCheck;
import com.puppycrawl.tools.checkstyle.checks.RegexpHeaderCheck;
public class HeaderCheckTest extends BaseCheckTestCase
{
public HeaderCheckTest(String aName)
{
super(aName);
}
public void testStaticHeader()
throws Exception
{
final CheckConfiguration checkConfig = new CheckConfiguration();
checkConfig.setClassname(HeaderCheck.class.getName());
checkConfig.addProperty("headerFile", getPath("java.header"));
final Checker c = createChecker(checkConfig);
final String fname = getPath("inputHeader.java");
final String[] expected = {
"1:1: Missing a header - not enough lines in file."
};
verify(c, fname, expected);
}
public void testRegexpHeader()
throws Exception
{
final CheckConfiguration checkConfig = new CheckConfiguration();
checkConfig.setClassname(RegexpHeaderCheck.class.getName());
checkConfig.addProperty("headerFile", getPath("regexp.header"));
checkConfig.addProperty("ignoreLines", "4,5");
final Checker c = createChecker(checkConfig);
final String fname = getPath("InputScopeAnonInner.java");
final String[] expected = {
"3:1: Line does not match expected header line of '// Created: 2002'."
};
verify(c, fname, expected);
}
}