1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.allanbank.mongodb;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.Serializable;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Properties;
28
29 import com.allanbank.mongodb.bson.NumericElement;
30 import com.allanbank.mongodb.util.IOUtils;
31 import com.allanbank.mongodb.util.log.Log;
32 import com.allanbank.mongodb.util.log.LogFactory;
33
34
35
36
37
38
39
40 public class Version implements Serializable, Comparable<Version> {
41
42
43
44
45
46 public static final Version UNKNOWN;
47
48
49 public static final Version VERSION;
50
51
52 public static final Version VERSION_0 = Version.parse("0");
53
54
55 public static final Version VERSION_2_0 = Version.parse("2.0");
56
57
58 public static final Version VERSION_2_2 = Version.parse("2.2");
59
60
61 public static final Version VERSION_2_4 = Version.parse("2.4");
62
63
64 public static final Version VERSION_2_6 = Version.parse("2.6");
65
66
67 protected static final Version VERSION_2_5_2 = Version.parse("2.5.2");
68
69
70 protected static final Version VERSION_2_5_4 = Version.parse("2.5.4");
71
72
73 private static final Log LOG = LogFactory.getLog(Version.class);
74
75
76 private static final long serialVersionUID = 4726973040107711788L;
77
78 static {
79
80 final Properties props = new Properties();
81 InputStream in = null;
82 try {
83 in = Version.class
84 .getResourceAsStream("/META-INF/maven/com.allanbank/"
85 + "mongodb-async-driver/pom.properties");
86 if (in != null) {
87 props.load(in);
88 }
89 }
90 catch (final IOException error) {
91 LOG.info("Could not read the version information for the driver.");
92 }
93 finally {
94 IOUtils.close(in);
95 }
96
97 VERSION = parse(props.getProperty("version", "0-DEVELOPMENT"));
98 UNKNOWN = new Version(new int[0], "UNKNOWN");
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112 public static Version earlier(final Version lhs, final Version rhs) {
113 if ((lhs == null) || ((rhs != null) && (lhs.compareTo(rhs) > 0))) {
114 return rhs;
115 }
116
117 return lhs;
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131 public static Version forWireVersion(final int wireVersion) {
132 Version result = null;
133 if (wireVersion >= 2) {
134 result = VERSION_2_5_4;
135 }
136 else if (wireVersion == 1) {
137 result = VERSION_2_5_2;
138 }
139 else if (wireVersion == 0) {
140 result = VERSION_2_4;
141 }
142
143 return result;
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157 public static Version later(final Version lhs, final Version rhs) {
158 if ((lhs == null) || ((rhs != null) && (lhs.compareTo(rhs) < 0))) {
159 return rhs;
160 }
161 return lhs;
162 }
163
164
165
166
167
168
169
170
171
172 public static Version parse(final List<NumericElement> versionArray) {
173
174 final int[] version = new int[versionArray.size()];
175 for (int i = 0; i < version.length; ++i) {
176 version[i] = versionArray.get(i).getIntValue();
177 }
178
179 return new Version(version, null);
180 }
181
182
183
184
185
186
187
188
189 public static Version parse(final String version) {
190
191 final String[] tokens = version.split("\\.");
192 final int[] versions = new int[tokens.length];
193 String suffix = "";
194 for (int i = 0; i < tokens.length; ++i) {
195 String token = tokens[i];
196
197
198 if (i == (tokens.length - 1)) {
199 final int dashIndex = token.indexOf('-');
200 if (dashIndex >= 0) {
201 suffix = token.substring(dashIndex + 1);
202 token = token.substring(0, dashIndex);
203 }
204 }
205
206 try {
207 versions[i] = Integer.parseInt(token);
208 }
209 catch (final NumberFormatException nfe) {
210 LOG.debug(
211 "Could not parse version string token ('{}') from version '{}'.",
212 token, version);
213 }
214 }
215
216 return new Version(versions, suffix);
217 }
218
219
220 private final String mySuffix;
221
222
223 private final int[] myVersion;
224
225
226
227
228
229
230
231
232
233
234 private Version(final int[] version, final String suffix) {
235 myVersion = version.clone();
236 mySuffix = (suffix != null) ? suffix : "";
237 }
238
239
240
241
242
243
244
245 @Override
246 public int compareTo(final Version other) {
247
248 int compare = 0;
249
250
251 if (UNKNOWN.equals(this)) {
252 compare = UNKNOWN.equals(other) ? 0 : 1;
253 }
254 else if (UNKNOWN.equals(other)) {
255 compare = -1;
256 }
257
258 final int fields = Math.min(myVersion.length, other.myVersion.length);
259 for (int i = 0; (compare == 0) && (i < fields); ++i) {
260 compare = compare(myVersion[i], other.myVersion[i]);
261 }
262
263 if (compare == 0) {
264 compare = compare(myVersion.length, other.myVersion.length);
265 if (compare == 0) {
266 compare = mySuffix.compareTo(other.mySuffix);
267 }
268 }
269
270 return compare;
271 }
272
273
274
275
276
277
278
279
280
281
282 @Override
283 public boolean equals(final Object object) {
284 boolean result = false;
285 if (this == object) {
286 result = true;
287 }
288 else if ((object != null) && (getClass() == object.getClass())) {
289 final Version other = (Version) object;
290
291 result = mySuffix.equals(other.mySuffix)
292 && Arrays.equals(myVersion, other.myVersion);
293 }
294 return result;
295 }
296
297
298
299
300
301
302 @Override
303 public int hashCode() {
304 int result = 1;
305 result = (31 * result) + mySuffix.hashCode();
306 result = (31 * result) + Arrays.hashCode(myVersion);
307 return result;
308 }
309
310
311
312
313
314
315
316 @Override
317 public String toString() {
318 final StringBuilder builder = new StringBuilder();
319 for (int i = 0; i < myVersion.length; ++i) {
320 if (i != 0) {
321 builder.append('.');
322 }
323 builder.append(String.valueOf(myVersion[i]));
324 }
325 if (!mySuffix.isEmpty()) {
326 if (myVersion.length > 0) {
327 builder.append('-');
328 }
329 builder.append(mySuffix);
330 }
331 return builder.toString();
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 protected int compare(final int x, final int y) {
352 return (x < y) ? -1 : ((x == y) ? 0 : 1);
353 }
354
355 }