Index: hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java (revision 1586806) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterList.java (working copy) @@ -345,12 +345,8 @@ @Override public boolean hasFilterRow() { - for (Filter filter : filters) { - if(filter.hasFilterRow()) { - return true; - } - } - return false; + // filterRow is overridden below + return true; } @Override Index: hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterWrapper.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterWrapper.java (revision 1586806) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FilterWrapper.java (working copy) @@ -20,9 +20,12 @@ package org.apache.hadoop.hbase.filter; import java.io.IOException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.hbase.Cell; @@ -43,7 +46,9 @@ */ @InterfaceAudience.Private final public class FilterWrapper extends Filter { + static final Log LOG = LogFactory.getLog(FilterWrapper.class); Filter filter = null; + boolean hasFilterRow; public FilterWrapper( Filter filter ) { if (null == filter) { @@ -51,6 +56,7 @@ throw new NullPointerException("Cannot create FilterWrapper with null Filter"); } this.filter = filter; + this.hasFilterRow = isFilterMethodImplemented(filter, "filterRow"); } /** @@ -146,9 +152,32 @@ return KeyValueUtil.ensureKeyValue(this.filter.transformCell(currentKV)); } + /* + * 'Implemented' means the method is implemented and not inherited from FilterBase + * @param filter the filter object + * @param name method name + * @return true if named method is implemented + */ + public static boolean isFilterMethodImplemented(Filter filter, String name) + { + Class baseCls = FilterBase.class.getClass(); + try + { + Class clazz = filter.getClass(); + Method m = clazz.getMethod(name, new Class []{}); + return !m.getDeclaringClass().equals(baseCls); + } catch (SecurityException e) { + LOG.error("Unable to determine whether " + name + " is implemented", e); + } catch (NoSuchMethodException e) { + LOG.error(name + " doesn't exist", e); + } + + return false; + } + @Override public boolean hasFilterRow() { - return this.filter.hasFilterRow(); + return this.hasFilterRow; } @Override Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java (revision 1586806) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java (working copy) @@ -25,6 +25,7 @@ import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterWrapper; import org.apache.hadoop.hbase.filter.IncompatibleFilterException; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.util.Bytes; @@ -376,10 +377,10 @@ * @param batch the maximum number of values */ public void setBatch(int batch) { - if (this.hasFilter() && this.filter.hasFilterRow()) { + if (this.hasFilter() && FilterWrapper.isFilterMethodImplemented(this.filter, "filterRow")) { throw new IncompatibleFilterException( "Cannot set batch on a scan using a filter" + - " that returns true for filter.hasFilterRow"); + " that overrides filterRow()"); } this.batch = batch; }