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;
024
025import javax.xml.bind.annotation.XmlAccessType;
026import javax.xml.bind.annotation.XmlAccessorType;
027import javax.xml.bind.annotation.XmlAttribute;
028import javax.xml.bind.annotation.XmlRootElement;
029import javax.xml.bind.annotation.XmlValue;
030
031import com.fasterxml.jackson.annotation.JsonProperty;
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.util.ByteStringer;
036import org.apache.yetus.audience.InterfaceAudience;
037import org.apache.hadoop.hbase.CellUtil;
038import org.apache.hadoop.hbase.HConstants;
039import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
040import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
041import org.apache.hadoop.hbase.rest.protobuf.generated.CellMessage.Cell;
042
043/**
044 * Representation of a cell. A cell is a single value associated a column and
045 * optional qualifier, and either the timestamp when it was stored or the user-
046 * provided timestamp if one was explicitly supplied.
047 *
048 * <pre>
049 * &lt;complexType name="Cell"&gt;
050 *   &lt;sequence&gt;
051 *     &lt;element name="value" maxOccurs="1" minOccurs="1"&gt;
052 *       &lt;simpleType&gt;
053 *         &lt;restriction base="base64Binary"/&gt;
054 *       &lt;/simpleType&gt;
055 *     &lt;/element&gt;
056 *   &lt;/sequence&gt;
057 *   &lt;attribute name="column" type="base64Binary" /&gt;
058 *   &lt;attribute name="timestamp" type="int" /&gt;
059 * &lt;/complexType&gt;
060 * </pre>
061 */
062@XmlRootElement(name="Cell")
063@XmlAccessorType(XmlAccessType.FIELD)
064@InterfaceAudience.Private
065public class CellModel implements ProtobufMessageHandler, Serializable {
066  private static final long serialVersionUID = 1L;
067
068  @JsonProperty("column")
069  @XmlAttribute
070  private byte[] column;
071
072  @JsonProperty("timestamp")
073  @XmlAttribute
074  private long timestamp = HConstants.LATEST_TIMESTAMP;
075
076  @JsonProperty("$")
077  @XmlValue
078  private byte[] value;
079
080  /**
081   * Default constructor
082   */
083  public CellModel() {}
084
085  /**
086   * Constructor
087   * @param column
088   * @param value
089   */
090  public CellModel(byte[] column, byte[] value) {
091    this(column, HConstants.LATEST_TIMESTAMP, value);
092  }
093
094  /**
095   * Constructor
096   * @param column
097   * @param qualifier
098   * @param value
099   */
100  public CellModel(byte[] column, byte[] qualifier, byte[] value) {
101    this(column, qualifier, HConstants.LATEST_TIMESTAMP, value);
102  }
103
104  /**
105   * Constructor from KeyValue
106   * @param cell
107   */
108  public CellModel(org.apache.hadoop.hbase.Cell cell) {
109    this(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell), cell.getTimestamp(), CellUtil
110        .cloneValue(cell));
111  }
112
113  /**
114   * Constructor
115   * @param column
116   * @param timestamp
117   * @param value
118   */
119  public CellModel(byte[] column, long timestamp, byte[] value) {
120    this.column = column;
121    this.timestamp = timestamp;
122    this.value = value;
123  }
124
125  /**
126   * Constructor
127   * @param column
128   * @param qualifier
129   * @param timestamp
130   * @param value
131   */
132  public CellModel(byte[] column, byte[] qualifier, long timestamp,
133      byte[] value) {
134    this.column = CellUtil.makeColumn(column, qualifier);
135    this.timestamp = timestamp;
136    this.value = value;
137  }
138
139  /**
140   * @return the column
141   */
142  public byte[] getColumn() {
143    return column;
144  }
145
146  /**
147   * @param column the column to set
148   */
149  public void setColumn(byte[] column) {
150    this.column = column;
151  }
152
153  /**
154   * @return true if the timestamp property has been specified by the
155   * user
156   */
157  public boolean hasUserTimestamp() {
158    return timestamp != HConstants.LATEST_TIMESTAMP;
159  }
160
161  /**
162   * @return the timestamp
163   */
164  public long getTimestamp() {
165    return timestamp;
166  }
167
168  /**
169   * @param timestamp the timestamp to set
170   */
171  public void setTimestamp(long timestamp) {
172    this.timestamp = timestamp;
173  }
174
175  /**
176   * @return the value
177   */
178  public byte[] getValue() {
179    return value;
180  }
181
182  /**
183   * @param value the value to set
184   */
185  public void setValue(byte[] value) {
186    this.value = value;
187  }
188
189  @Override
190  public byte[] createProtobufOutput() {
191    Cell.Builder builder = Cell.newBuilder();
192    builder.setColumn(ByteStringer.wrap(getColumn()));
193    builder.setData(ByteStringer.wrap(getValue()));
194    if (hasUserTimestamp()) {
195      builder.setTimestamp(getTimestamp());
196    }
197    return builder.build().toByteArray();
198  }
199
200  @Override
201  public ProtobufMessageHandler getObjectFromMessage(byte[] message)
202      throws IOException {
203    Cell.Builder builder = Cell.newBuilder();
204    ProtobufUtil.mergeFrom(builder, message);
205    setColumn(builder.getColumn().toByteArray());
206    setValue(builder.getData().toByteArray());
207    if (builder.hasTimestamp()) {
208      setTimestamp(builder.getTimestamp());
209    }
210    return this;
211  }
212
213  @Override
214  public boolean equals(Object obj) {
215    if (obj == null) {
216      return false;
217    }
218    if (obj == this) {
219      return true;
220    }
221    if (obj.getClass() != getClass()) {
222      return false;
223    }
224    CellModel cellModel = (CellModel) obj;
225    return new EqualsBuilder().
226        append(column, cellModel.column).
227        append(timestamp, cellModel.timestamp).
228        append(value, cellModel.value).
229        isEquals();
230  }
231
232  @Override
233  public int hashCode() {
234    return new HashCodeBuilder().
235        append(column).
236        append(timestamp).
237        append(value).
238        toHashCode();
239  }
240
241  @Override
242  public String toString() {
243    return new ToStringBuilder(this).
244        append("column", column).
245        append("timestamp", timestamp).
246        append("value", value).
247        toString();
248  }
249}