package com.limegroup.gnutella.filters; import java.util.List; import java.util.Locale; import java.util.Map.Entry; import org.limewire.core.api.search.SearchResult; import com.google.common.collect.ImmutableList; import com.limegroup.gnutella.Response; import com.limegroup.gnutella.filters.response.ResponseFilter; import com.limegroup.gnutella.filters.response.SearchResultFilter; import com.limegroup.gnutella.messages.Message; import com.limegroup.gnutella.messages.QueryReply; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.xml.LimeXMLDocument; /** * A filter that blocks queries and responses matching certain banned phrases. */ public class PhraseFilter implements SpamFilter, ResponseFilter, SearchResultFilter { /** INVARIANT: strings in ban contain only lowercase */ private final List<String> ban; PhraseFilter() { ban = createDefaultList(); } PhraseFilter(String... phrases) { ban = ImmutableList.of(phrases); } private List<String> createDefaultList() { ImmutableList.Builder<String> builder = ImmutableList.builder(); // ADD PHRASES HERE return builder.build(); } String canonical(String word) { return word.toLowerCase(Locale.US).intern(); } @Override // SpamFilter public boolean allow(Message m) { if (m instanceof QueryRequest) return !isBanned(((QueryRequest)m).getQuery()); else return true; } @Override // ResponseFilter public boolean allow(QueryReply qr, Response response) { if(isBanned(response.getName())) { return false; } else { LimeXMLDocument doc = response.getDocument(); return doc == null || allowDoc(doc); } } @Override public boolean allow(SearchResult result, LimeXMLDocument document) { if(isBanned(result.getFileNameWithoutExtension())) { return false; } else { return document == null || allowDoc(document); } } /** Returns true if input matches any of the banned phrases. */ public boolean isBanned(String input) { String canonical = input.toLowerCase(Locale.US); for(String word : ban) { int idx = canonical.indexOf(word); if(idx != -1 && (idx == 0 || canonical.charAt(idx - 1) == ' ') // start of word boundary && (word.length() + idx == canonical.length() || canonical.charAt(word.length() + idx) == ' ')) // end of word boundary { return true; } } return false; } /** Returns true if none of the filters matched. */ private boolean allowDoc(LimeXMLDocument doc) { for(Entry<String, String> entry : doc.getNameValueSet()) { if(isBanned(entry.getValue())) { return false; } } return true; } }