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