Simplified the code by removing HeaderInfo classes, they were introduced to avoid code duplication between header checks in two separate inheritance trees (Java Check vs. FileSetCheck). Now that we have only FileSetChecks as Header checks, this delegation is no longer necessary.
This commit is contained in:
parent
9cff1673f1
commit
b83c9aceef
|
|
@ -18,21 +18,30 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.checks.header;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
|
||||
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
|
||||
import org.apache.commons.beanutils.ConversionException;
|
||||
|
||||
/**
|
||||
* Abstract super class for header checks.
|
||||
* Provides support for headerFile property.
|
||||
* Provides support for header and headerFile properties.
|
||||
* @author o_sukhosolsky
|
||||
*/
|
||||
public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
|
||||
{
|
||||
/** information about the expected header file. */
|
||||
private HeaderInfo mHeaderInfo = createHeaderInfo();
|
||||
/** the lines of the header file. */
|
||||
private final List<String> mHeaderLines = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* Return the header lines to check against.
|
||||
|
|
@ -40,25 +49,7 @@ public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
|
|||
*/
|
||||
protected List<String> getHeaderLines()
|
||||
{
|
||||
return mHeaderInfo.getHeaderLines();
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract factory method to create an unconfigured
|
||||
* header info bean. Note that the actual type of the
|
||||
* return value can be subclass specific.
|
||||
*
|
||||
* @return a header info bean for this check.
|
||||
*/
|
||||
protected abstract HeaderInfo createHeaderInfo();
|
||||
|
||||
/**
|
||||
* Return the header info to check against.
|
||||
* @return the header info to check against.
|
||||
*/
|
||||
protected HeaderInfo getHeaderInfo()
|
||||
{
|
||||
return mHeaderInfo;
|
||||
return Collections.unmodifiableList(mHeaderLines);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,7 +60,47 @@ public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
|
|||
public void setHeaderFile(String aFileName)
|
||||
throws ConversionException
|
||||
{
|
||||
mHeaderInfo.setHeaderFile(aFileName);
|
||||
// Handle empty param
|
||||
if ((aFileName == null) || (aFileName.trim().length() == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadHeaderFile(aFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the header from a file.
|
||||
* @param aFileName the file to load
|
||||
* @throws ConversionException if the file cannot be loaded
|
||||
*/
|
||||
private void loadHeaderFile(String aFileName)
|
||||
{
|
||||
checkHeaderNotInitialized();
|
||||
Reader headerReader = null;
|
||||
try {
|
||||
headerReader = new FileReader(aFileName);
|
||||
loadHeader(headerReader);
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
throw new ConversionException(
|
||||
"unable to load header file " + aFileName, ex);
|
||||
}
|
||||
finally {
|
||||
Utils.closeQuietly(headerReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before initializing the header.
|
||||
* @throws ConversionException if header has already been set
|
||||
*/
|
||||
private void checkHeaderNotInitialized()
|
||||
{
|
||||
if (!mHeaderLines.isEmpty()) {
|
||||
throw new ConversionException(
|
||||
"header has already been set - "
|
||||
+ "set either header or headerFile, not both");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,13 +111,57 @@ public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
|
|||
*/
|
||||
public void setHeader(String aHeader)
|
||||
{
|
||||
mHeaderInfo.setHeader(aHeader);
|
||||
if ((aHeader == null) || (aHeader.trim().length() == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkHeaderNotInitialized();
|
||||
|
||||
final String headerExpandedNewLines = aHeader.replaceAll("\\\\n", "\n");
|
||||
|
||||
final Reader headerReader = new StringReader(headerExpandedNewLines);
|
||||
try {
|
||||
loadHeader(headerReader);
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
throw new ConversionException("unable to load header", ex);
|
||||
}
|
||||
finally {
|
||||
Utils.closeQuietly(headerReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load header to check against from a Reader into mHeaderLines.
|
||||
* @param aHeaderReader delivers the header to check against
|
||||
* @throws IOException if
|
||||
*/
|
||||
private void loadHeader(final Reader aHeaderReader) throws IOException
|
||||
{
|
||||
final LineNumberReader lnr = new LineNumberReader(aHeaderReader);
|
||||
mHeaderLines.clear();
|
||||
while (true) {
|
||||
final String l = lnr.readLine();
|
||||
if (l == null) {
|
||||
break;
|
||||
}
|
||||
mHeaderLines.add(l);
|
||||
}
|
||||
postprocessHeaderLines();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook method for post processing header lines.
|
||||
* This implementation does nothing.
|
||||
*/
|
||||
protected void postprocessHeaderLines()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void finishLocalSetup() throws CheckstyleException
|
||||
{
|
||||
if (mHeaderInfo.getHeaderLines().isEmpty()) {
|
||||
if (mHeaderLines.isEmpty()) {
|
||||
throw new CheckstyleException(
|
||||
"property 'headerFile' is missing or invalid in module "
|
||||
+ getConfiguration().getName());
|
||||
|
|
|
|||
|
|
@ -88,10 +88,4 @@ public class HeaderCheck extends AbstractHeaderCheck
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HeaderInfo createHeaderInfo()
|
||||
{
|
||||
return new HeaderInfo();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,156 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2008 Oliver Burn
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package com.puppycrawl.tools.checkstyle.checks.header;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.apache.commons.beanutils.ConversionException;
|
||||
|
||||
/**
|
||||
* Java Bean that holds header lines.
|
||||
*
|
||||
* @author lkuehne
|
||||
* @author o_sukhodolsky
|
||||
*/
|
||||
class HeaderInfo
|
||||
{
|
||||
/** the lines of the header file. */
|
||||
private final List<String> mHeaderLines = Lists.newArrayList();
|
||||
|
||||
/** Creates a new instance, without any header lines. */
|
||||
HeaderInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the header lines to check against.
|
||||
* @return the header lines to check against.
|
||||
*/
|
||||
final List<String> getHeaderLines()
|
||||
{
|
||||
return Collections.unmodifiableList(mHeaderLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the header file to check against.
|
||||
* @param aFileName the file that contains the header to check against.
|
||||
* @throws ConversionException if the file cannot be loaded
|
||||
*/
|
||||
final void setHeaderFile(String aFileName)
|
||||
throws ConversionException
|
||||
{
|
||||
// Handle empty param
|
||||
if ((aFileName == null) || (aFileName.trim().length() == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkHeaderNotInitialized();
|
||||
|
||||
// load the file
|
||||
Reader headerReader = null;
|
||||
try {
|
||||
headerReader = new FileReader(aFileName);
|
||||
loadHeader(headerReader);
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
throw new ConversionException(
|
||||
"unable to load header file " + aFileName, ex);
|
||||
}
|
||||
finally {
|
||||
Utils.closeQuietly(headerReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the header to check against. Individual lines in the header
|
||||
* must be separated by '\n' characters.
|
||||
* @param aHeader header content to check against.
|
||||
* @throws ConversionException if the header cannot be interpreted
|
||||
*/
|
||||
final void setHeader(String aHeader)
|
||||
{
|
||||
if ((aHeader == null) || (aHeader.trim().length() == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkHeaderNotInitialized();
|
||||
|
||||
final String headerExpandedNewLines = aHeader.replaceAll("\\\\n", "\n");
|
||||
|
||||
final Reader headerReader = new StringReader(headerExpandedNewLines);
|
||||
try {
|
||||
loadHeader(headerReader);
|
||||
}
|
||||
catch (final IOException ex) {
|
||||
throw new ConversionException("unable to load header", ex);
|
||||
}
|
||||
finally {
|
||||
Utils.closeQuietly(headerReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before initializing the header.
|
||||
* @throws ConversionException if header has already been set
|
||||
*/
|
||||
private void checkHeaderNotInitialized()
|
||||
{
|
||||
if (!mHeaderLines.isEmpty()) {
|
||||
throw new ConversionException(
|
||||
"header has already been set - "
|
||||
+ "set either header or headerFile, not both");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load header to check against from a Reader into mHeaderLines.
|
||||
* @param aHeaderReader delivers the header to check against
|
||||
* @throws IOException if
|
||||
*/
|
||||
private void loadHeader(final Reader aHeaderReader) throws IOException
|
||||
{
|
||||
final LineNumberReader lnr = new LineNumberReader(aHeaderReader);
|
||||
mHeaderLines.clear();
|
||||
while (true) {
|
||||
final String l = lnr.readLine();
|
||||
if (l == null) {
|
||||
break;
|
||||
}
|
||||
mHeaderLines.add(l);
|
||||
}
|
||||
postprocessHeaderLines();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook method for post processing header lines.
|
||||
* This implementation does nothing.
|
||||
*/
|
||||
protected void postprocessHeaderLines()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -23,6 +23,13 @@ import java.util.Arrays;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import org.apache.commons.beanutils.ConversionException;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
|
||||
/**
|
||||
* Checks the header of the source against a header file that contains a
|
||||
|
|
@ -34,15 +41,14 @@ import java.util.List;
|
|||
*/
|
||||
public class RegexpHeaderCheck extends AbstractHeaderCheck
|
||||
{
|
||||
/**
|
||||
* Provides typesafe access to the subclass specific HeaderInfo.
|
||||
*
|
||||
* @return the result of {@link #createHeaderInfo()}
|
||||
*/
|
||||
protected RegexpHeaderInfo getRegexpHeaderInfo()
|
||||
{
|
||||
return (RegexpHeaderInfo) getHeaderInfo();
|
||||
}
|
||||
/** empty array to avoid instantiations. */
|
||||
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||
|
||||
/** the compiled regular expressions */
|
||||
private final List<Pattern> mHeaderRegexps = Lists.newArrayList();
|
||||
|
||||
/** the header lines to repeat (0 or more) in the check, sorted. */
|
||||
private int[] mMultiLines = EMPTY_INT_ARRAY;
|
||||
|
||||
/**
|
||||
* Set the lines numbers to repeat in the header check.
|
||||
|
|
@ -50,17 +56,23 @@ public class RegexpHeaderCheck extends AbstractHeaderCheck
|
|||
*/
|
||||
public void setMultiLines(int[] aList)
|
||||
{
|
||||
getRegexpHeaderInfo().setMultiLines(aList);
|
||||
if ((aList == null) || (aList.length == 0)) {
|
||||
mMultiLines = EMPTY_INT_ARRAY;
|
||||
return;
|
||||
}
|
||||
|
||||
mMultiLines = new int[aList.length];
|
||||
System.arraycopy(aList, 0, mMultiLines, 0, aList.length);
|
||||
Arrays.sort(mMultiLines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processFiltered(File aFile, List<String> aLines)
|
||||
{
|
||||
final int headerSize = getRegexpHeaderInfo().getHeaderLines().size();
|
||||
final int headerSize = getHeaderLines().size();
|
||||
final int fileSize = aLines.size();
|
||||
|
||||
if (headerSize - getRegexpHeaderInfo().getMultLines().length > fileSize)
|
||||
{
|
||||
if (headerSize - mMultiLines.length > fileSize) {
|
||||
log(1, "header.missing");
|
||||
}
|
||||
else {
|
||||
|
|
@ -96,12 +108,6 @@ public class RegexpHeaderCheck extends AbstractHeaderCheck
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HeaderInfo createHeaderInfo()
|
||||
{
|
||||
return new RegexpHeaderInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a code line matches the required header line.
|
||||
* @param aLine the code line
|
||||
|
|
@ -110,8 +116,7 @@ public class RegexpHeaderCheck extends AbstractHeaderCheck
|
|||
*/
|
||||
private boolean isMatch(String aLine, int aHeaderLineNo)
|
||||
{
|
||||
return getRegexpHeaderInfo().getHeaderRegexps().get(aHeaderLineNo)
|
||||
.matcher(aLine).find();
|
||||
return mHeaderRegexps.get(aHeaderLineNo).matcher(aLine).find();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -120,7 +125,26 @@ public class RegexpHeaderCheck extends AbstractHeaderCheck
|
|||
*/
|
||||
private boolean isMultiLine(int aLineNo)
|
||||
{
|
||||
return (Arrays.binarySearch(getRegexpHeaderInfo().getMultLines(),
|
||||
aLineNo + 1) >= 0);
|
||||
return (Arrays.binarySearch(mMultiLines, aLineNo + 1) >= 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postprocessHeaderLines()
|
||||
{
|
||||
final List<String> headerLines = getHeaderLines();
|
||||
mHeaderRegexps.clear();
|
||||
for (String line : headerLines) {
|
||||
try {
|
||||
// TODO: Not sure if cache in Utils is still necessary
|
||||
mHeaderRegexps.add(Utils.getPattern(line));
|
||||
}
|
||||
catch (final PatternSyntaxException ex) {
|
||||
throw new ConversionException("line "
|
||||
+ (mHeaderRegexps.size() + 1)
|
||||
+ " in header specification"
|
||||
+ " is not a regular expression");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2008 Oliver Burn
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package com.puppycrawl.tools.checkstyle.checks.header;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.puppycrawl.tools.checkstyle.api.Utils;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import org.apache.commons.beanutils.ConversionException;
|
||||
|
||||
/**
|
||||
* Header info for regexp based checks,
|
||||
* adds the multilines property and holds the compiled regexps.
|
||||
*
|
||||
* @author lkuehne
|
||||
*/
|
||||
final class RegexpHeaderInfo extends HeaderInfo
|
||||
{
|
||||
/** empty array to avoid instantiations. */
|
||||
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||
|
||||
/** the compiled regular expressions */
|
||||
private final List<Pattern> mHeaderRegexps = Lists.newArrayList();
|
||||
|
||||
/** the header lines to repeat (0 or more) in the check, sorted. */
|
||||
private int[] mMultiLines = EMPTY_INT_ARRAY;
|
||||
|
||||
/**
|
||||
* Set the lines numbers to repeat in the header check.
|
||||
* @param aList comma separated list of line numbers to repeat in header.
|
||||
*/
|
||||
void setMultiLines(int[] aList)
|
||||
{
|
||||
if ((aList == null) || (aList.length == 0)) {
|
||||
mMultiLines = EMPTY_INT_ARRAY;
|
||||
return;
|
||||
}
|
||||
|
||||
mMultiLines = new int[aList.length];
|
||||
System.arraycopy(aList, 0, mMultiLines, 0, aList.length);
|
||||
Arrays.sort(mMultiLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lines numbers to repeat in the header check.
|
||||
* @return line numbers to repeat in header.
|
||||
*/
|
||||
int[] getMultLines()
|
||||
{
|
||||
return mMultiLines;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the compiled regexps from {@link #getHeaderLines()}.
|
||||
*
|
||||
* @return a list of non-null patterns,
|
||||
* same length as the result of {@link #getHeaderLines()}.
|
||||
*/
|
||||
List<Pattern> getHeaderRegexps()
|
||||
{
|
||||
return Collections.unmodifiableList(mHeaderRegexps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postprocessHeaderLines()
|
||||
{
|
||||
final List<String> headerLines = getHeaderLines();
|
||||
mHeaderRegexps.clear();
|
||||
for (String line : headerLines) {
|
||||
try {
|
||||
// TODO: Not sure if cache in Utils is still necessary
|
||||
mHeaderRegexps.add(Utils.getPattern(line));
|
||||
}
|
||||
catch (final PatternSyntaxException ex) {
|
||||
throw new ConversionException("line "
|
||||
+ (mHeaderRegexps.size() + 1)
|
||||
+ " in header specification"
|
||||
+ " is not a regular expression");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue