001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.filter;
021
022import java.io.IOException;
023import java.util.ArrayList;
024
025import org.apache.hadoop.hbase.Cell;
026import org.apache.hadoop.hbase.CompareOperator;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.apache.hadoop.hbase.exceptions.DeserializationException;
029import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
030import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos;
031import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
032
033/**
034 * This filter is used to filter based on the column qualifier. It takes an
035 * operator (equal, greater, not equal, etc) and a byte [] comparator for the
036 * column qualifier portion of a key.
037 * <p>
038 * This filter can be wrapped with {@link WhileMatchFilter} and {@link SkipFilter}
039 * to add more control.
040 * <p>
041 * Multiple filters can be combined using {@link FilterList}.
042 * <p>
043 * If an already known column qualifier is looked for, 
044 * use {@link org.apache.hadoop.hbase.client.Get#addColumn}
045 * directly rather than a filter.
046 */
047@InterfaceAudience.Public
048public class QualifierFilter extends CompareFilter {
049
050  /**
051   * Constructor.
052   * @param op the compare op for column qualifier matching
053   * @param qualifierComparator the comparator for column qualifier matching
054   * @deprecated Since 2.0.0. Will be removed in 3.0.0.
055   * Use {@link #QualifierFilter(CompareOperator, ByteArrayComparable)} instead.
056   */
057  @Deprecated
058  public QualifierFilter(final CompareOp op,
059      final ByteArrayComparable qualifierComparator) {
060    super(op, qualifierComparator);
061  }
062
063  /**
064   * Constructor.
065   * @param op the compare op for column qualifier matching
066   * @param qualifierComparator the comparator for column qualifier matching
067   */
068  public QualifierFilter(final CompareOperator op,
069                         final ByteArrayComparable qualifierComparator) {
070    super(op, qualifierComparator);
071  }
072
073  @Deprecated
074  @Override
075  public ReturnCode filterKeyValue(final Cell c) {
076    return filterCell(c);
077  }
078
079  @Override
080  public ReturnCode filterCell(final Cell c) {
081    if (compareQualifier(getCompareOperator(), this.comparator, c)) {
082      return ReturnCode.SKIP;
083    }
084    return ReturnCode.INCLUDE;
085  }
086
087  public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) {
088    ArrayList<?> arguments = CompareFilter.extractArguments(filterArguments);
089    CompareOperator compareOp = (CompareOperator)arguments.get(0);
090    ByteArrayComparable comparator = (ByteArrayComparable)arguments.get(1);
091    return new QualifierFilter(compareOp, comparator);
092  }
093
094  /**
095   * @return The filter serialized using pb
096   */
097  @Override
098  public byte [] toByteArray() {
099    FilterProtos.QualifierFilter.Builder builder =
100      FilterProtos.QualifierFilter.newBuilder();
101    builder.setCompareFilter(super.convert());
102    return builder.build().toByteArray();
103  }
104
105  /**
106   * @param pbBytes A pb serialized {@link QualifierFilter} instance
107   * @return An instance of {@link QualifierFilter} made from <code>bytes</code>
108   * @throws org.apache.hadoop.hbase.exceptions.DeserializationException
109   * @see #toByteArray
110   */
111  public static QualifierFilter parseFrom(final byte [] pbBytes)
112  throws DeserializationException {
113    FilterProtos.QualifierFilter proto;
114    try {
115      proto = FilterProtos.QualifierFilter.parseFrom(pbBytes);
116    } catch (InvalidProtocolBufferException e) {
117      throw new DeserializationException(e);
118    }
119    final CompareOperator valueCompareOp =
120      CompareOperator.valueOf(proto.getCompareFilter().getCompareOp().name());
121    ByteArrayComparable valueComparator = null;
122    try {
123      if (proto.getCompareFilter().hasComparator()) {
124        valueComparator = ProtobufUtil.toComparator(proto.getCompareFilter().getComparator());
125      }
126    } catch (IOException ioe) {
127      throw new DeserializationException(ioe);
128    }
129    return new QualifierFilter(valueCompareOp,valueComparator);
130  }
131
132  /**
133   * @return true if and only if the fields of the filter that are serialized
134   * are equal to the corresponding fields in other.  Used for testing.
135   */
136  @Override
137  boolean areSerializedFieldsEqual(Filter o) {
138    if (o == this) return true;
139    if (!(o instanceof QualifierFilter)) return false;
140
141    return super.areSerializedFieldsEqual(o);
142  }
143
144  @Override
145  public boolean equals(Object obj) {
146    return obj instanceof Filter && areSerializedFieldsEqual((Filter) obj);
147  }
148
149  @Override
150  public int hashCode() {
151    return super.hashCode();
152  }
153}