001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 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//////////////////////////////////////////////////////////////////////////////// 019package com.puppycrawl.tools.checkstyle.filters; 020 021import com.puppycrawl.tools.checkstyle.api.AuditEvent; 022import com.puppycrawl.tools.checkstyle.api.Filter; 023import com.puppycrawl.tools.checkstyle.api.Utils; 024import java.util.regex.Pattern; 025import java.util.regex.PatternSyntaxException; 026 027/** 028 * This filter processes {@link com.puppycrawl.tools.checkstyle.api.AuditEvent} 029 * objects based on the criteria of file, check, module id, line, and 030 * column. It rejects an AuditEvent if the following match: 031 * <ul> 032 * <li>the event's file name; and</li> 033 * <li>the check name or the module identifier; and</li> 034 * <li>(optionally) the event's line is in the filter's line CSV; and</li> 035 * <li>(optionally) the check's columns is in the filter's column CSV.</li> 036 * </ul> 037 * 038 * @author Rick Giles 039 */ 040public class SuppressElement 041 implements Filter 042{ 043 /** hash function multiplicand */ 044 private static final int HASH_MULT = 29; 045 046 /** the regexp to match file names against */ 047 private final Pattern mFileRegexp; 048 049 /** the pattern for file names*/ 050 private final String mFilePattern; 051 052 /** the regexp to match check names against */ 053 private Pattern mCheckRegexp; 054 055 /** the pattern for check class names*/ 056 private String mCheckPattern; 057 058 /** module id filter. */ 059 private String mModuleId; 060 061 /** line number filter */ 062 private CSVFilter mLineFilter; 063 064 /** CSV for line number filter */ 065 private String mLinesCSV; 066 067 /** column number filter */ 068 private CSVFilter mColumnFilter; 069 070 /** CSV for column number filter */ 071 private String mColumnsCSV; 072 073 /** 074 * Constructs a <code>SuppressElement</code> for a 075 * file name pattern. Must either call {@link #setColumns(String)} or 076 * {@link #setModuleId(String)} before using this object. 077 * @param aFiles regular expression for names of filtered files. 078 * @throws PatternSyntaxException if there is an error. 079 */ 080 public SuppressElement(String aFiles) 081 throws PatternSyntaxException 082 { 083 mFilePattern = aFiles; 084 mFileRegexp = Utils.getPattern(aFiles); 085 } 086 087 /** 088 * Set the check class pattern. 089 * @param aChecks regular expression for filtered check classes. 090 */ 091 public void setChecks(final String aChecks) 092 { 093 mCheckPattern = aChecks; 094 mCheckRegexp = Utils.getPattern(aChecks); 095 } 096 097 /** 098 * Set the module id for filtering. Cannot be null. 099 * @param aModuleId the id 100 */ 101 public void setModuleId(final String aModuleId) 102 { 103 mModuleId = aModuleId; 104 } 105 /** 106 * Sets the CSV values and ranges for line number filtering. 107 * E.g. "1,7-15,18". 108 * @param aLines CSV values and ranges for line number filtering. 109 */ 110 public void setLines(String aLines) 111 { 112 mLinesCSV = aLines; 113 if (aLines != null) { 114 mLineFilter = new CSVFilter(aLines); 115 } 116 else { 117 mLineFilter = null; 118 } 119 } 120 121 /** 122 * Sets the CSV values and ranges for column number filtering. 123 * E.g. "1,7-15,18". 124 * @param aColumns CSV values and ranges for column number filtering. 125 */ 126 public void setColumns(String aColumns) 127 { 128 mColumnsCSV = aColumns; 129 if (aColumns != null) { 130 mColumnFilter = new CSVFilter(aColumns); 131 } 132 else { 133 mColumnFilter = null; 134 } 135 } 136 137 /** {@inheritDoc} */ 138 public boolean accept(AuditEvent aEvent) 139 { 140 // file and check match? 141 if ((aEvent.getFileName() == null) 142 || !mFileRegexp.matcher(aEvent.getFileName()).find() 143 || (aEvent.getLocalizedMessage() == null) 144 || ((mModuleId != null) && !mModuleId.equals(aEvent 145 .getModuleId())) 146 || ((mCheckRegexp != null) && !mCheckRegexp.matcher( 147 aEvent.getSourceName()).find())) 148 { 149 return true; 150 } 151 152 // reject if no line/column matching 153 if ((mLineFilter == null) && (mColumnFilter == null)) { 154 return false; 155 } 156 157 if (mLineFilter != null && mLineFilter.accept(aEvent.getLine())) { 158 return false; 159 } 160 161 if (mColumnFilter != null && mColumnFilter.accept(aEvent.getColumn())) { 162 return false; 163 } 164 return true; 165 } 166 167 @Override 168 public String toString() 169 { 170 return "SuppressElement[files=" + mFilePattern + ",checks=" 171 + mCheckPattern + ",lines=" + mLinesCSV + ",columns=" 172 + mColumnsCSV + "]"; 173 } 174 175 @Override 176 public int hashCode() 177 { 178 int result = HASH_MULT * mFilePattern.hashCode(); 179 if (mCheckPattern != null) { 180 result = HASH_MULT * result + mCheckPattern.hashCode(); 181 } 182 if (mModuleId != null) { 183 result = HASH_MULT * result + mModuleId.hashCode(); 184 } 185 if (mLinesCSV != null) { 186 result = HASH_MULT * result + mLinesCSV.hashCode(); 187 } 188 if (mColumnsCSV != null) { 189 result = HASH_MULT * result + mColumnsCSV.hashCode(); 190 } 191 return result; 192 } 193 194 @Override 195 public boolean equals(Object aObject) 196 { 197 if (aObject instanceof SuppressElement) { 198 final SuppressElement other = (SuppressElement) aObject; 199 200 // same file pattern? 201 if (!this.mFilePattern.equals(other.mFilePattern)) { 202 return false; 203 } 204 205 // same check pattern? 206 if (mCheckPattern != null) { 207 if (!mCheckPattern.equals(other.mCheckPattern)) { 208 return false; 209 } 210 } 211 else if (other.mCheckPattern != null) { 212 return false; 213 } 214 215 // same module id? 216 if (mModuleId != null) { 217 if (!mModuleId.equals(other.mModuleId)) { 218 return false; 219 } 220 } 221 else if (other.mModuleId != null) { 222 return false; 223 } 224 225 // same line number filter? 226 if (mLineFilter != null) { 227 if (!mLineFilter.equals(other.mLineFilter)) { 228 return false; 229 } 230 } 231 else if (other.mLineFilter != null) { 232 return false; 233 } 234 235 // same column number filter? 236 if (mColumnFilter != null) { 237 if (!mColumnFilter.equals(other.mColumnFilter)) { 238 return false; 239 } 240 } 241 else if (other.mColumnFilter != null) { 242 return false; 243 } 244 245 // everything is the same 246 return true; 247 } 248 return false; 249 } 250}