001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2017 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; 027import com.puppycrawl.tools.checkstyle.utils.CommonUtils; 028 029/** 030 * This filter processes {@link AuditEvent} 031 * objects based on the criteria of file, check, module id, line, and 032 * column. It rejects an AuditEvent if the following match: 033 * <ul> 034 * <li>the event's file name; and</li> 035 * <li>the check name or the module identifier; and</li> 036 * <li>(optionally) the event's line is in the filter's line CSV; and</li> 037 * <li>(optionally) the check's columns is in the filter's column CSV.</li> 038 * </ul> 039 * 040 * @author Rick Giles 041 */ 042public class SuppressElement 043 implements Filter { 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 Pattern checkRegexp; 052 053 /** The pattern for check class names. */ 054 private String checkPattern; 055 056 /** Module id filter. */ 057 private String moduleId; 058 059 /** Line number filter. */ 060 private CsvFilter lineFilter; 061 062 /** CSV for line number filter. */ 063 private String linesCsv; 064 065 /** Column number filter. */ 066 private CsvFilter columnFilter; 067 068 /** CSV for column number filter. */ 069 private String columnsCsv; 070 071 /** 072 * Constructs a {@code SuppressElement} for a 073 * file name pattern. Must either call {@link #setColumns(String)} or 074 * {@link #setModuleId(String)} before using this object. 075 * @param files regular expression for names of filtered files. 076 */ 077 public SuppressElement(String files) { 078 filePattern = files; 079 fileRegexp = Pattern.compile(files); 080 } 081 082 /** 083 * Set the check class pattern. 084 * @param checks regular expression for filtered check classes. 085 */ 086 public void setChecks(final String checks) { 087 checkPattern = checks; 088 checkRegexp = CommonUtils.createPattern(checks); 089 } 090 091 /** 092 * Set the module id for filtering. Cannot be null. 093 * @param moduleId the id 094 */ 095 public void setModuleId(final String moduleId) { 096 this.moduleId = moduleId; 097 } 098 099 /** 100 * Sets the CSV values and ranges for line number filtering. 101 * E.g. "1,7-15,18". 102 * @param lines CSV values and ranges for line number filtering. 103 */ 104 public void setLines(String lines) { 105 linesCsv = lines; 106 if (lines == null) { 107 lineFilter = null; 108 } 109 else { 110 lineFilter = new CsvFilter(lines); 111 } 112 } 113 114 /** 115 * Sets the CSV values and ranges for column number filtering. 116 * E.g. "1,7-15,18". 117 * @param columns CSV values and ranges for column number filtering. 118 */ 119 public void setColumns(String columns) { 120 columnsCsv = columns; 121 if (columns == null) { 122 columnFilter = null; 123 } 124 else { 125 columnFilter = new CsvFilter(columns); 126 } 127 } 128 129 @Override 130 public boolean accept(AuditEvent event) { 131 return isFileNameAndModuleNotMatching(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.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 * Whether line and column match. 150 * @param event event to process. 151 * @return true if line and column match. 152 */ 153 private boolean isLineAndColumnMatch(AuditEvent event) { 154 return (lineFilter != null || columnFilter != null) 155 && (lineFilter == null || !lineFilter.accept(event.getLine())) 156 && (columnFilter == null || !columnFilter.accept(event.getColumn())); 157 } 158 159 @Override 160 public int hashCode() { 161 return Objects.hash(filePattern, checkPattern, moduleId, linesCsv, columnsCsv); 162 } 163 164 @Override 165 public boolean equals(Object other) { 166 if (this == other) { 167 return true; 168 } 169 if (other == null || getClass() != other.getClass()) { 170 return false; 171 } 172 final SuppressElement suppressElement = (SuppressElement) other; 173 return Objects.equals(filePattern, suppressElement.filePattern) 174 && Objects.equals(checkPattern, suppressElement.checkPattern) 175 && Objects.equals(moduleId, suppressElement.moduleId) 176 && Objects.equals(linesCsv, suppressElement.linesCsv) 177 && Objects.equals(columnsCsv, suppressElement.columnsCsv); 178 } 179}