1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.api.ldap.model.entry;
20
21
22 import java.io.IOException;
23 import java.io.ObjectInput;
24 import java.io.ObjectOutput;
25 import java.util.Arrays;
26 import java.util.Comparator;
27
28 import org.apache.directory.api.i18n.I18n;
29 import org.apache.directory.api.ldap.model.exception.LdapException;
30 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
31 import org.apache.directory.api.ldap.model.schema.AttributeType;
32 import org.apache.directory.api.ldap.model.schema.LdapComparator;
33 import org.apache.directory.api.ldap.model.schema.MatchingRule;
34 import org.apache.directory.api.ldap.model.schema.Normalizer;
35 import org.apache.directory.api.ldap.model.schema.comparators.ByteArrayComparator;
36 import org.apache.directory.api.util.Strings;
37
38
39
40
41
42
43
44
45
46
47 public class BinaryValue extends AbstractValue<byte[]>
48 {
49
50 public static final long serialVersionUID = 2L;
51
52
53
54
55
56
57
58 BinaryValue( AttributeType attributeType )
59 {
60 if ( attributeType != null )
61 {
62
63 if ( attributeType.getSyntax() == null )
64 {
65 throw new IllegalArgumentException( I18n.err( I18n.ERR_04445 ) );
66 }
67
68 if ( attributeType.getSyntax().isHumanReadable() )
69 {
70 LOG.warn( "Treating a value of a human readible attribute {} as binary: ", attributeType.getName() );
71 }
72
73 this.attributeType = attributeType;
74 }
75 }
76
77
78
79
80
81
82
83 public BinaryValue( byte[] value )
84 {
85 if ( value != null )
86 {
87 this.wrappedValue = new byte[value.length];
88 this.normalizedValue = new byte[value.length];
89 System.arraycopy( value, 0, this.wrappedValue, 0, value.length );
90 System.arraycopy( value, 0, this.normalizedValue, 0, value.length );
91 }
92 else
93 {
94 this.wrappedValue = null;
95 this.normalizedValue = null;
96 }
97 }
98
99
100
101
102
103
104
105
106
107
108 public BinaryValue( AttributeType attributeType, byte[] value ) throws LdapInvalidAttributeValueException
109 {
110 this( value );
111 apply( attributeType );
112 }
113
114
115
116
117
118
119
120
121
122
123 public byte[] getNormValue()
124 {
125 if ( isNull() )
126 {
127 return null;
128 }
129
130 byte[] copy = new byte[normalizedValue.length];
131 System.arraycopy( normalizedValue, 0, copy, 0, normalizedValue.length );
132 return copy;
133 }
134
135
136
137
138
139
140 public int compareTo( Value<byte[]> value )
141 {
142 if ( isNull() )
143 {
144 if ( ( value == null ) || value.isNull() )
145 {
146 return 0;
147 }
148 else
149 {
150 return -1;
151 }
152 }
153 else
154 {
155 if ( ( value == null ) || value.isNull() )
156 {
157 return 1;
158 }
159 }
160
161 BinaryValue binaryValue = ( BinaryValue ) value;
162
163 if ( attributeType != null )
164 {
165 try
166 {
167 LdapComparator<byte[]> comparator = getLdapComparator();
168
169 if ( comparator != null )
170 {
171 return comparator
172 .compare( getNormReference(), binaryValue.getNormReference() );
173 }
174 else
175 {
176 return new ByteArrayComparator( null ).compare( getNormReference(), binaryValue
177 .getNormReference() );
178 }
179 }
180 catch ( LdapException e )
181 {
182 String msg = I18n.err( I18n.ERR_04443, Arrays.toString( getReference() ), value );
183 LOG.error( msg, e );
184 throw new IllegalStateException( msg, e );
185 }
186 }
187 else
188 {
189 return new ByteArrayComparator( null ).compare( getNormValue(), binaryValue.getNormValue() );
190 }
191 }
192
193
194
195
196
197
198
199
200
201 public int hashCode()
202 {
203 if ( h == 0 )
204 {
205
206
207 if ( isNull() )
208 {
209 return 0;
210 }
211
212 byte[] normalizedValue = getNormReference();
213 h = Arrays.hashCode( normalizedValue );
214 }
215
216 return h;
217 }
218
219
220
221
222
223
224
225
226 public boolean equals( Object obj )
227 {
228 if ( this == obj )
229 {
230 return true;
231 }
232
233 if ( !( obj instanceof BinaryValue ) )
234 {
235 return false;
236 }
237
238 BinaryValue other = ( BinaryValue ) obj;
239
240
241 if ( attributeType != null )
242 {
243
244 if ( other.attributeType != null )
245 {
246 if ( attributeType.getOid().equals( other.getAttributeType().getOid() ) )
247 {
248
249
250
251
252 if ( isNull() )
253 {
254 return other.isNull();
255 }
256
257
258
259 if ( Arrays.equals( wrappedValue, other.wrappedValue ) )
260 {
261 return true;
262 }
263
264
265 try
266 {
267 Comparator<byte[]> comparator = getLdapComparator();
268
269
270 if ( comparator == null )
271 {
272 return Arrays.equals( getNormReference(), other.getNormReference() );
273 }
274 else
275 {
276 return comparator.compare( getNormReference(), other.getNormReference() ) == 0;
277 }
278 }
279 catch ( LdapException ne )
280 {
281 return false;
282 }
283 }
284 else
285 {
286
287 return false;
288 }
289 }
290 else
291 {
292
293
294
295 if ( isNull() )
296 {
297 return other.isNull();
298 }
299
300
301 try
302 {
303 Comparator<byte[]> comparator = getLdapComparator();
304
305
306
307 MatchingRule equality = getAttributeType().getEquality();
308
309 if ( equality == null )
310 {
311
312 return Arrays.equals( getNormReference(), other.getNormReference() );
313 }
314
315 Normalizer normalizer = equality.getNormalizer();
316
317 BinaryValue otherValue = ( BinaryValue ) normalizer.normalize( other );
318
319 if ( comparator == null )
320 {
321 return Arrays.equals( getNormReference(), otherValue.getNormReference() );
322 }
323 else
324 {
325 return comparator.compare( getNormReference(), otherValue.getNormReference() ) == 0;
326 }
327 }
328 catch ( LdapException ne )
329 {
330 return false;
331 }
332 }
333 }
334 else
335 {
336
337 if ( other.attributeType != null )
338 {
339
340
341
342 if ( isNull() )
343 {
344 return other.isNull();
345 }
346
347 try
348 {
349 Comparator<byte[]> comparator = other.getLdapComparator();
350
351
352
353 MatchingRule equality = other.getAttributeType().getEquality();
354
355 if ( equality == null )
356 {
357
358 return Arrays.equals( getNormReference(), other.getNormReference() );
359 }
360
361 Normalizer normalizer = equality.getNormalizer();
362
363 BinaryValue thisValue = ( BinaryValue ) normalizer.normalize( this );
364
365 if ( comparator == null )
366 {
367 return Arrays.equals( thisValue.getNormReference(), other.getNormReference() );
368 }
369 else
370 {
371 return comparator.compare( thisValue.getNormReference(), other.getNormReference() ) == 0;
372 }
373 }
374 catch ( LdapException ne )
375 {
376 return false;
377 }
378 }
379 else
380 {
381
382 if ( isNull() )
383 {
384 return other.isNull();
385 }
386
387
388 return Arrays.equals( getNormReference(), other.getNormReference() );
389 }
390 }
391 }
392
393
394
395
396
397
398
399
400 public BinaryValue clone()
401 {
402 BinaryValue clone = ( BinaryValue ) super.clone();
403
404
405 if ( normalizedValue != null )
406 {
407 clone.normalizedValue = new byte[normalizedValue.length];
408 System.arraycopy( normalizedValue, 0, clone.normalizedValue, 0, normalizedValue.length );
409 }
410
411 if ( wrappedValue != null )
412 {
413 clone.wrappedValue = new byte[wrappedValue.length];
414 System.arraycopy( wrappedValue, 0, clone.wrappedValue, 0, wrappedValue.length );
415 }
416
417 return clone;
418 }
419
420
421
422
423
424 public byte[] getValue()
425 {
426 if ( wrappedValue == null )
427 {
428 return null;
429 }
430
431 final byte[] copy = new byte[wrappedValue.length];
432 System.arraycopy( wrappedValue, 0, copy, 0, wrappedValue.length );
433
434 return copy;
435 }
436
437
438
439
440
441
442
443 public boolean isHumanReadable()
444 {
445 return false;
446 }
447
448
449
450
451
452 public int length()
453 {
454 return wrappedValue != null ? wrappedValue.length : 0;
455 }
456
457
458
459
460
461
462
463
464 public byte[] getBytes()
465 {
466 return getValue();
467 }
468
469
470
471
472
473
474
475 public String getString()
476 {
477 return Strings.utf8ToString( wrappedValue );
478 }
479
480
481
482
483
484
485
486
487
488
489
490 public static BinaryValue deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
491 {
492 BinaryValue value = new BinaryValue( ( AttributeType ) null );
493 value.readExternal( in );
494
495 return value;
496 }
497
498
499
500
501
502
503
504
505
506
507
508 public static BinaryValue deserialize( AttributeType attributeType, ObjectInput in ) throws IOException,
509 ClassNotFoundException
510 {
511 BinaryValue value = new BinaryValue( attributeType );
512 value.readExternal( in );
513
514 return value;
515 }
516
517
518
519
520
521 public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
522 {
523
524 boolean isHR = in.readBoolean();
525
526 if ( isHR )
527 {
528 throw new IOException( "The serialized value is not a Binary value" );
529 }
530
531 int wrappedLength = in.readInt();
532
533 if ( wrappedLength >= 0 )
534 {
535 wrappedValue = new byte[wrappedLength];
536
537 in.readFully( wrappedValue );
538 }
539
540
541 boolean normalized = in.readBoolean();
542
543 if ( normalized )
544 {
545 int normalizedLength = in.readInt();
546
547 if ( normalizedLength >= 0 )
548 {
549 normalizedValue = new byte[normalizedLength];
550
551 in.readFully( normalizedValue );
552 }
553 }
554 else
555 {
556 if ( attributeType != null )
557 {
558 try
559 {
560 normalizedValue = attributeType.getEquality().getNormalizer().normalize( this ).getBytes();
561 MatchingRule equality = attributeType.getEquality();
562
563 if ( equality == null )
564 {
565 if ( wrappedLength >= 0 )
566 {
567 normalizedValue = new byte[wrappedLength];
568
569 System.arraycopy( wrappedValue, 0, normalizedValue, 0, wrappedLength );
570 }
571 }
572 else
573 {
574 Normalizer normalizer = equality.getNormalizer();
575
576 if ( normalizer != null )
577 {
578 normalizedValue = normalizer.normalize( this ).getBytes();
579 }
580 else
581 {
582 if ( wrappedLength >= 0 )
583 {
584 normalizedValue = new byte[wrappedLength];
585
586 System.arraycopy( wrappedValue, 0, normalizedValue, 0, wrappedLength );
587 }
588 }
589 }
590 }
591 catch ( LdapException le )
592 {
593
594 if ( wrappedLength >= 0 )
595 {
596 normalizedValue = new byte[wrappedLength];
597
598 System.arraycopy( wrappedValue, 0, normalizedValue, 0, wrappedLength );
599 }
600 }
601 }
602 else
603 {
604
605 if ( wrappedLength >= 0 )
606 {
607 normalizedValue = new byte[wrappedLength];
608
609 System.arraycopy( wrappedValue, 0, normalizedValue, 0, wrappedLength );
610 }
611 }
612 }
613
614
615 h = in.readInt();
616 }
617
618
619
620
621
622 public void writeExternal( ObjectOutput out ) throws IOException
623 {
624
625 out.writeBoolean( BINARY );
626
627
628 if ( wrappedValue != null )
629 {
630 out.writeInt( wrappedValue.length );
631
632 if ( wrappedValue.length > 0 )
633 {
634 out.write( wrappedValue, 0, wrappedValue.length );
635 }
636 }
637 else
638 {
639 out.writeInt( -1 );
640 }
641
642
643 if ( attributeType != null )
644 {
645 out.writeBoolean( true );
646
647
648 if ( normalizedValue != null )
649 {
650 out.writeInt( normalizedValue.length );
651
652 if ( normalizedValue.length > 0 )
653 {
654 out.write( normalizedValue, 0, normalizedValue.length );
655 }
656 }
657 else
658 {
659 out.writeInt( -1 );
660 }
661 }
662 else
663 {
664 out.writeBoolean( false );
665 }
666
667
668 out.writeInt( h );
669
670 out.flush();
671 }
672
673
674
675
676
677
678
679 public String toString()
680 {
681 if ( wrappedValue == null )
682 {
683 return "null";
684 }
685 else if ( wrappedValue.length > 16 )
686 {
687
688 byte[] copy = new byte[16];
689
690 System.arraycopy( wrappedValue, 0, copy, 0, 16 );
691
692 return Strings.dumpBytes( copy ) + "...";
693 }
694 else
695 {
696 return Strings.dumpBytes( wrappedValue );
697 }
698 }
699 }