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.Collections; 023import java.util.HashSet; 024import java.util.Objects; 025import java.util.Set; 026 027import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent; 028import com.puppycrawl.tools.checkstyle.TreeWalkerFilter; 029import com.puppycrawl.tools.checkstyle.api.AutomaticBean; 030import com.puppycrawl.tools.checkstyle.api.CheckstyleException; 031import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder; 032import com.puppycrawl.tools.checkstyle.utils.FilterUtils; 033 034/** 035 * This filter accepts TreeWalkerAuditEvents according to file, check and xpath query, 036 * as specified in a suppression file. 037 * 038 * @author Timur Tibeyev. 039 * @noinspection NonFinalFieldReferenceInEquals, NonFinalFieldReferencedInHashCode 040 */ 041public class SuppressionXpathFilter extends AutomaticBean implements 042 TreeWalkerFilter, ExternalResourceHolder { 043 044 /** Filename of suppression file. */ 045 private String file; 046 /** Tells whether config file existence is optional. */ 047 private boolean optional; 048 /** Set of individual xpath suppresses. */ 049 private Set<TreeWalkerFilter> filters = new HashSet<>(); 050 051 /** 052 * Sets name of the suppression file. 053 * @param fileName name of the suppressions file. 054 */ 055 public void setFile(String fileName) { 056 file = fileName; 057 } 058 059 /** 060 * Sets whether config file existence is optional. 061 * @param optional tells if config file existence is optional. 062 */ 063 public void setOptional(boolean optional) { 064 this.optional = optional; 065 } 066 067 @Override 068 public boolean equals(Object obj) { 069 if (this == obj) { 070 return true; 071 } 072 if (obj == null || getClass() != obj.getClass()) { 073 return false; 074 } 075 final SuppressionXpathFilter suppressionXpathFilter = (SuppressionXpathFilter) obj; 076 return Objects.equals(filters, suppressionXpathFilter.filters); 077 } 078 079 @Override 080 public int hashCode() { 081 return Objects.hash(filters); 082 } 083 084 @Override 085 public boolean accept(TreeWalkerAuditEvent treeWalkerAuditEvent) { 086 boolean result = true; 087 for (TreeWalkerFilter filter : filters) { 088 if (!filter.accept(treeWalkerAuditEvent)) { 089 result = false; 090 break; 091 } 092 } 093 return result; 094 } 095 096 @Override 097 public Set<String> getExternalResourceLocations() { 098 return Collections.singleton(file); 099 } 100 101 @Override 102 protected void finishLocalSetup() throws CheckstyleException { 103 if (file != null) { 104 if (optional) { 105 if (FilterUtils.isFileExists(file)) { 106 filters = SuppressionsLoader.loadXpathSuppressions(file); 107 } 108 else { 109 filters = new HashSet<>(); 110 } 111 } 112 else { 113 filters = SuppressionsLoader.loadXpathSuppressions(file); 114 } 115 } 116 } 117 118}