1 /* 2 * #%L 3 * MongoTimestampElement.java - mongodb-async-driver - Allanbank Consulting, Inc. 4 * %% 5 * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc. 6 * %% 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * #L% 19 */ 20 package com.allanbank.mongodb.bson.element; 21 22 import com.allanbank.mongodb.bson.Element; 23 import com.allanbank.mongodb.bson.ElementType; 24 import com.allanbank.mongodb.bson.Visitor; 25 import com.allanbank.mongodb.bson.io.StringEncoder; 26 27 /** 28 * A wrapper for a BSON (signed 64-bit) Mongo timestamp as 4 byte increment and 29 * 4 byte timestamp. 30 * 31 * @api.yes This class is part of the driver's API. Public and protected members 32 * will be deprecated for at least 1 non-bugfix release (version 33 * numbers are <major>.<minor>.<bugfix>) before being 34 * removed or modified. 35 * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved 36 */ 37 public class MongoTimestampElement extends AbstractElement { 38 39 /** The BSON type for a long. */ 40 public static final ElementType TYPE = ElementType.MONGO_TIMESTAMP; 41 42 /** Serialization version for the class. */ 43 private static final long serialVersionUID = -402083578422199042L; 44 45 /** 46 * Computes and returns the number of bytes that are used to encode the 47 * element. 48 * 49 * @param name 50 * The name for the element. 51 * @return The size of the element when encoded in bytes. 52 */ 53 private static long computeSize(final String name) { 54 long result = 10; // type (1) + name null byte (1) + value (8). 55 result += StringEncoder.utf8Size(name); 56 57 return result; 58 } 59 60 /** The BSON timestamp value as 4 byte increment and 4 byte timestamp. */ 61 private final long myTimestamp; 62 63 /** 64 * Constructs a new {@link MongoTimestampElement}. 65 * 66 * @param name 67 * The name for the BSON long. 68 * @param value 69 * The BSON timestamp value as 4 byte increment and 4 byte 70 * timestamp. 71 * @throws IllegalArgumentException 72 * If the {@code name} is <code>null</code>. 73 */ 74 public MongoTimestampElement(final String name, final long value) { 75 this(name, value, computeSize(name)); 76 } 77 78 /** 79 * Constructs a new {@link MongoTimestampElement}. 80 * 81 * @param name 82 * The name for the BSON long. 83 * @param value 84 * The BSON timestamp value as 4 byte increment and 4 byte 85 * timestamp. 86 * @param size 87 * The size of the element when encoded in bytes. If not known 88 * then use the 89 * {@link MongoTimestampElement#MongoTimestampElement(String, long)} 90 * constructor instead. 91 * @throws IllegalArgumentException 92 * If the {@code name} is <code>null</code>. 93 */ 94 public MongoTimestampElement(final String name, final long value, 95 final long size) { 96 super(name, size); 97 98 myTimestamp = value; 99 } 100 101 /** 102 * Accepts the visitor and calls the {@link Visitor#visitMongoTimestamp} 103 * method. 104 * 105 * @see Element#accept(Visitor) 106 */ 107 @Override 108 public void accept(final Visitor visitor) { 109 visitor.visitMongoTimestamp(getName(), getTime()); 110 } 111 112 /** 113 * {@inheritDoc} 114 * <p> 115 * Overridden to compare the times if the base class comparison is equals. 116 * </p> 117 * <p> 118 * Note that for MongoDB {@link MongoTimestampElement} and 119 * {@link TimestampElement} will return equal based on the type. Care is 120 * taken here to make sure that the values return the same value regardless 121 * of comparison order. 122 * </p> 123 */ 124 @Override 125 public int compareTo(final Element otherElement) { 126 int result = super.compareTo(otherElement); 127 128 if (result == 0) { 129 // Might be a MongoTimestampElement or TimestampElement. 130 final ElementType otherType = otherElement.getType(); 131 132 if (otherType == ElementType.MONGO_TIMESTAMP) { 133 result = compare(getTime(), 134 ((MongoTimestampElement) otherElement).getTime()); 135 } 136 else { 137 result = compare(getTime(), 138 ((TimestampElement) otherElement).getTime()); 139 } 140 } 141 142 return result; 143 } 144 145 /** 146 * Determines if the passed object is of this same type as this object and 147 * if so that its fields are equal. 148 * 149 * @param object 150 * The object to compare to. 151 * 152 * @see java.lang.Object#equals(java.lang.Object) 153 */ 154 @Override 155 public boolean equals(final Object object) { 156 boolean result = false; 157 if (this == object) { 158 result = true; 159 } 160 else if ((object != null) && (getClass() == object.getClass())) { 161 final MongoTimestampElement other = (MongoTimestampElement) object; 162 163 result = super.equals(object) && (myTimestamp == other.myTimestamp); 164 } 165 return result; 166 } 167 168 /** 169 * Returns the BSON Mongo timestamp value as 4 byte increment and 4 byte 170 * timestamp. 171 * 172 * @return The BSON Mongo timestamp value as 4 byte increment and 4 byte 173 * timestamp. 174 */ 175 public long getTime() { 176 return myTimestamp; 177 } 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override 183 public ElementType getType() { 184 return TYPE; 185 } 186 187 /** 188 * {@inheritDoc} 189 * <p> 190 * Returns a {@link Long} with the value of the timestamp. 191 * </p> 192 * <p> 193 * <b>Note:</b> This value will not be recreated is a Object-->Element 194 * conversion. Long with the value of the timestamp is created instead. 195 * </p> 196 */ 197 @Override 198 public Long getValueAsObject() { 199 return Long.valueOf(myTimestamp); 200 } 201 202 /** 203 * Computes a reasonable hash code. 204 * 205 * @return The hash code value. 206 */ 207 @Override 208 public int hashCode() { 209 int result = 1; 210 result = (31 * result) + super.hashCode(); 211 result = (31 * result) + (int) ((myTimestamp >> 32) & 0xFFFFFFFF); 212 result = (31 * result) + (int) (myTimestamp & 0xFFFFFFFF); 213 return result; 214 } 215 216 /** 217 * {@inheritDoc} 218 * <p> 219 * Returns a new {@link MongoTimestampElement}. 220 * </p> 221 */ 222 @Override 223 public MongoTimestampElement withName(final String name) { 224 if (getName().equals(name)) { 225 return this; 226 } 227 return new MongoTimestampElement(name, myTimestamp); 228 } 229 }