Issue #2866: added before execution and exclusion file filters

This commit is contained in:
rnveach 2016-07-31 10:36:59 -04:00 committed by Roman Ivanov
parent e163d24909
commit fbaabe83cf
19 changed files with 775 additions and 3 deletions

View File

@ -18,6 +18,9 @@
<property name="fileExtensions" value="java, properties, xml, g, g4"/>
<!-- BeforeExecutionFileFilters -->
<module name="BeforeExecutionExclusionFileFilter" />
<!-- Filters -->
<module name="SeverityMatchFilter">
<!-- report all violations except ignore -->

View File

@ -43,6 +43,12 @@
<property name="violationSuppressXPath" value="//MethodDeclaration[@Name='isNotRelevantSituation' and ../../..[@Image='WhitespaceAroundCheck']] | //MethodDeclaration[@Name='validateCli' and ../../..[@Image='Main']] | //ClassOrInterfaceDeclaration[@Image='JavadocMethodCheck' or @Image='JavadocStyleCheck']"/>
</properties>
</rule>
<rule ref="rulesets/java/codesize.xml/TooManyFields">
<properties>
<!-- Unable to split fields out of class. -->
<property name="violationSuppressXPath" value="//ClassOrInterfaceDeclaration[@Image='Checker']"/>
</properties>
</rule>
<rule ref="rulesets/java/codesize.xml/TooManyMethods">
<properties>
<property name="maxmethods" value="20"/>

View File

@ -37,6 +37,8 @@ import org.apache.commons.logging.LogFactory;
import com.puppycrawl.tools.checkstyle.api.AuditEvent;
import com.puppycrawl.tools.checkstyle.api.AuditListener;
import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilter;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilterSet;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.Context;
@ -72,6 +74,10 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
/** Vector of fileset checks. */
private final List<FileSetCheck> fileSetChecks = new ArrayList<>();
/** The audit event before execution file filters. */
private final BeforeExecutionFileFilterSet beforeExecutionFileFilters =
new BeforeExecutionFileFilterSet();
/** The audit event filters. */
private final FilterSet filters = new FilterSet();
@ -136,6 +142,14 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
cache.load();
}
/**
* Removes before execution file filter.
* @param filter before execution file filter to remove.
*/
public void removeBeforeExecutionFileFilter(BeforeExecutionFileFilter filter) {
beforeExecutionFileFilters.removeBeforeExecutionFileFilter(filter);
}
/**
* Removes filter.
* @param filter filter to remove.
@ -147,6 +161,7 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
/** Cleans up the object. **/
public void destroy() {
listeners.clear();
beforeExecutionFileFilters.clear();
filters.clear();
if (cache != null) {
try {
@ -259,7 +274,8 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
final String fileName = file.getAbsolutePath();
final long timestamp = file.lastModified();
if (cache != null && cache.isInCache(fileName, timestamp)
|| !CommonUtils.matchesFileExtension(file, fileExtensions)) {
|| !CommonUtils.matchesFileExtension(file, fileExtensions)
|| !acceptFileStarted(fileName)) {
continue;
}
fireFileStarted(fileName);
@ -307,6 +323,18 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
return fileMessages;
}
/**
* Check if all before execution file filters accept starting the file.
*
* @param fileName
* the file to be audited
* @return {@code true} if the file is accepted.
*/
private boolean acceptFileStarted(String fileName) {
final String stripped = CommonUtils.relativizeAndNormalizePath(basedir, fileName);
return beforeExecutionFileFilters.accept(stripped);
}
/**
* Notify all listeners about the beginning of a file audit.
*
@ -408,6 +436,10 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
fsc.init();
addFileSetCheck(fsc);
}
else if (child instanceof BeforeExecutionFileFilter) {
final BeforeExecutionFileFilter filter = (BeforeExecutionFileFilter) child;
addBeforeExecutionFileFilter(filter);
}
else if (child instanceof Filter) {
final Filter filter = (Filter) child;
addFilter(filter);
@ -432,6 +464,14 @@ public class Checker extends AutomaticBean implements MessageDispatcher {
fileSetChecks.add(fileSetCheck);
}
/**
* Adds a before execution file filter to the end of the event chain.
* @param filter the additional filter
*/
public void addBeforeExecutionFileFilter(BeforeExecutionFileFilter filter) {
beforeExecutionFileFilters.addBeforeExecutionFileFilter(filter);
}
/**
* Adds a filter to the end of the audit event filter chain.
* @param filter the additional filter

View File

@ -0,0 +1,33 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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.api;
/**
* An interface for before execution file filtering events.
* @author Richard Veach
*/
public interface BeforeExecutionFileFilter {
/**
* Determines whether or not a before execution file filtered event is accepted.
* @param uri the uri to filter.
* @return true if the event is accepted.
*/
boolean accept(String uri);
}

View File

@ -0,0 +1,82 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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.api;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* A before execution file filter set applies filters to events.
* If a before execution file filter in the set rejects an event, then the
* event is rejected. Otherwise, the event is accepted.
* @author Richard Veach
*/
public final class BeforeExecutionFileFilterSet
implements BeforeExecutionFileFilter {
/** Filter set. */
private final Set<BeforeExecutionFileFilter> beforeExecutionFileFilters = new HashSet<>();
/**
* Adds a Filter to the set.
* @param filter the Filter to add.
*/
public void addBeforeExecutionFileFilter(BeforeExecutionFileFilter filter) {
beforeExecutionFileFilters.add(filter);
}
/**
* Removes filter.
* @param filter filter to remove.
*/
public void removeBeforeExecutionFileFilter(BeforeExecutionFileFilter filter) {
beforeExecutionFileFilters.remove(filter);
}
/**
* Returns the Filters of the filter set.
* @return the Filters of the filter set.
*/
public Set<BeforeExecutionFileFilter> getBeforeExecutionFileFilters() {
return Collections.unmodifiableSet(beforeExecutionFileFilters);
}
@Override
public String toString() {
return beforeExecutionFileFilters.toString();
}
@Override
public boolean accept(String uri) {
boolean result = true;
for (BeforeExecutionFileFilter filter : beforeExecutionFileFilters) {
if (!filter.accept(uri)) {
result = false;
break;
}
}
return result;
}
/** Clears the BeforeExecutionFileFilterSet. */
public void clear() {
beforeExecutionFileFilters.clear();
}
}

View File

@ -0,0 +1,92 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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.filefilters;
import java.util.regex.Pattern;
import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilter;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
/**
* <p>
* File filter <code>BeforeExecutionExclusionFileFilter</code> decides which files should be
* excluded from being processed by the utility.
* </p>
*
* <p>
* By default Checkstyle includes all files and sub-directories in a directory to be processed and
* checked for violations. Users could have files that are in these sub-directories that shouldn't
* be processed with their checkstyle configuration for various reasons, one of which is a valid
* Java file that won't pass Checkstyle's parser. When Checkstyle tries to parse a Java file and
* fails, it will throw an <code>Exception</code> and halt parsing any more files for violations.
* An example of a valid Java file Checkstyle can't parse is JDK 9's <code>module-info.java</code>.
* This file filter will exclude these problem files from being parsed, allowing the rest of the
* files to run normal and be validated.
* </p>
*
* <p>
* <b>Note:</b> When a file is excluded from the utility, it is excluded from all Checks and no
* testing for violations will be performed on them.
* </p>
*
* <p>
* Check have following options:
* </p>
* <ul>
* <li>
* fileNamePattern - Regular expression to match the file name against. Default value is null.</li>
* </ul>
* <br>
*
* <p>
* To configure the filter to exclude all 'module-info.java' files:
* </p>
*
* <pre>
* &lt;module name=&quot;BeforeExecutionExclusionFileFilter&quot;&gt;
* &lt;property name=&quot;fileNamePattern&quot; value=&quot;module\-info\.java$&quot;/&gt;
* &lt;/module&gt;
* </pre>
*
* @author Richard Veach
*/
public final class BeforeExecutionExclusionFileFilter extends AutomaticBean
implements BeforeExecutionFileFilter {
/** Filename of exclusion. */
private Pattern fileNamePattern;
/**
* Sets regular expression of the file to exclude.
*
* @param fileNamePattern regular expression of the excluded file.
* @throws org.apache.commons.beanutils.ConversionException if unable to
* create Pattern object.
*/
public void setFileNamePattern(String fileNamePattern) {
this.fileNamePattern = CommonUtils.createPattern(fileNamePattern);
}
@Override
public boolean accept(String uri) {
return fileNamePattern == null || !fileNamePattern.matcher(uri).find();
}
}

View File

@ -0,0 +1,23 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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
////////////////////////////////////////////////////////////////////////////////
/**
* Contains the before execution file filters that are bundled with the main distribution.
*/
package com.puppycrawl.tools.checkstyle.filefilters;

View File

@ -22,6 +22,7 @@
<package name="sizes"/>
<package name="whitespace"/>
</package>
<package name="filefilters"/>
<package name="filters"/>
</package>
</checkstyle-packages>

View File

@ -60,6 +60,7 @@
<item name="Configuration" href="config.html">
<item name="Property Types" href="property_types.html"/>
<item name="Filters" href="config_filters.html"/>
<item name="File Filters" href="config_filefilters.html"/>
</item>
<item name="Running" href="running.html">
@ -95,6 +96,7 @@
<item name="Writing Checks" href="writingchecks.html"/>
<item name="Writing Javadoc Checks" href="writingjavadocchecks.html"/>
<item name="Writing Filters" href="writingfilters.html"/>
<item name="Writing File Filters" href="writingfilefilters.html"/>
<item name="Writing Listeners" href="writinglisteners.html"/>
</item>
<item name="Contributing" href="contributing.html"/>

View File

@ -65,6 +65,14 @@ public class CheckerTest extends BaseCheckTestSupport {
@Rule
public final TemporaryFolder temporaryFolder = new TemporaryFolder();
private static Method getAcceptFileStarted() throws NoSuchMethodException {
final Class<Checker> checkerClass = Checker.class;
final Method acceptFileStarted = checkerClass.getDeclaredMethod("acceptFileStarted",
String.class);
acceptFileStarted.setAccessible(true);
return acceptFileStarted;
}
private static Method getFireAuditFinished() throws NoSuchMethodException {
final Class<Checker> checkerClass = Checker.class;
final Method fireAuditFinished = checkerClass.getDeclaredMethod("fireAuditFinished");
@ -178,6 +186,33 @@ public class CheckerTest extends BaseCheckTestSupport {
}
@Test
public void testAddBeforeExecutionFileFilter() throws Exception {
final Checker checker = new Checker();
final TestBeforeExecutionFileFilter filter = new TestBeforeExecutionFileFilter();
checker.addBeforeExecutionFileFilter(filter);
filter.resetFilter();
getAcceptFileStarted().invoke(checker, "Test.java");
assertTrue("Checker.acceptFileStarted() doesn't call filter", filter.wasCalled());
}
@Test
public void testRemoveBeforeExecutionFileFilter() throws Exception {
final Checker checker = new Checker();
final TestBeforeExecutionFileFilter filter = new TestBeforeExecutionFileFilter();
final TestBeforeExecutionFileFilter f2 = new TestBeforeExecutionFileFilter();
checker.addBeforeExecutionFileFilter(filter);
checker.addBeforeExecutionFileFilter(f2);
checker.removeBeforeExecutionFileFilter(filter);
f2.resetFilter();
getAcceptFileStarted().invoke(checker, "Test.java");
assertTrue("Checker.acceptFileStarted() doesn't call filter", f2.wasCalled());
assertFalse("Checker.acceptFileStarted() does call removed filter", filter.wasCalled());
}
@Test
public void testAddFilter() {
final Checker checker = new Checker();

View File

@ -79,8 +79,8 @@ public class PackageNamesLoaderTest {
"com.puppycrawl.tools.checkstyle.checks.regexp.",
"com.puppycrawl.tools.checkstyle.checks.sizes.",
"com.puppycrawl.tools.checkstyle.checks.whitespace.",
"com.puppycrawl.tools.checkstyle.filefilters.",
"com.puppycrawl.tools.checkstyle.filters.",
};
assertEquals("pkgNames.length.", checkstylePackages.length,

View File

@ -0,0 +1,40 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilter;
class TestBeforeExecutionFileFilter implements BeforeExecutionFileFilter {
private boolean called;
@Override
public boolean accept(String uri) {
called = true;
return true;
}
public boolean wasCalled() {
return called;
}
public void resetFilter() {
called = false;
}
}

View File

@ -0,0 +1,92 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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.filefilters;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
public class ExclusionBeforeExecutionFileFilterTest extends BaseCheckTestSupport {
@Test
public void testAccept() {
final String fileName = "BAD";
final BeforeExecutionExclusionFileFilter filter =
createExclusionBeforeExecutionFileFilter(fileName);
assertTrue(filter.accept("ATest.java"));
}
@Test
public void testAcceptOnNullFile() {
final String fileName = null;
final BeforeExecutionExclusionFileFilter filter =
createExclusionBeforeExecutionFileFilter(fileName);
assertTrue(filter.accept("AnyJava.java"));
}
@Test
public void testReject() {
final String fileName = "Test";
final BeforeExecutionExclusionFileFilter filter =
createExclusionBeforeExecutionFileFilter(fileName);
assertFalse(filter.accept("ATest.java"));
}
@Test
public void testRejectBadFile() throws Exception {
final DefaultConfiguration filterConfig =
createBeforeExecutionFileFilterConfig(BeforeExecutionExclusionFileFilter.class);
filterConfig.addAttribute("fileNamePattern", "IncorrectClass\\.java");
final String[] violations = CommonUtils.EMPTY_STRING_ARRAY;
verify(createChecker(filterConfig), getNonCompilablePath("InputIncorrectClass.java"),
violations);
}
private static BeforeExecutionExclusionFileFilter
createExclusionBeforeExecutionFileFilter(String fileName) {
final BeforeExecutionExclusionFileFilter exclusionBeforeExecutionFileFilter =
new BeforeExecutionExclusionFileFilter();
if (fileName != null) {
exclusionBeforeExecutionFileFilter.setFileNamePattern(fileName);
}
return exclusionBeforeExecutionFileFilter;
}
private static DefaultConfiguration createBeforeExecutionFileFilterConfig(Class<?> aClass) {
return new DefaultConfiguration(aClass.getName());
}
@Override
protected DefaultConfiguration createCheckerConfig(Configuration config) {
final DefaultConfiguration dc =
new DefaultConfiguration("configuration");
dc.addChild(config);
return dc;
}
}

View File

@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// 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.filters;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilterSet;
import com.puppycrawl.tools.checkstyle.filefilters.BeforeExecutionExclusionFileFilter;
public class BeforeExecutionFileFilterSetTest {
@Test
public void testAccept() {
final String fileName = "BAD";
final BeforeExecutionExclusionFileFilter filter = new BeforeExecutionExclusionFileFilter();
filter.setFileNamePattern(fileName);
final BeforeExecutionFileFilterSet set = new BeforeExecutionFileFilterSet();
set.addBeforeExecutionFileFilter(filter);
assertTrue(set.accept("ATest.java"));
}
@Test
public void testReject() {
final String fileName = "Test";
final BeforeExecutionExclusionFileFilter filter = new BeforeExecutionExclusionFileFilter();
filter.setFileNamePattern(fileName);
final BeforeExecutionFileFilterSet set = new BeforeExecutionFileFilterSet();
set.addBeforeExecutionFileFilter(filter);
assertFalse(set.accept("ATest.java"));
}
@Test
public void testGetFilters2() {
final BeforeExecutionFileFilterSet filterSet = new BeforeExecutionFileFilterSet();
filterSet.addBeforeExecutionFileFilter(new BeforeExecutionExclusionFileFilter());
assertEquals("size is the same", 1, filterSet.getBeforeExecutionFileFilters().size());
}
@Test
public void testToString2() {
final BeforeExecutionFileFilterSet filterSet = new BeforeExecutionFileFilterSet();
filterSet.addBeforeExecutionFileFilter(new BeforeExecutionExclusionFileFilter());
assertNotNull("size is the same", filterSet.toString());
}
}

View File

@ -41,6 +41,7 @@ import org.w3c.dom.NodeList;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilter;
import com.puppycrawl.tools.checkstyle.api.Filter;
import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpMultilineCheck;
import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck;
@ -184,7 +185,7 @@ public final class CheckUtil {
* Checks whether a class may be considered as the checkstyle module.
* Checkstyle's modules are nonabstract classes which names end with 'Check',
* do not contain the word 'Input' (are not input files for UTs),
* checkstyle's filters and SuppressWarningsHolder class.
* checkstyle's filters, checkstyle's file filters and SuppressWarningsHolder class.
* @param loadedClass class to check.
* @return true if the class may be considered as the checkstyle module.
*/
@ -192,6 +193,7 @@ public final class CheckUtil {
final String className = loadedClass.getSimpleName();
return isCheckstyleNonAbstractCheck(loadedClass, className)
|| isFilterModule(loadedClass, className)
|| isFileFilterModule(loadedClass, className)
|| "SuppressWarningsHolder".equals(className)
|| "FileContentsHolder".equals(className);
}
@ -210,6 +212,20 @@ public final class CheckUtil {
&& className.endsWith("Filter");
}
/**
* Checks whether a class may be considered as the checkstyle file filter.
* Checkstyle's file filters are classes which are subclasses of AutomaticBean,
* implement 'BeforeExecutionFileFilter' interface, and which names end with 'FileFilter'.
* @param loadedClass class to check.
* @param className class name to check.
* @return true if a class may be considered as the checkstyle file filter.
*/
private static boolean isFileFilterModule(Class<?> loadedClass, String className) {
return BeforeExecutionFileFilter.class.isAssignableFrom(loadedClass)
&& AutomaticBean.class.isAssignableFrom(loadedClass)
&& className.endsWith("FileFilter");
}
/**
* Get's the check's messages.
* @param module class to examine.

View File

@ -99,6 +99,7 @@ public class XDocsPagesTest {
"name=\"SuppressionCommentFilter\"",
"name=\"SuppressWithNearbyCommentFilter\"",
"name=\"SuppressWarningsFilter\"",
"name=\"BeforeExecutionExclusionFileFilter\"",
"name=\"RegexpHeader\"",
"name=\"RegexpOnFilename\"",
"name=\"RegexpSingleline\"",

View File

@ -659,6 +659,20 @@
</section>
<section name="Before Execution File Filters">
<p>
A Checker module has a Before Execution File Filter submodule to filter
files from being processed by the utility. A Before Execution File Filter
can accept or reject a file by its name. If all Before Execution File Filters
accept a file, then Checker will process and validate the file.
If any Before Execution File Filter rejects an file, then Checker skips over
the file and acts like it does not exist.
For more information, please visit the <a href="config_filefilters.xml">file filters page</a>.
</p>
</section>
<section name="AuditListeners">
<p>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
<head>
<title>Before Execution File Filters</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"/>
<script type="text/javascript" src="js/anchors.js"/>
<script type="text/javascript" src="js/google-analytics.js"/>
<link rel="icon" href="images/favicon.png" type="image/x-icon" />
<link rel="shortcut icon" href="images/favicon.ico" type="image/ico" />
</head>
<body>
<section name="Content">
<macro name="toc">
<param name="fromDepth" value="1"/>
<param name="toDepth" value="1"/>
</macro>
</section>
<section name="BeforeExecutionExclusionFileFilter">
<subsection name="Description">
<p>
File filter <code>BeforeExecutionExclusionFileFilter</code> decides which files should be
excluded from being processed by the utility.
</p>
<p>
By default Checkstyle includes all files and sub-directories in a directory to be
processed and checked for violations. Users could have files that are in these
sub-directories that shouldn't be processed with their checkstyle configuration for
various reasons, one of which is a valid Java file that won't pass Checkstyle's parser.
When Checkstyle tries to parse a Java file and fails, it will throw an
<code>Exception</code> and halt parsing any more files for violations. An example of a
valid Java file Checkstyle can't parse is JDK 9's <code>module-info.java</code>.
This file filter will exclude these problem files from being parsed,
allowing the rest of the files to run normal and be validated.
</p>
<p>
<b>Note:</b> When a file is excluded from the utility, it is excluded from all Checks and
no testing for violations will be performed on them.
</p>
</subsection>
<subsection name="Properties">
<table>
<tr>
<th>name</th>
<th>description</th>
<th>type</th>
<th>default value</th>
</tr>
<tr>
<td>fileNamePattern</td>
<td>Regular expression to match the file name against.</td>
<td><a href="property_types.html#regexp">regular expression</a></td>
<td><code>null</code></td>
</tr>
</table>
</subsection>
<subsection name="Examples">
<p>
To configure the filter to exclude all 'module-info.java' files:
</p>
<source>
&lt;module name=&quot;BeforeExecutionExclusionFileFilter&quot;&gt;
&lt;property name=&quot;fileNamePattern&quot; value=&quot;module\-info\.java$&quot;/&gt;
&lt;/module&gt;
</source>
</subsection>
<subsection name="Example of Usage">
<ul>
<li>
<a href="https://github.com/search?q=path%3Aconfig+filename%3Acheckstyle_checks.xml+repo%3Acheckstyle%2Fcheckstyle+BeforeExecutionExclusionFileFilter">
Checkstyle Style</a>
</li>
</ul>
</subsection>
<subsection name="Package">
<p> com.puppycrawl.tools.checkstyle.filefilters </p>
</subsection>
<subsection name="Parent Module">
<p> <a href="config.html#Checker">Checker</a> </p>
</subsection>
</section>
</body>
</document>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
<head>
<title>Writing Before Execution Filters</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"/>
<script type="text/javascript" src="js/anchors.js"/>
<script type="text/javascript" src="js/google-analytics.js"/>
<link rel="icon" href="images/favicon.png" type="image/x-icon" />
<link rel="shortcut icon" href="images/favicon.ico" type="image/ico" />
</head>
<body>
<section name="Content">
<macro name="toc">
<param name="fromDepth" value="1"/>
<param name="toDepth" value="1"/>
</macro>
</section>
<section name="Overview">
<p>
A <code>Checker</code> has a set of <code>BeforeExecutionFileFilter</code>s that decide which files the <code>Checker</code> processes. Interface
<code>BeforeExecutionFileFilter</code> and class <code>BeforeExecutionFileFilterSet</code> are intended to support general file uri filtering using a set of <code>BeforeExecutionFileFilter</code>s.
</p>
<p>
A <code>BeforeExecutionFileFilter</code> has <code>boolean</code> method <code>accept(String uri)</code> that returns <code>true</code> if the <code>BeforeExecutionFileFilter</code>
accepts the <code>file uri</code> parameter and returns
<code>false</code> if the <code>file uri</code> rejects it.
</p>
<p>
A <code>BeforeExecutionFileFilterSet</code> is a particular <code>BeforeExecutionFileFilter</code> that contains a set of <code>BeforeExecutionFileFilter</code>s. A <code>BeforeExecutionFileFilterSet</code>
accepts an <code>file uri</code> if and only if all
<code>BeforeExecutionFileFilter</code>s in the set accept the <code>file uri</code>.
</p>
</section>
<section name="Writing Before Execution File Filters">
<p>
The <code>BeforeExecutionFileFilter</code> that we demonstrate here rejects
file uris whose name matches a <a
href="property_types.html#regexp">regular expression</a>. In order to
enable the specification of the file name pattern as a property in a
configuration file, the <code>BeforeExecutionFileFilter</code> is an <a
href="apidocs/com/puppycrawl/tools/checkstyle/api/AutomaticBean.html">AutomaticBean</a>
with mutator method <code>setFiles(String)</code> that
receives the file name pattern. An <code>AutomaticBean</code> uses JavaBean introspection to set
JavaBean properties such as <code>files</code>.
</p>
<source>
package com.mycompany.filefilters;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.BeforeExecutionFileFilter;
import com.puppycrawl.tools.checkstyle.api.Utils;
public class FilesBeforeExecutionFileFilter
extends AutomaticBean
implements BeforeExecutionFileFilter
{
private Pattern mFileRegexp;
public FilesBeforeExecutionFileFilter()
throws PatternSyntaxException
{
setFiles("^$");
}
public boolean accept(String uri)
{
return ((uri == null) || !mFileRegexp.matcher(uri).find());
}
public void setFiles(String aFilesPattern)
throws PatternSyntaxException
{
mFileRegexp = Utils.getPattern(aFilesPattern);
}
}
</source>
</section>
<section name="Using Before Execution File Filters">
<p>
To incorporate a <code>BeforeExecutionFileFilter</code> in the before execution file filter set
for a <code>Checker</code>, include a module element for
the <code>BeforeExecutionFileFilter</code> in the <a
href="config.html#Before Execution File Filters">configuration file</a>. For example, to
configure a <code>Checker</code> so that it uses custom
filter <code>FilesBeforeExecutionFileFilter</code> to prevent processing
files whose name contains &quot;Generated&quot;,
include the following module in the configuration file:
</p>
<source>
&lt;module name=&quot;com.mycompany.filters.FilesBeforeExecutionFileFilter&quot;&gt;
&lt;property name=&quot;files&quot; value=&quot;Generated&quot;/&gt;
&lt;/module&gt;
</source>
</section>
<section name="Huh? I can&#39;t figure it out!">
<p>
That&#39;s probably our fault, and it means that we have to provide
better documentation. Please do not hesitate to ask questions on the
user mailing list, this will help us to improve this document. Please
ask your questions as precisely as possible. We will not be able to
answer questions like &quot;I want to write a filter but I don&#39;t
know how, can you help me?&quot;. Tell us what you are trying to do
(the purpose of the filter), what you have understood so far, and what
exactly you are getting stuck on.
</p>
</section>
<section name="Contributing">
<p>
We need <em>your</em> help to keep improving Checkstyle. Whenever you
write a before execution file filter that you think is generally useful,
please consider <a href="contributing.html">contributing</a> it to the Checkstyle
community and submit it for inclusion in the next release of
Checkstyle.
</p>
</section>
</body>
</document>