diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/AbstractHeaderCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/AbstractHeaderCheck.java index c5af41f19..f72292fb0 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/AbstractHeaderCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/AbstractHeaderCheck.java @@ -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 mHeaderLines = Lists.newArrayList(); /** * Return the header lines to check against. @@ -40,25 +49,7 @@ public abstract class AbstractHeaderCheck extends AbstractFileSetCheck */ protected List 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()); diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheck.java index ef8947b04..98b10e4f0 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheck.java @@ -88,10 +88,4 @@ public class HeaderCheck extends AbstractHeaderCheck } } } - - @Override - protected HeaderInfo createHeaderInfo() - { - return new HeaderInfo(); - } } diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderInfo.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderInfo.java deleted file mode 100644 index 8939955c4..000000000 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderInfo.java +++ /dev/null @@ -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 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 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() - { - } - -} diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderCheck.java index 0ca3404b7..4f596eefe 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderCheck.java @@ -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 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 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 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"); + } + } + } + } diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderInfo.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderInfo.java deleted file mode 100644 index bb62017b2..000000000 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderInfo.java +++ /dev/null @@ -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 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 getHeaderRegexps() - { - return Collections.unmodifiableList(mHeaderRegexps); - } - - @Override - protected void postprocessHeaderLines() - { - final List 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"); - } - } - } -}