Skip to content

Commit

Permalink
Issue checkstyle#5879: Suppression xpath single filter
Browse files Browse the repository at this point in the history
  • Loading branch information
tsunghanjacktsai committed Feb 1, 2019
1 parent c0e131d commit d9ff15e
Show file tree
Hide file tree
Showing 14 changed files with 968 additions and 39 deletions.
4 changes: 3 additions & 1 deletion .ci/jsoref-spellchecker/whitelist.words
Expand Up @@ -521,7 +521,7 @@ gzip
hadoop
hamcrest
Haml
Hardcoded
hardcoded
hashcode
hashset
hashtable
Expand Down Expand Up @@ -630,6 +630,7 @@ javadoctags
javadoctype
javadocvariable
Javaee
javaformat
javaguide
javall
javamail
Expand Down Expand Up @@ -1194,6 +1195,7 @@ suppressionfilter
suppressionsloader
suppressionsstringprinter
suppressionxpathfilter
suppressionxpathsinglefilter
suppresswarnings
suppresswarningsfilter
suppresswarningsholder
Expand Down
38 changes: 38 additions & 0 deletions config/checkstyle_checks.xml
Expand Up @@ -350,6 +350,44 @@
<module name="SuppressionXpathFilter">
<property name="file" value="${checkstyle.suppressions-xpath.file}"/>
</module>
<!-- Tone down the checking for test code -->
<module name="SuppressionXpathSingleFilter">
<property name="files" value="[\\/]internal[\\/].*[\\/]\w+Util\.java"/>
<property name="checks" value="IllegalCatch"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/]test[\\/]"/>
<property name="checks" value="EmptyBlock"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="JavadocVariable"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="JavadocType"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="MagicNumber"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="AvoidStaticImport"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="WriteTag"/>
</module>
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="MethodCount"/>
</module>
<!-- Fixing these cases will decrease code readability -->
<module name="SuppressionXpathSingleFilter">
<property name="files" value=".*[\\/]src[\\/](test|it)[\\/]"/>
<property name="checks" value="MultipleStringLiterals"/>
</module>
<module name="SuppressWithNearbyCommentFilter">
<property name="commentFormat"
value="-@cs\[(\w{8,}(\|\w{8,})*)\] \w[\(\)\-\.\'\`\,\:\;\w ]{10,}"/>
Expand Down
13 changes: 13 additions & 0 deletions config/pmd-test.xml
Expand Up @@ -193,4 +193,17 @@
</properties>
</rule>

<rule ref="category/java/design.xml/UseObjectForClearerAPI">
<properties>
<!-- This is checking for amount of arguments more that 3 (hardcoded).
But in make sense to start making violations on items where
amount of arguments more that 7. Extra abstraction(object)
for single method does not make code more readable or
easy to maintain -->
<property name="violationSuppressXPath"
value="//ClassOrInterfaceDeclaration[
@Image='SuppressionXpathSingleFilterTest']
//MethodDeclarator[@Image='createSuppressionXpathSingleFilter']"/>
</properties>
</rule>
</ruleset>
3 changes: 3 additions & 0 deletions config/spotbugs-exclude.xml
Expand Up @@ -78,6 +78,9 @@
<Class name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck" />
<!--Uses setters to set fields values-->
<Class name="com.puppycrawl.tools.checkstyle.api.AbstractCheck" />
<!-- We cannot modify fields since we won't have the values
to create the instance until the setters are called -->
<Class name="com.puppycrawl.tools.checkstyle.filters.SuppressionXpathSingleFilter"/>
</Or>
<Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" />
</Match>
Expand Down
10 changes: 0 additions & 10 deletions config/suppressions.xml
Expand Up @@ -28,12 +28,8 @@
<suppress checks="ExecutableStatementCount|JavaNCSS|BooleanExpressionComplexity|
|NestedIfDepth|MethodLength"
files="[\\/]XdocsPagesTest\.java"/>
<suppress checks="IllegalCatch" files="[\\/]internal[\\/].*[\\/]\w+Util\.java"/>
<suppress checks="EmptyBlock" files=".*[\\/]src[\\/]test[\\/]"/>

<suppress checks="JavadocPackage" files=".*[\\/]src[\\/](test|it)[\\/]"/>
<suppress checks="JavadocVariable" files=".*[\\/]src[\\/](test|it)[\\/]"/>
<suppress checks="JavadocType" files=".*[\\/]src[\\/](test|it)[\\/]"/>
<!-- we do not need javadocs in all classes except for *Support classes -->
<suppress checks="JavadocMethod" files=".*[\\/]src[\\/](test|it)[\\/].*(?&lt;!Support)\.java"/>
<!-- till https://github.com/checkstyle/checkstyle/issues/6336 -->
Expand All @@ -44,11 +40,6 @@
<suppress checks="JavadocMethod" files=".*AbstractPathTestSupport\.java"/>
<suppress checks="JavadocMethod" files=".*AbstractXmlTestSupport\.java"/>

<suppress checks="MagicNumber" files=".*[\\/]src[\\/](test|it)[\\/]"/>
<suppress checks="AvoidStaticImport" files=".*[\\/]src[\\/](test|it)[\\/]"/>
<suppress checks="WriteTag" files=".*[\\/]src[\\/](test|it)[\\/]"/>
<suppress checks="MethodCount" files=".*[\\/]src[\\/](test|it)[\\/]"/>

<!--The Check generates too many violations, fixing them will make code unmanageable.-->
<suppress checks="MagicNumber" files="(ParseTreeTablePresentation|MainFrame)\.java"/>

Expand All @@ -70,7 +61,6 @@

<!-- Fixing these cases will decrease code readability -->
<suppress checks="MultipleStringLiterals" files="JavadocStyleCheck\.java|XMLLogger\.java"/>
<suppress checks="MultipleStringLiterals" files=".*[\\/]src[\\/](test|it)[\\/]"/>

<!-- There are a lot of setters/getters in the Check.
A small number of methods is left for Check's logic -->
Expand Down
Expand Up @@ -843,6 +843,8 @@ private static void fillModulesFromFiltersPackage() {
BASE_PACKAGE + ".filters.SuppressionFilter");
NAME_TO_FULL_MODULE_NAME.put("SuppressionXpathFilter",
BASE_PACKAGE + ".filters.SuppressionXpathFilter");
NAME_TO_FULL_MODULE_NAME.put("SuppressionXpathSingleFilter",
BASE_PACKAGE + ".filters.SuppressionXpathSingleFilter");
NAME_TO_FULL_MODULE_NAME.put("SuppressWarningsFilter",
BASE_PACKAGE + ".filters.SuppressWarningsFilter");
NAME_TO_FULL_MODULE_NAME.put("SuppressWithNearbyCommentFilter",
Expand Down
Expand Up @@ -212,7 +212,8 @@
* </li>
* </ul>
* <p>
* Note: a <a href="config_filters.html#SuppressionFilter">suppression filter</a> is needed because
* Note: a <a href="config_filters.html#SuppressionXpathSingleFilter">
* suppression xpath single filter</a> is needed because
* IDEA has no blank line between "javax" and "java".
* ImportOrder has a limitation by design to enforce an empty line between groups ("java", "javax").
* There is no flexibility to enforce empty lines between some groups and no empty lines between
Expand All @@ -230,17 +231,10 @@
* &lt;property name=&quot;option&quot; value=&quot;bottom&quot;/&gt;
* &lt;property name=&quot;sortStaticImportsAlphabetically&quot; value=&quot;true&quot;/&gt;
* &lt;/module&gt;
* </pre>
* <pre>
* &lt;?xml version=&quot;1.0&quot;?&gt;
* &lt;!DOCTYPE suppressions PUBLIC
* &quot;-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN&quot;
* &quot;https://checkstyle.org/dtds/suppressions_1_2.dtd&quot;&gt;
*
* &lt;suppressions&gt;
* &lt;!-- message contains no message text to work well in multi-language environments --&gt;
* &lt;suppress checks=&quot;ImportOrder&quot; message=&quot;^'java\..*'.*&quot;/&gt;
* &lt;/suppressions&gt;
* &lt;module name="SuppressionXpathSingleFilter"&gt;
* &lt;property name="checks" value="ImportOrder"/&gt;
* &lt;property name="message" value="^'java\..*'.*"/&gt;
* &lt;/module&gt;
* </pre>
* <p>
* To configure the check so that it matches default NetBeans formatter configuration
Expand Down
@@ -0,0 +1,127 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2019 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 java.util.regex.Pattern;

import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent;
import com.puppycrawl.tools.checkstyle.TreeWalkerFilter;
import com.puppycrawl.tools.checkstyle.api.AutomaticBean;

/**
* Filter {@code SuppressionXpathSingleFilter} suppresses audit events for
* Checks violations in the specified file, class, checks, message, module id,
* and xpath.
* Attention: This filter only supports single suppression, and will need
* multiple instances if users wants to suppress multiple violations.
*/
public class SuppressionXpathSingleFilter extends AutomaticBean implements
TreeWalkerFilter {
/**
* XpathFilter instance.
*/
private XpathFilter xpathFilter;
/**
* The pattern for file names.
*/
private Pattern files;
/**
* The pattern for check class names.
*/
private Pattern checks;
/**
* The pattern for message names.
*/
private Pattern message;
/**
* Module id of filter.
*/
private String id;
/**
* Xpath query.
*/
private String query;

/**
* Set the regular expression to specify names of files to suppress.
* @param files the name of the file
*/
public void setFiles(String files) {
if (files == null) {
this.files = null;
}
else {
this.files = Pattern.compile(files);
}
}

/**
* Set the regular expression to specify the name of the check to suppress.
* @param checks the name of the check
*/
public void setChecks(String checks) {
if (checks == null) {
this.checks = null;
}
else {
this.checks = Pattern.compile(checks);
}
}

/**
* Set the regular expression to specify the message of the check to suppress.
* @param message the message of the check
*/
public void setMessage(String message) {
if (message == null) {
this.message = null;
}
else {
this.message = Pattern.compile(message);
}
}

/**
* Set the ID of the check to suppress.
* @param id the ID of the check
*/
public void setId(String id) {
this.id = id;
}

/**
* Set the xpath query.
* @param query the xpath query
*/
public void setQuery(String query) {
this.query = query;
}

@Override
protected void finishLocalSetup() {
xpathFilter = new XpathFilter(files, checks, message, id, query);
}

@Override
public boolean accept(TreeWalkerAuditEvent treeWalkerAuditEvent) {
return xpathFilter.accept(treeWalkerAuditEvent);
}

}
Expand Up @@ -111,7 +111,57 @@ public XpathFilter(String files, String checks,
xpathExpression = xpathEvaluator.createExpression(xpathQuery);
}
catch (XPathException ex) {
throw new IllegalStateException("Unexpected xpath query: " + xpathQuery, ex);
throw new IllegalArgumentException("Unexpected xpath query: " + xpathQuery, ex);
}
}
}

/**
* Creates a {@code XpathElement} instance.
* @param files regular expression for names of filtered files
* @param checks regular expression for filtered check classes
* @param message regular expression for messages.
* @param moduleId the module id
* @param query the xpath query
*/
public XpathFilter(Pattern files, Pattern checks, Pattern message,
String moduleId, String query) {
if (files == null) {
filePattern = null;
fileRegexp = null;
}
else {
filePattern = files.pattern();
fileRegexp = files;
}
if (checks == null) {
checkPattern = null;
checkRegexp = null;
}
else {
checkPattern = checks.pattern();
checkRegexp = checks;
}
if (message == null) {
messagePattern = null;
messageRegexp = null;
}
else {
messagePattern = message.pattern();
messageRegexp = message;
}
this.moduleId = moduleId;
xpathQuery = query;
if (xpathQuery == null) {
xpathExpression = null;
}
else {
final XPathEvaluator xpathEvaluator = new XPathEvaluator();
try {
xpathExpression = xpathEvaluator.createExpression(xpathQuery);
}
catch (XPathException ex) {
throw new IllegalArgumentException("Incorrect xpath query: " + xpathQuery, ex);
}
}
}
Expand Down

0 comments on commit d9ff15e

Please sign in to comment.