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 java.io.IOException; 023import java.io.Serializable; 024import java.util.ArrayList; 025import java.util.List; 026import javax.xml.bind.annotation.XmlAccessType; 027import javax.xml.bind.annotation.XmlAccessorType; 028import javax.xml.bind.annotation.XmlElement; 029import javax.xml.bind.annotation.XmlRootElement; 030import org.apache.hadoop.hbase.HConstants; 031import org.apache.hadoop.hbase.rest.ProtobufMessageHandler; 032import org.apache.hadoop.hbase.rest.RestUtil; 033import org.apache.hadoop.hbase.rest.protobuf.generated.CellMessage.Cell; 034import org.apache.hadoop.hbase.rest.protobuf.generated.CellSetMessage.CellSet; 035import org.apache.yetus.audience.InterfaceAudience; 036 037import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream; 038import org.apache.hbase.thirdparty.com.google.protobuf.Message; 039import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations; 040 041/** 042 * Representation of a grouping of cells. May contain cells from more than one row. Encapsulates 043 * RowModel and CellModel models. 044 * 045 * <pre> 046 * <complexType name="CellSet"> 047 * <sequence> 048 * <element name="row" type="tns:Row" maxOccurs="unbounded" 049 * minOccurs="1"></element> 050 * </sequence> 051 * </complexType> 052 * 053 * <complexType name="Row"> 054 * <sequence> 055 * <element name="key" type="base64Binary"></element> 056 * <element name="cell" type="tns:Cell" 057 * maxOccurs="unbounded" minOccurs="1"></element> 058 * </sequence> 059 * </complexType> 060 * 061 * <complexType name="Cell"> 062 * <sequence> 063 * <element name="value" maxOccurs="1" minOccurs="1"> 064 * <simpleType> 065 * <restriction base="base64Binary"/> 066 * </simpleType> 067 * </element> 068 * </sequence> 069 * <attribute name="column" type="base64Binary" /> 070 * <attribute name="timestamp" type="int" /> 071 * </complexType> 072 * </pre> 073 */ 074@XmlRootElement(name = "CellSet") 075@XmlAccessorType(XmlAccessType.NONE) 076@InterfaceAudience.Private 077public class CellSetModel implements Serializable, ProtobufMessageHandler { 078 private static final long serialVersionUID = 1L; 079 080 @XmlElement(name = "Row") 081 private List<RowModel> rows; 082 083 /** 084 * Constructor 085 */ 086 public CellSetModel() { 087 this.rows = new ArrayList<>(); 088 } 089 090 /** 091 * @param rows the rows 092 */ 093 public CellSetModel(List<RowModel> rows) { 094 super(); 095 this.rows = rows; 096 } 097 098 /** 099 * Add a row to this cell set 100 * @param row the row 101 */ 102 public void addRow(RowModel row) { 103 rows.add(row); 104 } 105 106 /** Returns the rows */ 107 public List<RowModel> getRows() { 108 return rows; 109 } 110 111 @Override 112 public Message messageFromObject() { 113 CellSet.Builder builder = CellSet.newBuilder(); 114 for (RowModel row : getRows()) { 115 CellSet.Row.Builder rowBuilder = CellSet.Row.newBuilder(); 116 if (row.getKeyLength() == MAGIC_LENGTH) { 117 rowBuilder.setKey(UnsafeByteOperations.unsafeWrap(row.getKey())); 118 } else { 119 rowBuilder.setKey(UnsafeByteOperations.unsafeWrap(row.getKeyArray(), row.getKeyOffset(), 120 row.getKeyLength())); 121 } 122 for (CellModel cell : row.getCells()) { 123 Cell.Builder cellBuilder = Cell.newBuilder(); 124 cellBuilder.setColumn(UnsafeByteOperations.unsafeWrap(cell.getColumn())); 125 if (cell.getValueLength() == MAGIC_LENGTH) { 126 cellBuilder.setData(UnsafeByteOperations.unsafeWrap(cell.getValue())); 127 } else { 128 cellBuilder.setData(UnsafeByteOperations.unsafeWrap(cell.getValueArray(), 129 cell.getValueOffset(), cell.getValueLength())); 130 } 131 if (cell.hasUserTimestamp()) { 132 cellBuilder.setTimestamp(cell.getTimestamp()); 133 } 134 rowBuilder.addValues(cellBuilder); 135 } 136 builder.addRows(rowBuilder); 137 } 138 return builder.build(); 139 } 140 141 @Override 142 public ProtobufMessageHandler getObjectFromMessage(CodedInputStream cis) throws IOException { 143 CellSet.Builder builder = CellSet.newBuilder(); 144 RestUtil.mergeFrom(builder, cis); 145 for (CellSet.Row row : builder.getRowsList()) { 146 RowModel rowModel = new RowModel(row.getKey().toByteArray()); 147 for (Cell cell : row.getValuesList()) { 148 long timestamp = HConstants.LATEST_TIMESTAMP; 149 if (cell.hasTimestamp()) { 150 timestamp = cell.getTimestamp(); 151 } 152 rowModel.addCell( 153 new CellModel(cell.getColumn().toByteArray(), timestamp, cell.getData().toByteArray())); 154 } 155 addRow(rowModel); 156 } 157 return this; 158 } 159}