1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.graph.property;
25
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.math.BigDecimal;
29 import java.net.URI;
30 import java.util.Calendar;
31 import java.util.Comparator;
32 import java.util.Date;
33 import java.util.UUID;
34 import net.jcip.annotations.Immutable;
35 import org.modeshape.common.util.SecureHash;
36 import org.modeshape.graph.GraphI18n;
37 import org.modeshape.graph.property.basic.StringValueFactory;
38
39
40
41
42
43
44 @Immutable
45 public class ValueComparators {
46
47
48
49
50 public static final Comparator<String> STRING_COMPARATOR = new Comparator<String>() {
51
52 public int compare( String o1,
53 String o2 ) {
54 if (o1 == o2) return 0;
55 if (o1 == null) return -1;
56 if (o2 == null) return 1;
57 return o1.compareTo(o2);
58 }
59 };
60
61
62
63 public static final Comparator<Long> LONG_COMPARATOR = new Comparator<Long>() {
64
65 public int compare( Long o1,
66 Long o2 ) {
67 if (o1 == o2) return 0;
68 if (o1 == null) return -1;
69 if (o2 == null) return 1;
70 return o1.compareTo(o2);
71 }
72 };
73
74
75
76 public static final Comparator<Double> DOUBLE_COMPARATOR = new Comparator<Double>() {
77
78 public int compare( Double o1,
79 Double o2 ) {
80 if (o1 == o2) return 0;
81 if (o1 == null) return -1;
82 if (o2 == null) return 1;
83 return o1.compareTo(o2);
84 }
85 };
86
87
88
89 public static final Comparator<BigDecimal> DECIMAL_COMPARATOR = new Comparator<BigDecimal>() {
90
91 public int compare( BigDecimal o1,
92 BigDecimal o2 ) {
93 if (o1 == o2) return 0;
94 if (o1 == null) return -1;
95 if (o2 == null) return 1;
96 return o1.compareTo(o2);
97 }
98 };
99
100
101
102
103
104 public static final Comparator<Binary> BINARY_COMPARATOR = new Comparator<Binary>() {
105
106 public int compare( Binary o1,
107 Binary o2 ) {
108 if (o1 == o2) return 0;
109 if (o1 == null) return -1;
110 if (o2 == null) return 1;
111 try {
112 o1.acquire();
113 try {
114 o2.acquire();
115 final long len1 = o1.getSize();
116 final long len2 = o2.getSize();
117 if (len1 < len2) return -1;
118 if (len1 > len2) return 1;
119
120
121 byte[] hash1 = o1.getHash();
122 byte[] hash2 = o2.getHash();
123 if (hash1.length != 0 || hash2.length != 0) {
124 assert hash1.length == hash2.length;
125 for (int i = 0; i != hash1.length; ++i) {
126 int diff = hash1[i] - hash2[i];
127 if (diff != 0) return diff;
128 }
129 return 0;
130
131
132 }
133
134
135
136
137
138
139 InputStream stream1 = null;
140 InputStream stream2 = null;
141 try {
142 stream1 = o1.getStream();
143 stream2 = o2.getStream();
144 byte[] buffer1 = new byte[1024];
145 byte[] buffer2 = new byte[1024];
146 while (true) {
147 int numRead1 = stream1.read(buffer1);
148 if (numRead1 < 0) break;
149 int numRead2 = stream2.read(buffer2);
150 if (numRead1 != numRead2) {
151 throw new IoException(GraphI18n.errorReadingPropertyValueBytes.text());
152 }
153 for (int i = 0; i != numRead1; ++i) {
154 int diff = buffer1[i] - buffer2[i];
155 if (diff != 0) return diff;
156 }
157 }
158 return 0;
159 } catch (IOException e) {
160 throw new IoException(GraphI18n.errorReadingPropertyValueBytes.text());
161 } finally {
162 if (stream1 != null) {
163 try {
164 stream1.close();
165 } catch (IOException e) {
166
167 }
168 }
169 if (stream2 != null) {
170 try {
171 stream2.close();
172 } catch (IOException e) {
173
174 }
175 }
176 }
177 } finally {
178 o2.release();
179 }
180 } finally {
181 o1.release();
182 }
183 }
184 };
185
186
187
188 public static final Comparator<Boolean> BOOLEAN_COMPARATOR = new Comparator<Boolean>() {
189
190 public int compare( Boolean o1,
191 Boolean o2 ) {
192 if (o1 == o2) return 0;
193 if (o1 == null) return -1;
194 if (o2 == null) return 1;
195 return o1.compareTo(o2);
196 }
197 };
198
199
200
201 public static final Comparator<DateTime> DATE_TIME_COMPARATOR = new Comparator<DateTime>() {
202
203 public int compare( DateTime o1,
204 DateTime o2 ) {
205 if (o1 == o2) return 0;
206 if (o1 == null) return -1;
207 if (o2 == null) return 1;
208 return o1.compareTo(o2);
209 }
210 };
211
212
213
214 public static final Comparator<Date> DATE_COMPARATOR = new Comparator<Date>() {
215
216 public int compare( Date o1,
217 Date o2 ) {
218 if (o1 == o2) return 0;
219 if (o1 == null) return -1;
220 if (o2 == null) return 1;
221 return o1.compareTo(o2);
222 }
223 };
224
225
226
227 public static final Comparator<Calendar> CALENDAR_COMPARATOR = new Comparator<Calendar>() {
228
229 public int compare( Calendar o1,
230 Calendar o2 ) {
231 if (o1 == o2) return 0;
232 if (o1 == null) return -1;
233 if (o2 == null) return 1;
234 return o1.compareTo(o2);
235 }
236 };
237
238
239
240 public static final Comparator<Name> NAME_COMPARATOR = new Comparator<Name>() {
241
242 public int compare( Name o1,
243 Name o2 ) {
244 if (o1 == o2) return 0;
245 if (o1 == null) return -1;
246 if (o2 == null) return 1;
247 return o1.compareTo(o2);
248 }
249 };
250
251
252
253 public static final Comparator<Path> PATH_COMPARATOR = new Comparator<Path>() {
254
255 public int compare( Path o1,
256 Path o2 ) {
257 if (o1 == o2) return 0;
258 if (o1 == null) return -1;
259 if (o2 == null) return 1;
260 return o1.compareTo(o2);
261 }
262 };
263
264
265
266 public static final Comparator<Path.Segment> PATH_SEGMENT_COMPARATOR = new Comparator<Path.Segment>() {
267
268 public int compare( Path.Segment o1,
269 Path.Segment o2 ) {
270 if (o1 == o2) return 0;
271 if (o1 == null) return -1;
272 if (o2 == null) return 1;
273 return o1.compareTo(o2);
274 }
275 };
276
277
278
279 public static final Comparator<Path.Segment> PATH_SEGMENT_NAME_COMPARATOR = new Comparator<Path.Segment>() {
280
281 public int compare( Path.Segment o1,
282 Path.Segment o2 ) {
283 if (o1 == o2) return 0;
284 if (o1 == null) return -1;
285 if (o2 == null) return 1;
286 return o1.getName().compareTo(o2.getName());
287 }
288 };
289
290
291
292 public static final Comparator<URI> URI_COMPARATOR = new Comparator<URI>() {
293
294 public int compare( URI o1,
295 URI o2 ) {
296 if (o1 == o2) return 0;
297 if (o1 == null) return -1;
298 if (o2 == null) return 1;
299 return o1.compareTo(o2);
300 }
301 };
302
303
304
305 public static final Comparator<UUID> UUID_COMPARATOR = new Comparator<UUID>() {
306
307 public int compare( UUID o1,
308 UUID o2 ) {
309 if (o1 == o2) return 0;
310 if (o1 == null) return -1;
311 if (o2 == null) return 1;
312 return o1.compareTo(o2);
313 }
314 };
315
316
317
318 public static final Comparator<Reference> REFERENCE_COMPARATOR = new Comparator<Reference>() {
319
320 public int compare( Reference o1,
321 Reference o2 ) {
322 if (o1 == o2) return 0;
323 if (o1 == null) return -1;
324 if (o2 == null) return 1;
325 return o1.compareTo(o2);
326 }
327 };
328
329
330
331 public static final Comparator<Object> OBJECT_COMPARATOR = new Comparator<Object>() {
332
333 @SuppressWarnings( "unchecked" )
334 public int compare( Object o1,
335 Object o2 ) {
336 if (o1 == o2) return 0;
337 if (o1 == null) return -1;
338 if (o2 == null) return 1;
339 PropertyType type1 = PropertyType.discoverType(o1);
340 PropertyType type2 = PropertyType.discoverType(o2);
341
342
343 o1 = type1.getCanonicalValue(o1);
344 o2 = type2.getCanonicalValue(o2);
345
346 if (type1 != PropertyType.OBJECT && type2 != PropertyType.OBJECT) {
347 if (type1 == type2) return ((Comparator<Object>)type1.getComparator()).compare(o1, o2);
348
349
350 if (type1.getValueClass().isAssignableFrom(type2.getValueClass())) {
351 return ((Comparator<Object>)type1.getComparator()).compare(o1, o2);
352 }
353 if (type2.getValueClass().isAssignableFrom(type1.getValueClass())) {
354 return ((Comparator<Object>)type2.getComparator()).compare(o1, o2);
355 }
356 }
357
358
359
360 ValueFactory<String> stringFactory = getStringValueFactory();
361 String value1 = null;
362 String value2 = null;
363 if (type1 == PropertyType.BINARY || type2 == PropertyType.BINARY) {
364 try {
365 byte[] hash1 = null;
366 byte[] hash2 = null;
367
368
369 if (type1 == PropertyType.BINARY) {
370 value2 = stringFactory.create(o2);
371 hash2 = SecureHash.getHash(SecureHash.Algorithm.SHA_1, value2.getBytes());
372 hash1 = ((Binary)o1).getHash();
373 } else {
374 assert type2 == PropertyType.BINARY;
375 value1 = stringFactory.create(o1);
376 hash1 = SecureHash.getHash(SecureHash.Algorithm.SHA_1, value1.getBytes());
377 hash2 = ((Binary)o2).getHash();
378 }
379
380 if (hash1.length == hash2.length) {
381 for (int i = 0; i != hash1.length; ++i) {
382 int diff = hash1[i] - hash2[i];
383 if (diff != 0) return diff;
384 }
385 return 0;
386 }
387 } catch (Throwable error) {
388
389 }
390 }
391
392
393 if (value1 == null) value1 = stringFactory.create(o1);
394 if (value2 == null) value2 = stringFactory.create(o2);
395 return value1.compareTo(value2);
396 }
397 };
398
399
400
401 private static ValueFactory<String> STRING_VALUE_FACTORY;
402
403 protected static final ValueFactory<String> getStringValueFactory() {
404
405 if (STRING_VALUE_FACTORY == null) {
406 STRING_VALUE_FACTORY = new StringValueFactory(Path.NO_OP_DECODER, Path.NO_OP_ENCODER);
407 }
408 return STRING_VALUE_FACTORY;
409 }
410 }