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