View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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      /** The regexp to match file names against. */
44      private final Pattern fileRegexp;
45  
46      /** The pattern for file names. */
47      private final String filePattern;
48  
49      /** The regexp to match check names against. */
50      private final Pattern checkRegexp;
51  
52      /** The pattern for check class names. */
53      private final String checkPattern;
54  
55      /** The regexp to match message names against. */
56      private final Pattern messageRegexp;
57  
58      /** The pattern for message names. */
59      private final String messagePattern;
60  
61      /** Module id filter. */
62      private final String moduleId;
63  
64      /** Line number filter. */
65      private final CsvFilter lineFilter;
66  
67      /** CSV for line number filter. */
68      private final String linesCsv;
69  
70      /** Column number filter. */
71      private final CsvFilter columnFilter;
72  
73      /** CSV for column number filter. */
74      private final String columnsCsv;
75  
76      /**
77       * Constructs a {@code SuppressElement} for a
78       * file name pattern.
79       *
80       * @param files   regular expression for names of filtered files.
81       * @param checks  regular expression for filtered check classes.
82       * @param message regular expression for messages.
83       * @param modId   the id
84       * @param lines   lines CSV values and ranges for line number filtering.
85       * @param columns columns CSV values and ranges for column number filtering.
86       */
87      public SuppressElement(String files, String checks,
88                             String message, String modId, String lines, String columns) {
89          filePattern = files;
90          if (files == null) {
91              fileRegexp = null;
92          }
93          else {
94              fileRegexp = Pattern.compile(files);
95          }
96          checkPattern = checks;
97          if (checks == null) {
98              checkRegexp = null;
99          }
100         else {
101             checkRegexp = Pattern.compile(checks);
102         }
103         messagePattern = message;
104         if (message == null) {
105             messageRegexp = null;
106         }
107         else {
108             messageRegexp = Pattern.compile(message);
109         }
110         moduleId = modId;
111         linesCsv = lines;
112         if (lines == null) {
113             lineFilter = null;
114         }
115         else {
116             lineFilter = new CsvFilter(lines);
117         }
118         columnsCsv = columns;
119         if (columns == null) {
120             columnFilter = null;
121         }
122         else {
123             columnFilter = new CsvFilter(columns);
124         }
125     }
126 
127     @Override
128     public boolean accept(AuditEvent event) {
129         return isFileNameAndModuleNotMatching(event)
130                 || !isMessageNameMatching(event)
131                 || isLineAndColumnMatch(event);
132     }
133 
134     /**
135      * Is matching by file name and Check name.
136      * @param event event
137      * @return true is matching
138      */
139     private boolean isFileNameAndModuleNotMatching(AuditEvent event) {
140         return event.getFileName() == null
141                 || fileRegexp != null && !fileRegexp.matcher(event.getFileName()).find()
142                 || event.getLocalizedMessage() == null
143                 || moduleId != null && !moduleId.equals(event.getModuleId())
144                 || checkRegexp != null && !checkRegexp.matcher(event.getSourceName()).find();
145     }
146 
147     /**
148      * Is matching by message.
149      * @param event event
150      * @return true is matching or not set.
151      */
152     private boolean isMessageNameMatching(AuditEvent event) {
153         return messageRegexp == null || messageRegexp.matcher(event.getMessage()).find();
154     }
155 
156     /**
157      * Whether line and column match.
158      * @param event event to process.
159      * @return true if line and column match.
160      */
161     private boolean isLineAndColumnMatch(AuditEvent event) {
162         return (lineFilter != null || columnFilter != null)
163                 && (lineFilter == null || !lineFilter.accept(event.getLine()))
164                 && (columnFilter == null || !columnFilter.accept(event.getColumn()));
165     }
166 
167     @Override
168     public int hashCode() {
169         return Objects.hash(filePattern, checkPattern, messagePattern, moduleId, linesCsv,
170                 columnsCsv);
171     }
172 
173     @Override
174     public boolean equals(Object other) {
175         if (this == other) {
176             return true;
177         }
178         if (other == null || getClass() != other.getClass()) {
179             return false;
180         }
181         final SuppressElement suppressElement = (SuppressElement) other;
182         return Objects.equals(filePattern, suppressElement.filePattern)
183                 && Objects.equals(checkPattern, suppressElement.checkPattern)
184                 && Objects.equals(messagePattern, suppressElement.messagePattern)
185                 && Objects.equals(moduleId, suppressElement.moduleId)
186                 && Objects.equals(linesCsv, suppressElement.linesCsv)
187                 && Objects.equals(columnsCsv, suppressElement.columnsCsv);
188     }
189 }