001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.filter; 019 020import java.util.Locale; 021import org.apache.hadoop.hbase.exceptions.DeserializationException; 022import org.apache.hadoop.hbase.util.Bytes; 023import org.apache.yetus.audience.InterfaceAudience; 024 025import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 026 027import org.apache.hadoop.hbase.shaded.protobuf.generated.ComparatorProtos; 028 029/** 030 * This comparator is for use with SingleColumnValueFilter, for filtering based on the value of a 031 * given column. Use it to test if a given substring appears in a cell value in the column. The 032 * comparison is case insensitive. 033 * <p> 034 * Only EQUAL or NOT_EQUAL tests are valid with this comparator. 035 * <p> 036 * For example: 037 * <p> 038 * 039 * <pre> 040 * SingleColumnValueFilter scvf = 041 * new SingleColumnValueFilter("col", CompareOp.EQUAL, new SubstringComparator("substr")); 042 * </pre> 043 */ 044@InterfaceAudience.Public 045@SuppressWarnings("ComparableType") // Should this move to Comparator usage? 046public class SubstringComparator extends ByteArrayComparable { 047 048 private String substr; 049 050 /** 051 * Constructor 052 * @param substr the substring 053 */ 054 public SubstringComparator(String substr) { 055 super(Bytes.toBytes(substr.toLowerCase(Locale.ROOT))); 056 this.substr = substr.toLowerCase(Locale.ROOT); 057 } 058 059 @Override 060 public byte[] getValue() { 061 return Bytes.toBytes(substr); 062 } 063 064 @Override 065 public int compareTo(byte[] value, int offset, int length) { 066 return Bytes.toString(value, offset, length).toLowerCase(Locale.ROOT).contains(substr) ? 0 : 1; 067 } 068 069 /** Returns The comparator serialized using pb */ 070 @Override 071 public byte[] toByteArray() { 072 ComparatorProtos.SubstringComparator.Builder builder = 073 ComparatorProtos.SubstringComparator.newBuilder(); 074 builder.setSubstr(this.substr); 075 return builder.build().toByteArray(); 076 } 077 078 /** 079 * Parse a serialized representation of {@link SubstringComparator} 080 * @param pbBytes A pb serialized {@link SubstringComparator} instance 081 * @return An instance of {@link SubstringComparator} made from <code>bytes</code> 082 * @throws DeserializationException if an error occurred 083 * @see #toByteArray 084 */ 085 public static SubstringComparator parseFrom(final byte[] pbBytes) 086 throws DeserializationException { 087 ComparatorProtos.SubstringComparator proto; 088 try { 089 proto = ComparatorProtos.SubstringComparator.parseFrom(pbBytes); 090 } catch (InvalidProtocolBufferException e) { 091 throw new DeserializationException(e); 092 } 093 return new SubstringComparator(proto.getSubstr()); 094 } 095 096 /** 097 * Returns true if and only if the fields of the comparator that are serialized are equal to the 098 * corresponding fields in other. Used for testing. 099 */ 100 @Override 101 boolean areSerializedFieldsEqual(ByteArrayComparable other) { 102 if (other == this) { 103 return true; 104 } 105 if (!(other instanceof SubstringComparator)) { 106 return false; 107 } 108 SubstringComparator comparator = (SubstringComparator) other; 109 return super.areSerializedFieldsEqual(comparator) && this.substr.equals(comparator.substr); 110 } 111 112}