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 */
019package org.apache.hadoop.hbase.rest.model;
020
021import java.io.IOException;
022import java.io.Serializable;
023import java.util.ArrayList;
024import java.util.List;
025
026import javax.xml.bind.annotation.XmlAccessType;
027import javax.xml.bind.annotation.XmlAccessorType;
028import javax.xml.bind.annotation.XmlElement;
029import javax.xml.bind.annotation.XmlRootElement;
030
031import org.apache.hadoop.hbase.HConstants;
032import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
033import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
034import org.apache.hadoop.hbase.rest.protobuf.generated.CellMessage.Cell;
035import org.apache.hadoop.hbase.rest.protobuf.generated.CellSetMessage.CellSet;
036import org.apache.hadoop.hbase.util.ByteStringer;
037
038import org.apache.yetus.audience.InterfaceAudience;
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  private static final long serialVersionUID = 1L;
078
079  @XmlElement(name="Row")
080  private List<RowModel> rows;
081
082  /**
083   * Constructor
084   */
085  public CellSetModel() {
086    this.rows = new ArrayList<>();
087  }
088
089  /**
090   * @param rows the rows
091   */
092  public CellSetModel(List<RowModel> rows) {
093    super();
094    this.rows = rows;
095  }
096
097  /**
098   * Add a row to this cell set
099   * @param row the row
100   */
101  public void addRow(RowModel row) {
102    rows.add(row);
103  }
104
105  /**
106   * @return the rows
107   */
108  public List<RowModel> getRows() {
109    return rows;
110  }
111
112  @Override
113  public byte[] createProtobufOutput() {
114    CellSet.Builder builder = CellSet.newBuilder();
115    for (RowModel row : getRows()) {
116      CellSet.Row.Builder rowBuilder = CellSet.Row.newBuilder();
117      rowBuilder.setKey(ByteStringer.wrap(row.getKey()));
118      for (CellModel cell : row.getCells()) {
119        Cell.Builder cellBuilder = Cell.newBuilder();
120        cellBuilder.setColumn(ByteStringer.wrap(cell.getColumn()));
121        cellBuilder.setData(ByteStringer.wrap(cell.getValue()));
122        if (cell.hasUserTimestamp()) {
123          cellBuilder.setTimestamp(cell.getTimestamp());
124        }
125        rowBuilder.addValues(cellBuilder);
126      }
127      builder.addRows(rowBuilder);
128    }
129    return builder.build().toByteArray();
130  }
131
132  @Override
133  public ProtobufMessageHandler getObjectFromMessage(byte[] message)
134      throws IOException {
135    CellSet.Builder builder = CellSet.newBuilder();
136    ProtobufUtil.mergeFrom(builder, message);
137    for (CellSet.Row row : builder.getRowsList()) {
138      RowModel rowModel = new RowModel(row.getKey().toByteArray());
139      for (Cell cell : row.getValuesList()) {
140        long timestamp = HConstants.LATEST_TIMESTAMP;
141        if (cell.hasTimestamp()) {
142          timestamp = cell.getTimestamp();
143        }
144        rowModel.addCell(
145            new CellModel(cell.getColumn().toByteArray(), timestamp,
146                  cell.getData().toByteArray()));
147      }
148      addRow(rowModel);
149    }
150    return this;
151  }
152}