001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2015 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 * Sets the CSV values and ranges for line number filtering. 100 * E.g. "1,7-15,18". 101 * @param lines CSV values and ranges for line number filtering. 102 */ 103 public void setLines(String lines) { 104 linesCSV = lines; 105 if (lines != null) { 106 lineFilter = new CSVFilter(lines); 107 } 108 else { 109 lineFilter = null; 110 } 111 } 112 113 /** 114 * Sets the CSV values and ranges for column number filtering. 115 * E.g. "1,7-15,18". 116 * @param columns CSV values and ranges for column number filtering. 117 */ 118 public void setColumns(String columns) { 119 columnsCSV = columns; 120 if (columns != null) { 121 columnFilter = new CSVFilter(columns); 122 } 123 else { 124 columnFilter = null; 125 } 126 } 127 128 @Override 129 public boolean accept(AuditEvent event) { 130 // reject if file or check module mismatch? 131 if (isFileNameAndModuleNotMatching(event)) { 132 return true; 133 } 134 135 // reject if no line/column matching 136 return (lineFilter != null || columnFilter != null) 137 && (lineFilter == null || !lineFilter.accept(event.getLine())) 138 && (columnFilter == null || !columnFilter.accept(event.getColumn())); 139 } 140 141 /** 142 * Is matching by file name and Check name. 143 * @param event event 144 * @return true is matching 145 */ 146 private boolean isFileNameAndModuleNotMatching(AuditEvent event) { 147 return event.getFileName() == null 148 || !fileRegexp.matcher(event.getFileName()).find() 149 || event.getLocalizedMessage() == null 150 || moduleId != null && !moduleId.equals(event.getModuleId()) 151 || checkRegexp != null && !checkRegexp.matcher(event.getSourceName()).find(); 152 } 153 154 @Override 155 public int hashCode() { 156 return Objects.hash(filePattern, checkPattern, moduleId, linesCSV, columnsCSV); 157 } 158 159 @Override 160 public boolean equals(Object o) { 161 if (this == o) { 162 return true; 163 } 164 if (o == null || getClass() != o.getClass()) { 165 return false; 166 } 167 final SuppressElement suppressElement = (SuppressElement) o; 168 return Objects.equals(filePattern, suppressElement.filePattern) 169 && Objects.equals(checkPattern, suppressElement.checkPattern) 170 && Objects.equals(moduleId, suppressElement.moduleId) 171 && Objects.equals(linesCSV, suppressElement.linesCSV) 172 && Objects.equals(columnsCSV, suppressElement.columnsCSV); 173 } 174}