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.rest.model; 019 020import static org.apache.hadoop.hbase.rest.model.CellModel.MAGIC_LENGTH; 021 022import com.fasterxml.jackson.annotation.JsonProperty; 023import java.io.IOException; 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.List; 027import javax.xml.bind.annotation.XmlAccessType; 028import javax.xml.bind.annotation.XmlAccessorType; 029import javax.xml.bind.annotation.XmlAttribute; 030import javax.xml.bind.annotation.XmlElement; 031import javax.xml.bind.annotation.XmlRootElement; 032import org.apache.commons.lang3.builder.EqualsBuilder; 033import org.apache.commons.lang3.builder.HashCodeBuilder; 034import org.apache.commons.lang3.builder.ToStringBuilder; 035import org.apache.hadoop.hbase.rest.ProtobufMessageHandler; 036import org.apache.hadoop.hbase.util.Bytes; 037import org.apache.yetus.audience.InterfaceAudience; 038 039import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream; 040import org.apache.hbase.thirdparty.com.google.protobuf.Message; 041 042/** 043 * Representation of a row. A row is a related set of cells, grouped by common row key. RowModels do 044 * not appear in results by themselves. They are always encapsulated within CellSetModels. 045 * 046 * <pre> 047 * <complexType name="Row"> 048 * <sequence> 049 * <element name="key" type="base64Binary"></element> 050 * <element name="cell" type="tns:Cell" 051 * maxOccurs="unbounded" minOccurs="1"></element> 052 * </sequence> 053 * </complexType> 054 * </pre> 055 */ 056@XmlRootElement(name = "Row") 057@XmlAccessorType(XmlAccessType.NONE) 058@InterfaceAudience.Private 059public class RowModel implements ProtobufMessageHandler, Serializable { 060 private static final long serialVersionUID = 1L; 061 062 // If keyLength = -1, this represents the key 063 // If keyLength <> -1, this represents the base array, and key is determined by offset and length 064 private byte[] key; 065 066 private int keyOffset = 0; 067 private int keyLength = MAGIC_LENGTH; 068 069 @JsonProperty("Cell") 070 @XmlElement(name = "Cell") 071 private List<CellModel> cells = new ArrayList<>(); 072 073 /** 074 * Default constructor 075 */ 076 public RowModel() { 077 } 078 079 /** 080 * Constructor 081 * @param key the row key 082 */ 083 public RowModel(final String key) { 084 this(Bytes.toBytes(key)); 085 } 086 087 /** 088 * Constructor 089 * @param key the row key 090 */ 091 public RowModel(final byte[] key) { 092 setKey(key); 093 cells = new ArrayList<>(); 094 } 095 096 /** 097 * Constructor 098 * @param key the row key as represented in the Cell 099 */ 100 public RowModel(final byte[] key, int keyOffset, int keyLength) { 101 this.key = key; 102 this.keyOffset = keyOffset; 103 this.keyLength = keyLength; 104 cells = new ArrayList<>(); 105 } 106 107 /** 108 * Constructor 109 * @param key the row key 110 * @param cells the cells 111 */ 112 public RowModel(final String key, final List<CellModel> cells) { 113 this(Bytes.toBytes(key), cells); 114 } 115 116 /** 117 * Constructor 118 * @param key the row key 119 * @param cells the cells 120 */ 121 public RowModel(final byte[] key, final List<CellModel> cells) { 122 this(key); 123 this.cells = cells; 124 } 125 126 /** 127 * Constructor 128 * @param key the row key 129 * @param cells the cells 130 */ 131 public RowModel(final byte[] key, int keyOffset, int keyLength, final List<CellModel> cells) { 132 this(key, keyOffset, keyLength); 133 this.cells = cells; 134 } 135 136 /** 137 * Adds a cell to the list of cells for this row 138 * @param cell the cell 139 */ 140 public void addCell(CellModel cell) { 141 cells.add(cell); 142 } 143 144 /** Returns the row key */ 145 @XmlAttribute 146 @JsonProperty("key") 147 public byte[] getKey() { 148 if (keyLength == MAGIC_LENGTH) { 149 return key; 150 } else { 151 byte[] retKey = new byte[keyLength]; 152 System.arraycopy(key, keyOffset, retKey, 0, keyLength); 153 return retKey; 154 } 155 } 156 157 /** Returns the backing row key array */ 158 public byte[] getKeyArray() { 159 return key; 160 } 161 162 /** 163 * @param key the row key 164 */ 165 @JsonProperty("key") 166 public void setKey(byte[] key) { 167 this.key = key; 168 this.keyLength = MAGIC_LENGTH; 169 } 170 171 public int getKeyOffset() { 172 return keyOffset; 173 } 174 175 public int getKeyLength() { 176 return keyLength; 177 } 178 179 /** Returns the cells */ 180 public List<CellModel> getCells() { 181 return cells; 182 } 183 184 @Override 185 public Message messageFromObject() { 186 // there is no standalone row protobuf message 187 throw new UnsupportedOperationException("no protobuf equivalent to RowModel"); 188 } 189 190 @Override 191 public ProtobufMessageHandler getObjectFromMessage(CodedInputStream is) throws IOException { 192 // there is no standalone row protobuf message 193 throw new UnsupportedOperationException("no protobuf equivalent to RowModel"); 194 } 195 196 @Override 197 public boolean equals(Object obj) { 198 if (obj == null) { 199 return false; 200 } 201 if (obj == this) { 202 return true; 203 } 204 if (obj.getClass() != getClass()) { 205 return false; 206 } 207 RowModel rowModel = (RowModel) obj; 208 return new EqualsBuilder().append(getKey(), rowModel.getKey()).append(cells, rowModel.cells) 209 .isEquals(); 210 } 211 212 @Override 213 public int hashCode() { 214 return new HashCodeBuilder().append(getKey()).append(cells).toHashCode(); 215 } 216 217 @Override 218 public String toString() { 219 return new ToStringBuilder(this).append("key", getKey()).append("cells", cells).toString(); 220 } 221}