1 /*
2 * #%L
3 * ObjectIdElement.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 static com.allanbank.mongodb.util.Assertions.assertNotNull;
23
24 import com.allanbank.mongodb.bson.Element;
25 import com.allanbank.mongodb.bson.ElementType;
26 import com.allanbank.mongodb.bson.Visitor;
27 import com.allanbank.mongodb.bson.io.StringEncoder;
28
29 /**
30 * A wrapper for a BSON Object Id.
31 *
32 * @api.yes This class is part of the driver's API. Public and protected members
33 * will be deprecated for at least 1 non-bugfix release (version
34 * numbers are <major>.<minor>.<bugfix>) before being
35 * removed or modified.
36 * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
37 */
38 public class ObjectIdElement extends AbstractElement {
39
40 /** The BSON type for a Object Id. */
41 public static final String DEFAULT_NAME = "_id";
42
43 /** The BSON type for a Object Id. */
44 public static final ElementType TYPE = ElementType.OBJECT_ID;
45
46 /** Serialization version for the class. */
47 private static final long serialVersionUID = -3563737127052573642L;
48
49 /**
50 * Computes and returns the number of bytes that are used to encode the
51 * element.
52 *
53 * @param name
54 * The name for the element.
55 * @return The size of the element when encoded in bytes.
56 */
57 private static long computeSize(final String name) {
58 long result = 14; // type (1) + name null byte (1) + id value 12
59 result += StringEncoder.utf8Size(name);
60
61 return result;
62 }
63
64 /** The BSON Object id. */
65 private final ObjectId myId;
66
67 /**
68 * Constructs a new {@link ObjectIdElement}.
69 *
70 * @param name
71 * The name for the BSON Object Id.
72 * @param id
73 * The object id.
74 * @throws IllegalArgumentException
75 * If the {@code name} or {@code id} is <code>null</code>.
76 */
77 public ObjectIdElement(final String name, final ObjectId id) {
78 this(name, id, computeSize(name));
79 }
80
81 /**
82 * Constructs a new {@link ObjectIdElement}.
83 *
84 * @param name
85 * The name for the BSON Object Id.
86 * @param id
87 * The object id.
88 * @param size
89 * The size of the element when encoded in bytes. If not known
90 * then use the
91 * {@link ObjectIdElement#ObjectIdElement(String, ObjectId)}
92 * constructor instead.
93 * @throws IllegalArgumentException
94 * If the {@code name} or {@code id} is <code>null</code>.
95 */
96 public ObjectIdElement(final String name, final ObjectId id, final long size) {
97 super(name, size);
98
99 assertNotNull(id, "ObjectId element's id cannot be null.");
100
101 myId = id;
102 }
103
104 /**
105 * Accepts the visitor and calls the {@link Visitor#visitObjectId} method.
106 *
107 * @see Element#accept(Visitor)
108 */
109 @Override
110 public void accept(final Visitor visitor) {
111 visitor.visitObjectId(getName(), myId);
112 }
113
114 /**
115 * {@inheritDoc}
116 * <p>
117 * Overridden to compare the values if the base class comparison is equals.
118 * </p>
119 */
120 @Override
121 public int compareTo(final Element otherElement) {
122 int result = super.compareTo(otherElement);
123
124 if (result == 0) {
125 final ObjectIdElement other = (ObjectIdElement) otherElement;
126
127 result = myId.compareTo(other.myId);
128 }
129
130 return result;
131 }
132
133 /**
134 * Determines if the passed object is of this same type as this object and
135 * if so that its fields are equal.
136 *
137 * @param object
138 * The object to compare to.
139 *
140 * @see java.lang.Object#equals(java.lang.Object)
141 */
142 @Override
143 public boolean equals(final Object object) {
144 boolean result = false;
145 if (this == object) {
146 result = true;
147 }
148 else if ((object != null) && (getClass() == object.getClass())) {
149 final ObjectIdElement other = (ObjectIdElement) object;
150
151 result = super.equals(object) && myId.equals(other.myId);
152 }
153 return result;
154 }
155
156 /**
157 * Returns the id value.
158 *
159 * @return The id value.
160 */
161 public ObjectId getId() {
162 return myId;
163 }
164
165 /**
166 * {@inheritDoc}
167 */
168 @Override
169 public ElementType getType() {
170 return TYPE;
171 }
172
173 /**
174 * {@inheritDoc}
175 * <p>
176 * Returns the {@link ObjectId}.
177 * </p>
178 */
179 @Override
180 public ObjectId getValueAsObject() {
181 return myId;
182 }
183
184 /**
185 * Computes a reasonable hash code.
186 *
187 * @return The hash code value.
188 */
189 @Override
190 public int hashCode() {
191 int result = 1;
192 result = (31 * result) + super.hashCode();
193 result = (31 * result) + myId.hashCode();
194 return result;
195 }
196
197 /**
198 * {@inheritDoc}
199 * <p>
200 * Returns a new {@link ObjectIdElement}.
201 * </p>
202 */
203 @Override
204 public ObjectIdElement withName(final String name) {
205 if (getName().equals(name)) {
206 return this;
207 }
208 return new ObjectIdElement(name, myId);
209 }
210 }