001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2018 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.filters; 021 022import java.util.Objects; 023import java.util.regex.Pattern; 024 025import com.puppycrawl.tools.checkstyle.api.AuditEvent; 026import com.puppycrawl.tools.checkstyle.api.Filter; 027 028/** 029 * This filter processes {@link AuditEvent} 030 * objects based on the criteria of file, check, module id, line, and 031 * column. It rejects an AuditEvent if the following match: 032 * <ul> 033 * <li>the event's file name; and</li> 034 * <li>the check name or the module identifier; and</li> 035 * <li>(optionally) the event's line is in the filter's line CSV; and</li> 036 * <li>(optionally) the check's columns is in the filter's column CSV.</li> 037 * </ul> 038 * 039 * @author Rick Giles 040 */ 041public class SuppressElement 042 implements Filter { 043 044 /** The regexp to match file names against. */ 045 private final Pattern fileRegexp; 046 047 /** The pattern for file names. */ 048 private final String filePattern; 049 050 /** The regexp to match check names against. */ 051 private final Pattern checkRegexp; 052 053 /** The pattern for check class names. */ 054 private final String checkPattern; 055 056 /** The regexp to match message names against. */ 057 private final Pattern messageRegexp; 058 059 /** The pattern for message names. */ 060 private final String messagePattern; 061 062 /** Module id filter. */ 063 private final String moduleId; 064 065 /** Line number filter. */ 066 private final CsvFilter lineFilter; 067 068 /** CSV for line number filter. */ 069 private final String linesCsv; 070 071 /** Column number filter. */ 072 private final CsvFilter columnFilter; 073 074 /** CSV for column number filter. */ 075 private final String columnsCsv; 076 077 /** 078 * Constructs a {@code SuppressElement} for a 079 * file name pattern. 080 * 081 * @param files regular expression for names of filtered files. 082 * @param checks regular expression for filtered check classes. 083 * @param message regular expression for messages. 084 * @param modId the id 085 * @param lines lines CSV values and ranges for line number filtering. 086 * @param columns columns CSV values and ranges for column number filtering. 087 */ 088 public SuppressElement(String files, String checks, 089 String message, String modId, String lines, String columns) { 090 filePattern = files; 091 if (files == null) { 092 fileRegexp = null; 093 } 094 else { 095 fileRegexp = Pattern.compile(files); 096 } 097 checkPattern = checks; 098 if (checks == null) { 099 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}