View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2018 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.filters;
21  
22  import java.util.Objects;
23  import java.util.regex.Pattern;
24  
25  import com.puppycrawl.tools.checkstyle.api.AuditEvent;
26  import com.puppycrawl.tools.checkstyle.api.Filter;
27  
28  /**
29   * This filter processes {@link AuditEvent}
30   * objects based on the criteria of file, check, module id, line, and
31   * column. It rejects an AuditEvent if the following match:
32   * <ul>
33   *   <li>the event's file name; and</li>
34   *   <li>the check name or the module identifier; and</li>
35   *   <li>(optionally) the event's line is in the filter's line CSV; and</li>
36   *   <li>(optionally) the check's columns is in the filter's column CSV.</li>
37   * </ul>
38   *
39   * @author Rick Giles
40   */
41  public class SuppressElement
42      implements Filter {
43  
44      /** The regexp to match file names against. */
45      private final Pattern fileRegexp;
46  
47      /** The pattern for file names. */
48      private final String filePattern;
49  
50      /** The regexp to match check names against. */
51      private final Pattern checkRegexp;
52  
53      /** The pattern for check class names. */
54      private final String checkPattern;
55  
56      /** The regexp to match message names against. */
57      private final Pattern messageRegexp;
58  
59      /** The pattern for message names. */
60      private final String messagePattern;
61  
62      /** Module id filter. */
63      private final String moduleId;
64  
65      /** Line number filter. */
66      private final CsvFilter lineFilter;
67  
68      /** CSV for line number filter. */
69      private final String linesCsv;
70  
71      /** Column number filter. */
72      private final CsvFilter columnFilter;
73  
74      /** CSV for column number filter. */
75      private final String columnsCsv;
76  
77      /**
78       * Constructs a {@code SuppressElement} for a
79       * file name pattern.
80       *
81       * @param files   regular expression for names of filtered files.
82       * @param checks  regular expression for filtered check classes.
83       * @param message regular expression for messages.
84       * @param modId   the id
85       * @param lines   lines CSV values and ranges for line number filtering.
86       * @param columns columns CSV values and ranges for column number filtering.
87       */
88      public SuppressElement(String files, String checks,
89                             String message, String modId, String lines, String columns) {
90          filePattern = files;
91          if (files == null) {
92              fileRegexp = null;
93          }
94          else {
95              fileRegexp = Pattern.compile(files);
96          }
97          checkPattern = checks;
98          if (checks == null) {
99              checkRegexp = null;
100         }
101         else {
102             checkRegexp = Pattern.compile(checks);
103         }
104         messagePattern = message;
105         if (message == null) {
106             messageRegexp = null;
107         }
108         else {
109             messageRegexp = Pattern.compile(message);
110         }
111         moduleId = modId;
112         linesCsv = lines;
113         if (lines == null) {
114             lineFilter = null;
115         }
116         else {
117             lineFilter = new CsvFilter(lines);
118         }
119         columnsCsv = columns;
120         if (columns == null) {
121             columnFilter = null;
122         }
123         else {
124             columnFilter = new CsvFilter(columns);
125         }
126     }
127 
128     @Override
129     public boolean accept(AuditEvent event) {
130         return isFileNameAndModuleNotMatching(event)
131                 || !isMessageNameMatching(event)
132                 || isLineAndColumnMatch(event);
133     }
134 
135     /**
136      * Is matching by file name and Check name.
137      * @param event event
138      * @return true is matching
139      */
140     private boolean isFileNameAndModuleNotMatching(AuditEvent event) {
141         return event.getFileName() == null
142                 || fileRegexp != null && !fileRegexp.matcher(event.getFileName()).find()
143                 || event.getLocalizedMessage() == null
144                 || moduleId != null && !moduleId.equals(event.getModuleId())
145                 || checkRegexp != null && !checkRegexp.matcher(event.getSourceName()).find();
146     }
147 
148     /**
149      * Is matching by message.
150      * @param event event
151      * @return true is matching or not set.
152      */
153     private boolean isMessageNameMatching(AuditEvent event) {
154         return messageRegexp == null || messageRegexp.matcher(event.getMessage()).find();
155     }
156 
157     /**
158      * Whether line and column match.
159      * @param event event to process.
160      * @return true if line and column match.
161      */
162     private boolean isLineAndColumnMatch(AuditEvent event) {
163         return (lineFilter != null || columnFilter != null)
164                 && (lineFilter == null || !lineFilter.accept(event.getLine()))
165                 && (columnFilter == null || !columnFilter.accept(event.getColumn()));
166     }
167 
168     @Override
169     public int hashCode() {
170         return Objects.hash(filePattern, checkPattern, messagePattern, moduleId, linesCsv,
171                 columnsCsv);
172     }
173 
174     @Override
175     public boolean equals(Object other) {
176         if (this == other) {
177             return true;
178         }
179         if (other == null || getClass() != other.getClass()) {
180             return false;
181         }
182         final SuppressElement suppressElement = (SuppressElement) other;
183         return Objects.equals(filePattern, suppressElement.filePattern)
184                 && Objects.equals(checkPattern, suppressElement.checkPattern)
185                 && Objects.equals(messagePattern, suppressElement.messagePattern)
186                 && Objects.equals(moduleId, suppressElement.moduleId)
187                 && Objects.equals(linesCsv, suppressElement.linesCsv)
188                 && Objects.equals(columnsCsv, suppressElement.columnsCsv);
189     }
190 
191 }