1 /* 2 * #%L 3 * LongElement.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.NumericElement; 25 import com.allanbank.mongodb.bson.Visitor; 26 import com.allanbank.mongodb.bson.io.StringEncoder; 27 28 /** 29 * A wrapper for a BSON (signed 64-bit) integer or long. 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 LongElement extends AbstractElement implements NumericElement { 38 39 /** The BSON type for a long. */ 40 public static final ElementType TYPE = ElementType.LONG; 41 42 /** Serialization version for the class. */ 43 private static final long serialVersionUID = -2599658746763036474L; 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 long value. */ 61 private final long myValue; 62 63 /** 64 * Constructs a new {@link LongElement}. 65 * 66 * @param name 67 * The name for the BSON long. 68 * @param value 69 * The BSON integer value. 70 * @throws IllegalArgumentException 71 * If the {@code name} is <code>null</code>. 72 */ 73 public LongElement(final String name, final long value) { 74 this(name, value, computeSize(name)); 75 } 76 77 /** 78 * Constructs a new {@link LongElement}. 79 * 80 * @param name 81 * The name for the BSON long. 82 * @param value 83 * The BSON integer value. 84 * @param size 85 * The size of the element when encoded in bytes. If not known 86 * then use the {@link LongElement#LongElement(String, long)} 87 * constructor instead. 88 * @throws IllegalArgumentException 89 * If the {@code name} is <code>null</code>. 90 */ 91 public LongElement(final String name, final long value, final long size) { 92 super(name, size); 93 94 myValue = value; 95 } 96 97 /** 98 * Accepts the visitor and calls the {@link Visitor#visitLong} method. 99 * 100 * @see Element#accept(Visitor) 101 */ 102 @Override 103 public void accept(final Visitor visitor) { 104 visitor.visitLong(getName(), getValue()); 105 } 106 107 /** 108 * {@inheritDoc} 109 * <p> 110 * Overridden to compare the values if the base class comparison is equals. 111 * </p> 112 * <p> 113 * Note that for MongoDB integers, longs, and doubles will return equal 114 * based on the type. Care is taken here to make sure that double, integer, 115 * and long values return the same value regardless of comparison order by 116 * using the lowest resolution representation of the value. 117 * </p> 118 */ 119 @Override 120 public int compareTo(final Element otherElement) { 121 int result = super.compareTo(otherElement); 122 123 if (result == 0) { 124 // Might be a IntegerElement, LongElement, or DoubleElement. 125 // Compare as integer or long. 126 final NumericElement other = (NumericElement) otherElement; 127 final ElementType otherType = other.getType(); 128 129 if (otherType == ElementType.DOUBLE) { 130 result = Double.compare(getDoubleValue(), 131 other.getDoubleValue()); 132 } 133 else { 134 result = compare(getLongValue(), other.getLongValue()); 135 } 136 } 137 138 return result; 139 } 140 141 /** 142 * Determines if the passed object is of this same type as this object and 143 * if so that its fields are equal. 144 * 145 * @param object 146 * The object to compare to. 147 * 148 * @see java.lang.Object#equals(java.lang.Object) 149 */ 150 @Override 151 public boolean equals(final Object object) { 152 boolean result = false; 153 if (this == object) { 154 result = true; 155 } 156 else if ((object != null) && (getClass() == object.getClass())) { 157 final LongElement other = (LongElement) object; 158 159 result = super.equals(object) && (myValue == other.myValue); 160 } 161 return result; 162 } 163 164 /** 165 * {@inheritDoc} 166 * <p> 167 * Overridden to return the value as a double. 168 * </p> 169 */ 170 @Override 171 public double getDoubleValue() { 172 return myValue; 173 } 174 175 /** 176 * {@inheritDoc} 177 * <p> 178 * Overridden to cast the long value to an integer. 179 * </p> 180 */ 181 @Override 182 public int getIntValue() { 183 return (int) myValue; 184 } 185 186 /** 187 * {@inheritDoc} 188 * <p> 189 * Overridden to return the value. 190 * </p> 191 */ 192 @Override 193 public long getLongValue() { 194 return myValue; 195 } 196 197 /** 198 * {@inheritDoc} 199 */ 200 @Override 201 public ElementType getType() { 202 return TYPE; 203 } 204 205 /** 206 * Returns the BSON long value. 207 * 208 * @return The BSON long value. 209 */ 210 public long getValue() { 211 return myValue; 212 } 213 214 /** 215 * {@inheritDoc} 216 * <p> 217 * Returns a {@link Long} with the value. 218 * </p> 219 */ 220 @Override 221 public Long getValueAsObject() { 222 return Long.valueOf(myValue); 223 } 224 225 /** 226 * {@inheritDoc} 227 * <p> 228 * Returns the result of {@link Long#toString(long)}. 229 * </p> 230 */ 231 @Override 232 public String getValueAsString() { 233 return Long.toString(myValue); 234 } 235 236 /** 237 * Computes a reasonable hash code. 238 * 239 * @return The hash code value. 240 */ 241 @Override 242 public int hashCode() { 243 int result = 1; 244 result = (31 * result) + super.hashCode(); 245 result = (31 * result) + (int) (myValue & 0xFFFFFFFF); 246 result = (31 * result) + (int) ((myValue >> 32) & 0xFFFFFFFF); 247 return result; 248 } 249 250 /** 251 * {@inheritDoc} 252 * <p> 253 * Returns a new {@link LongElement}. 254 * </p> 255 */ 256 @Override 257 public LongElement withName(final String name) { 258 if (getName().equals(name)) { 259 return this; 260 } 261 return new LongElement(name, myValue); 262 } 263 }