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