1 /*
2 * #%L
3 * DBPointerElement.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.DocumentReference;
25 import com.allanbank.mongodb.bson.Element;
26 import com.allanbank.mongodb.bson.ElementType;
27 import com.allanbank.mongodb.bson.Visitor;
28 import com.allanbank.mongodb.bson.io.StringEncoder;
29
30 /**
31 * A wrapper for a deprecated BSON DB Pointer element.
32 *
33 * @api.yes This class is part of the driver's API. Public and protected members
34 * will be deprecated for at least 1 non-bugfix release (version
35 * numbers are <major>.<minor>.<bugfix>) before being
36 * removed or modified.
37 * @deprecated See BSON Specification.
38 * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
39 */
40 @Deprecated
41 public class DBPointerElement extends AbstractElement {
42
43 /** The BSON type for a Object Id. */
44 public static final ElementType TYPE = ElementType.DB_POINTER;
45
46 /** Serialization version for the class. */
47 private static final long serialVersionUID = 2736569317385382748L;
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 BSON Object Id.
55 * @param dbName
56 * The database name.
57 * @param collectionName
58 * The name of the collection.
59 * @return The size of the element when encoded in bytes.
60 */
61 private static long computeSize(final String name, final String dbName,
62 final String collectionName) {
63 long result = 16; // type (1) + name null byte (1) + dbName "." (1)
64 // + collectionName null byte (1)
65 // + ObjectId length (12) .
66 result += StringEncoder.utf8Size(name);
67 result += StringEncoder.utf8Size(dbName);
68 result += StringEncoder.utf8Size(collectionName);
69
70 return result;
71 }
72
73 /** The name of the collection containing the document. */
74 private final String myCollectionName;
75
76 /** The name of the database containing the document. */
77 private final String myDatabaseName;
78
79 /** The id for the document. */
80 private final ObjectId myId;
81
82 /**
83 * Constructs a new {@link DBPointerElement}.
84 *
85 * @param name
86 * The name for the BSON Object Id.
87 * @param dbName
88 * The database name.
89 * @param collectionName
90 * The name of the collection.
91 * @param id
92 * The object id.
93 * @throws IllegalArgumentException
94 * If the {@code name}, {@code dbName}, {@code collectionName},
95 * or {@code id} is <code>null</code>.
96 */
97 public DBPointerElement(final String name, final String dbName,
98 final String collectionName, final ObjectId id) {
99 this(name, dbName, collectionName, id, computeSize(name, dbName,
100 collectionName));
101 }
102
103 /**
104 * Constructs a new {@link DBPointerElement}.
105 *
106 * @param name
107 * The name for the BSON Object Id.
108 * @param dbName
109 * The database name.
110 * @param collectionName
111 * The name of the collection.
112 * @param id
113 * The object id.
114 * @param size
115 * The size of the element when encoded in bytes. If not known
116 * then use the
117 * {@link DBPointerElement#DBPointerElement(String, String, String, ObjectId)}
118 * constructor instead.
119 * @throws IllegalArgumentException
120 * If the {@code name}, {@code dbName}, {@code collectionName},
121 * or {@code id} is <code>null</code>.
122 */
123 public DBPointerElement(final String name, final String dbName,
124 final String collectionName, final ObjectId id, final long size) {
125 super(name, size);
126
127 assertNotNull(dbName,
128 "DBPointer element's database name cannot be null.");
129 assertNotNull(collectionName,
130 "DBPointer element's collection name cannot be null.");
131 assertNotNull(id, "DBPointer element's object id cannot be null.");
132
133 myDatabaseName = dbName;
134 myCollectionName = collectionName;
135 myId = id;
136 }
137
138 /**
139 * Accepts the visitor and calls the {@link Visitor#visitDBPointer} method.
140 *
141 * @see Element#accept(Visitor)
142 */
143 @Override
144 public void accept(final Visitor visitor) {
145 visitor.visitDBPointer(getName(), myDatabaseName, myCollectionName,
146 myId);
147 }
148
149 /**
150 * {@inheritDoc}
151 * <p>
152 * Overridden to compare the (database, collection, id) if the base class
153 * comparison is equals.
154 * </p>
155 */
156 @Override
157 public int compareTo(final Element otherElement) {
158 int result = super.compareTo(otherElement);
159
160 if (result == 0) {
161 final DBPointerElement other = (DBPointerElement) otherElement;
162
163 result = myDatabaseName.compareTo(other.myDatabaseName);
164 if (result == 0) {
165 result = myCollectionName.compareTo(other.myCollectionName);
166 if (result == 0) {
167 result = myId.compareTo(other.myId);
168 }
169 }
170 }
171
172 return result;
173 }
174
175 /**
176 * Determines if the passed object is of this same type as this object and
177 * if so that its fields are equal.
178 *
179 * @param object
180 * The object to compare to.
181 *
182 * @see java.lang.Object#equals(java.lang.Object)
183 */
184 @Override
185 public boolean equals(final Object object) {
186 boolean result = false;
187 if (this == object) {
188 result = true;
189 }
190 else if ((object != null) && (getClass() == object.getClass())) {
191 final DBPointerElement other = (DBPointerElement) object;
192
193 result = super.equals(object)
194 && myDatabaseName.equals(other.myDatabaseName)
195 && myCollectionName.equals(other.myCollectionName)
196 && myId.equals(other.myId);
197 }
198 return result;
199 }
200
201 /**
202 * Returns the collectionName value.
203 *
204 * @return The collectionName value.
205 */
206 public String getCollectionName() {
207 return myCollectionName;
208 }
209
210 /**
211 * Returns the databaseName value.
212 *
213 * @return The databaseName value.
214 */
215 public String getDatabaseName() {
216 return myDatabaseName;
217 }
218
219 /**
220 * Returns the id value.
221 *
222 * @return The id value.
223 */
224 public ObjectId getId() {
225 return myId;
226 }
227
228 /**
229 * {@inheritDoc}
230 */
231 @Override
232 public ElementType getType() {
233 return TYPE;
234 }
235
236 /**
237 * {@inheritDoc}
238 * <p>
239 * Returns a {@link DocumentReference}.
240 * </p>
241 * <p>
242 * <b>Note:</b> This value will not be recreated is a Object-->Element
243 * conversion. A more generic sub-document following the DBRef convention is
244 * created instead.
245 * </p>
246 */
247 @Override
248 public DocumentReference getValueAsObject() {
249 return new DocumentReference(myDatabaseName, myCollectionName,
250 new ObjectIdElement("_id", myId));
251 }
252
253 /**
254 * Computes a reasonable hash code.
255 *
256 * @return The hash code value.
257 */
258 @Override
259 public int hashCode() {
260 int result = 1;
261 result = (31 * result) + super.hashCode();
262 result = (31 * result) + myDatabaseName.hashCode();
263 result = (31 * result) + myCollectionName.hashCode();
264 result = (31 * result) + myId.hashCode();
265 return result;
266 }
267
268 /**
269 * {@inheritDoc}
270 * <p>
271 * Returns a new {@link DBPointerElement}.
272 * </p>
273 */
274 @Override
275 public DBPointerElement withName(final String name) {
276 if (getName().equals(name)) {
277 return this;
278 }
279 return new DBPointerElement(name, myDatabaseName, myCollectionName,
280 myId);
281 }
282 }