From b83c9aceef9577eaada5cfd78bc7b2cd04a176d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20K=C3=BChne?= Date: Thu, 5 Feb 2009 21:22:49 +0000 Subject: [PATCH] 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. --- .../checks/header/AbstractHeaderCheck.java | 125 +++++++++++--- .../checkstyle/checks/header/HeaderCheck.java | 6 - .../checkstyle/checks/header/HeaderInfo.java | 156 ------------------ .../checks/header/RegexpHeaderCheck.java | 70 +++++--- .../checks/header/RegexpHeaderInfo.java | 103 ------------ 5 files changed, 147 insertions(+), 313 deletions(-) delete mode 100644 src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/HeaderInfo.java delete mode 100644 src/checkstyle/com/puppycrawl/tools/checkstyle/checks/header/RegexpHeaderInfo.java 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"); - } - } - } -}