Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
AbstractMessage |
|
| 1.3846153846153846;1.385 |
1 | /* | |
2 | * #%L | |
3 | * AbstractMessage.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.client.message; | |
21 | ||
22 | import com.allanbank.mongodb.ReadPreference; | |
23 | import com.allanbank.mongodb.bson.io.BsonOutputStream; | |
24 | import com.allanbank.mongodb.bson.io.BufferingBsonOutputStream; | |
25 | import com.allanbank.mongodb.client.Message; | |
26 | import com.allanbank.mongodb.client.Operation; | |
27 | import com.allanbank.mongodb.client.VersionRange; | |
28 | ||
29 | /** | |
30 | * Base class for a MongoDB message. | |
31 | * | |
32 | * @api.no This class is <b>NOT</b> part of the drivers API. This class may be | |
33 | * mutated in incompatible ways between any two releases of the driver. | |
34 | * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved | |
35 | */ | |
36 | public abstract class AbstractMessage implements Message { | |
37 | ||
38 | /** The size of a message header. */ | |
39 | public static final int HEADER_SIZE = Header.SIZE; | |
40 | ||
41 | /** The name of the collection to operate on. */ | |
42 | protected String myCollectionName; | |
43 | ||
44 | /** The name of the database to operate on. */ | |
45 | protected String myDatabaseName; | |
46 | ||
47 | /** The details on which servers may be sent the message. */ | |
48 | private final ReadPreference myReadPreference; | |
49 | ||
50 | /** The required version of the server to support processing the message. */ | |
51 | private final VersionRange myRequiredServerVersionRange; | |
52 | ||
53 | /** | |
54 | * Create a new AbstractMessage. | |
55 | */ | |
56 | 3696 | public AbstractMessage() { |
57 | 3696 | myDatabaseName = ""; |
58 | 3696 | myCollectionName = ""; |
59 | 3696 | myReadPreference = ReadPreference.PRIMARY; |
60 | 3696 | myRequiredServerVersionRange = null; |
61 | 3696 | } |
62 | ||
63 | /** | |
64 | * Create a new AbstractMessage. | |
65 | * | |
66 | * @param databaseName | |
67 | * The name of the database. | |
68 | * @param collectionName | |
69 | * The name of the collection. | |
70 | * @param readPreference | |
71 | * The preferences for which servers to send the message. | |
72 | */ | |
73 | public AbstractMessage(final String databaseName, | |
74 | 1011862 | final String collectionName, final ReadPreference readPreference) { |
75 | 1011862 | myDatabaseName = databaseName; |
76 | 1011862 | myCollectionName = collectionName; |
77 | 1011862 | myReadPreference = readPreference; |
78 | 1011862 | myRequiredServerVersionRange = null; |
79 | 1011862 | } |
80 | ||
81 | /** | |
82 | * Creates a new AbstractMessage. | |
83 | * | |
84 | * @param databaseName | |
85 | * The name of the database. | |
86 | * @param collectionName | |
87 | * The name of the collection. | |
88 | * @param readPreference | |
89 | * The preferences for which servers to send the message. | |
90 | * @param versionRange | |
91 | * The required range of versions of the server to support | |
92 | * processing the message. | |
93 | */ | |
94 | public AbstractMessage(final String databaseName, | |
95 | final String collectionName, final ReadPreference readPreference, | |
96 | 8650 | final VersionRange versionRange) { |
97 | 8650 | myDatabaseName = databaseName; |
98 | 8650 | myCollectionName = collectionName; |
99 | 8650 | myReadPreference = readPreference; |
100 | 8650 | myRequiredServerVersionRange = versionRange; |
101 | 8650 | } |
102 | ||
103 | /** | |
104 | * Determines if the passed object is of this same type as this object and | |
105 | * if so that its fields are equal. | |
106 | * | |
107 | * @param object | |
108 | * The object to compare to. | |
109 | * | |
110 | * @see java.lang.Object#equals(java.lang.Object) | |
111 | */ | |
112 | @Override | |
113 | public boolean equals(final Object object) { | |
114 | 813152 | boolean result = false; |
115 | ||
116 | // This should never return false as derived classes should have | |
117 | // verified. | |
118 | 813152 | if ((object != null) && (getClass() == object.getClass())) { |
119 | 813152 | final AbstractMessage other = (AbstractMessage) object; |
120 | ||
121 | 813152 | result = myCollectionName.equals(other.myCollectionName) |
122 | && myDatabaseName.equals(other.myDatabaseName) | |
123 | && myReadPreference.equals(other.myReadPreference); | |
124 | } | |
125 | 813152 | return result; |
126 | } | |
127 | ||
128 | /** | |
129 | * Returns the name of the collection. | |
130 | * | |
131 | * @return The name of the collection. | |
132 | */ | |
133 | public String getCollectionName() { | |
134 | 117 | return myCollectionName; |
135 | } | |
136 | ||
137 | /** | |
138 | * Returns the name of the database. | |
139 | * | |
140 | * @return The name of the database. | |
141 | */ | |
142 | @Override | |
143 | public String getDatabaseName() { | |
144 | 4774 | return myDatabaseName; |
145 | } | |
146 | ||
147 | /** | |
148 | * {@inheritDoc} | |
149 | * <p> | |
150 | * Returns the message's read preference. | |
151 | * </p> | |
152 | */ | |
153 | @Override | |
154 | public ReadPreference getReadPreference() { | |
155 | 5751 | return myReadPreference; |
156 | } | |
157 | ||
158 | /** | |
159 | * {@inheritDoc} | |
160 | */ | |
161 | @Override | |
162 | public VersionRange getRequiredVersionRange() { | |
163 | 4853 | return myRequiredServerVersionRange; |
164 | } | |
165 | ||
166 | /** | |
167 | * Computes a reasonable hash code. | |
168 | * | |
169 | * @return The hash code value. | |
170 | */ | |
171 | @Override | |
172 | public int hashCode() { | |
173 | 5874717 | int result = 1; |
174 | 5874717 | result = (31 * result) + myCollectionName.hashCode(); |
175 | 5874717 | result = (31 * result) + myDatabaseName.hashCode(); |
176 | 5874717 | result = (31 * result) + myReadPreference.hashCode(); |
177 | 5874717 | return result; |
178 | } | |
179 | ||
180 | /** | |
181 | * Writes the MsgHeader messageLengthField in the header <tt>stream</tt>. | |
182 | * | |
183 | * <pre> | |
184 | * <code> | |
185 | * struct MsgHeader { | |
186 | * int32 messageLength; // total message size, including this | |
187 | * int32 requestID; // identifier for this message | |
188 | * int32 responseTo; // requestID from the original request | |
189 | * // (used in reponses from db) | |
190 | * int32 opCode; // request type - see table below | |
191 | * } | |
192 | * </code> | |
193 | * </pre> | |
194 | * | |
195 | * @param stream | |
196 | * The stream to write to. | |
197 | * @param start | |
198 | * The position of the start of the header for the message. | |
199 | */ | |
200 | protected void finishHeader(final BufferingBsonOutputStream stream, | |
201 | final long start) { | |
202 | ||
203 | 327 | final long end = stream.getPosition(); |
204 | ||
205 | 327 | stream.writeIntAt(start, (int) (end - start)); |
206 | 327 | } |
207 | ||
208 | /** | |
209 | * Initializes the database and collection name from the full database name. | |
210 | * | |
211 | * @param name | |
212 | * The full database name. | |
213 | */ | |
214 | protected void init(final String name) { | |
215 | 3695 | final int firstDot = name.indexOf('.'); |
216 | 3696 | if (firstDot >= 0) { |
217 | 3695 | myDatabaseName = name.substring(0, firstDot); |
218 | 3695 | myCollectionName = name.substring(firstDot + 1); |
219 | } | |
220 | else { | |
221 | 1 | myDatabaseName = name; |
222 | } | |
223 | 3696 | } |
224 | ||
225 | /** | |
226 | * Writes the MsgHeader to the <tt>stream</tt>. | |
227 | * | |
228 | * <pre> | |
229 | * <code> | |
230 | * struct MsgHeader { | |
231 | * int32 messageLength; // total message size, including this | |
232 | * int32 requestID; // identifier for this message | |
233 | * int32 responseTo; // requestID from the original request | |
234 | * // (used in reponses from db) | |
235 | * int32 opCode; // request type - see table below | |
236 | * } | |
237 | * </code> | |
238 | * </pre> | |
239 | * | |
240 | * @param stream | |
241 | * The stream to write to. | |
242 | * @param requestId | |
243 | * The requestID from above. | |
244 | * @param responseTo | |
245 | * The responseTo from above. | |
246 | * @param op | |
247 | * The operation for the opCode field. | |
248 | * @param length | |
249 | * The length of the message including the header. | |
250 | */ | |
251 | protected void writeHeader(final BsonOutputStream stream, | |
252 | final int requestId, final int responseTo, final Operation op, | |
253 | final int length) { | |
254 | 3473 | stream.writeInt(length); |
255 | 3473 | stream.writeInt(requestId); |
256 | 3473 | stream.writeInt(responseTo); |
257 | 3473 | stream.writeInt(op.getCode()); |
258 | 3473 | } |
259 | ||
260 | /** | |
261 | * Writes the MsgHeader to the <tt>stream</tt>. | |
262 | * | |
263 | * <pre> | |
264 | * <code> | |
265 | * struct MsgHeader { | |
266 | * int32 messageLength; // total message size, including this | |
267 | * int32 requestID; // identifier for this message | |
268 | * int32 responseTo; // requestID from the original request | |
269 | * // (used in reponses from db) | |
270 | * int32 opCode; // request type - see table below | |
271 | * } | |
272 | * </code> | |
273 | * </pre> | |
274 | * | |
275 | * @param stream | |
276 | * The stream to write to. | |
277 | * @param requestId | |
278 | * The requestID from above. | |
279 | * @param responseTo | |
280 | * The responseTo from above. | |
281 | * @param op | |
282 | * The operation for the opCode field. | |
283 | * @return The position of the start of the header for the message. | |
284 | */ | |
285 | protected long writeHeader(final BufferingBsonOutputStream stream, | |
286 | final int requestId, final int responseTo, final Operation op) { | |
287 | ||
288 | 327 | final long start = stream.getPosition(); |
289 | ||
290 | 327 | stream.writeInt(0); |
291 | 327 | stream.writeInt(requestId); |
292 | 327 | stream.writeInt(responseTo); |
293 | 327 | stream.writeInt(op.getCode()); |
294 | ||
295 | 327 | return start; |
296 | } | |
297 | ||
298 | } |