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