package com.limegroup.gnutella.filters;
import java.util.Vector;
import com.limegroup.gnutella.messages.Message;
/**
* A filter to eliminate Gnutella spam. Subclass to implement custom
* filters. Each Gnutella connection has two SpamFilters; the
* personal filter (for filtering results and the search monitor) and
* a route filter (for deciding what I even consider). (Strategy
* pattern.) Note that a packet stopped by the route filter will
* never reach the personal filter.<p>
*
* Because one filter is used per connection, and only one invocation of
* the run(..) method is used, filters are <b>not synchronized</b> by
* default. The exception is BlackListFilter, which uses the Singleton
* pattern and thus must be synchronized.
*/
public abstract class SpamFilter {
/**
* Returns a new instance of a SpamFilter subclass based on
* the current settings manager. (Factory method) This
* filter is intended for deciding which packets I display in
* search results.
*/
public static SpamFilter newPersonalFilter() {
Vector /* of SpamFilter */ buf=new Vector();
//3. Spammy Replies
SpamReplyFilter spf=new SpamReplyFilter();
buf.add(spf);
//4. Mutable GUID-based filters.
MutableGUIDFilter mgf = MutableGUIDFilter.instance();
buf.add(mgf);
return compose(buf);
}
/**
* Returns a new instance of a SpamFilter subclass based on
* the current settings manager. (Factory method) This
* filter is intended for deciding which packets to route.
*/
public static SpamFilter newRouteFilter() {
//Assemble spam filters. Order matters a little bit.
Vector /* of SpamFilter */ buf=new Vector();
//1. Eliminate old LimeWire requeries.
buf.add(new RequeryFilter());
//1b. Eliminate runaway Qtrax queries.
buf.add(new GUIDFilter());
//4. BearShare high-bit queries.
// if (FilterSettings.FILTER_HIGHBIT_QUERIES.getValue())
// buf.add(new BearShareFilter());
return compose(buf);
}
/**
* Returns a composite filter of the given filters.
* @param filters a Vector of SpamFilter.
*/
private static SpamFilter compose(Vector /* of SpamFilter */ filters) {
//As a minor optimization, we avoid a few method calls in
//special cases.
if (filters.size()==0)
return new AllowFilter();
else if (filters.size()==1)
return (SpamFilter)filters.get(0);
else {
SpamFilter[] delegates=new SpamFilter[filters.size()];
filters.copyInto(delegates);
return new CompositeFilter(delegates);
}
}
/**
* Returns true iff this is considered spam and should not be processed.
*/
public abstract boolean allow(Message m);
}