1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.entry;
20
21
22 import java.io.Externalizable;
23 import java.io.IOException;
24 import java.io.ObjectInput;
25 import java.io.ObjectOutput;
26 import java.util.Arrays;
27 import java.util.Comparator;
28
29 import javax.naming.NamingException;
30
31 import org.apache.directory.shared.ldap.NotImplementedException;
32 import org.apache.directory.shared.ldap.entry.Value;
33 import org.apache.directory.shared.ldap.entry.client.ClientBinaryValue;
34 import org.apache.directory.shared.ldap.schema.AttributeType;
35 import org.apache.directory.shared.ldap.schema.ByteArrayComparator;
36 import org.apache.directory.shared.ldap.schema.MatchingRule;
37 import org.apache.directory.shared.ldap.schema.Normalizer;
38 import org.apache.directory.shared.ldap.util.StringTools;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46
47
48
49
50
51
52 public class ServerBinaryValue extends ClientBinaryValue
53 {
54
55 private static final long serialVersionUID = 2L;
56
57
58 private static final Logger LOG = LoggerFactory.getLogger( ServerBinaryValue.class );
59
60
61
62
63
64
65 private transient AttributeType attributeType;
66
67
68 private transient boolean same;
69
70
71
72
73
74
75
76
77 protected String logAssert( String message )
78 {
79 LOG.error( message );
80 return message;
81 }
82
83
84
85
86
87
88 protected String checkAttributeType( AttributeType attributeType )
89 {
90 try
91 {
92 if ( attributeType == null )
93 {
94 return "The AttributeType parameter should not be null";
95 }
96
97 if ( attributeType.getSyntax() == null )
98 {
99 return "There is no Syntax associated with this attributeType";
100 }
101
102 return null;
103 }
104 catch ( NamingException ne )
105 {
106 return "This AttributeType is incorrect";
107 }
108 }
109
110
111
112
113
114
115
116
117
118
119 public ServerBinaryValue( AttributeType attributeType )
120 {
121 super();
122
123 if ( attributeType == null )
124 {
125 throw new IllegalArgumentException( "The AttributeType parameter should not be null" );
126 }
127
128 try
129 {
130 if ( attributeType.getSyntax() == null )
131 {
132 throw new IllegalArgumentException( "There is no Syntax associated with this attributeType" );
133 }
134
135 if ( attributeType.getSyntax().isHumanReadable() )
136 {
137 LOG.warn( "Treating a value of a human readible attribute {} as binary: ", attributeType.getName() );
138 }
139 }
140 catch( NamingException e )
141 {
142 LOG.error( "Failed to resolve syntax for attributeType {}", attributeType, e );
143 }
144
145 this.attributeType = attributeType;
146 }
147
148
149
150
151
152
153
154
155 public ServerBinaryValue( AttributeType attributeType, byte[] wrapped )
156 {
157 this( attributeType );
158 this.wrapped = wrapped;
159 }
160
161
162
163
164
165
166
167
168
169
170
171 ServerBinaryValue( AttributeType attributeType, byte[] wrapped, byte[] normalizedValue, boolean same, boolean valid )
172 {
173 super( wrapped );
174 this.normalized = true;
175 this.attributeType = attributeType;
176 this.normalizedValue = normalizedValue;
177 this.valid = valid;
178 this.same = same;
179
180 }
181
182
183
184
185
186 public void normalize() throws NamingException
187 {
188 if ( isNormalized() )
189 {
190
191 return;
192 }
193
194 if ( getReference() != null )
195 {
196 Normalizer normalizer = getNormalizer();
197
198 if ( normalizer == null )
199 {
200 normalizedValue = getCopy();
201 setNormalized( false );
202 }
203 else
204 {
205 normalizedValue = ( byte[] ) normalizer.normalize( getCopy() );
206 setNormalized( true );
207 }
208
209 if ( Arrays.equals( super.getReference(), normalizedValue ) )
210 {
211 same = true;
212 }
213 else
214 {
215 same = false;
216 }
217 }
218 else
219 {
220 normalizedValue = null;
221 same = true;
222 setNormalized( false );
223 }
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237 public byte[] getNormalizedValueReference()
238 {
239 if ( isNull() )
240 {
241 return null;
242 }
243
244 if ( !isNormalized() )
245 {
246 try
247 {
248 normalize();
249 }
250 catch ( NamingException ne )
251 {
252 String message = "Cannot normalize the value :" + ne.getMessage();
253 LOG.warn( message );
254 normalized = false;
255 }
256 }
257
258 return normalizedValue;
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272 public byte[] getNormalizedValue()
273 {
274 if ( isNull() )
275 {
276 return null;
277 }
278
279 if ( !normalized )
280 {
281 try
282 {
283 normalize();
284 }
285 catch ( NamingException ne )
286 {
287 String message = "Cannot normalize the value :" + ne.getMessage();
288 LOG.warn( message );
289 normalized = false;
290 }
291 }
292
293 return normalizedValue;
294 }
295
296
297
298
299
300
301
302
303
304
305 public byte[] getNormalizedValueCopy()
306 {
307 if ( isNull() )
308 {
309 return null;
310 }
311
312 if ( normalizedValue == null )
313 {
314 try
315 {
316 normalize();
317 }
318 catch ( NamingException ne )
319 {
320 String message = "Cannot normalize the value :" + ne.getMessage();
321 LOG.warn( message );
322 normalized = false;
323 }
324 }
325
326 if ( normalizedValue != null )
327 {
328 byte[] copy = new byte[ normalizedValue.length ];
329 System.arraycopy( normalizedValue, 0, copy, 0, normalizedValue.length );
330 return copy;
331 }
332 else
333 {
334 return null;
335 }
336 }
337
338
339
340
341
342
343
344
345
346
347
348 public final boolean isValid()
349 {
350 if ( valid != null )
351 {
352 return valid;
353 }
354
355 try
356 {
357 valid = attributeType.getSyntax().getSyntaxChecker().isValidSyntax( getReference() );
358 }
359 catch ( NamingException ne )
360 {
361 String message = "Cannot check the syntax : " + ne.getMessage();
362 LOG.error( message );
363 valid = false;
364 }
365
366 return valid;
367 }
368
369
370
371
372
373 public final boolean isSame()
374 {
375 return same;
376 }
377
378
379
380
381
382
383
384
385 public int compareTo( Value<byte[]> value )
386 {
387 if ( isNull() )
388 {
389 if ( ( value == null ) || value.isNull() )
390 {
391 return 0;
392 }
393 else
394 {
395 return -1;
396 }
397 }
398 else
399 {
400 if ( ( value == null ) || value.isNull() )
401 {
402 return 1;
403 }
404 }
405
406 if ( value instanceof ServerBinaryValue )
407 {
408 ServerBinaryValue binaryValue = ( ServerBinaryValue ) value;
409
410 try
411 {
412 Comparator<? super Value<byte[]>> comparator = getComparator();
413
414 if ( comparator != null )
415 {
416 return getComparator().compare( getNormalizedValueReference(), binaryValue.getNormalizedValueReference() );
417 }
418 else
419 {
420 return ByteArrayComparator.INSTANCE.compare( getNormalizedValueReference(),
421 binaryValue.getNormalizedValueReference() );
422 }
423 }
424 catch ( NamingException e )
425 {
426 String msg = "Failed to compare normalized values for " + Arrays.toString( getReference() )
427 + " and " + value;
428 LOG.error( msg, e );
429 throw new IllegalStateException( msg, e );
430 }
431 }
432
433 String message = "I don't really know how to compare anything other " +
434 "than ServerBinaryValues at this point in time.";
435 LOG.error( message );
436 throw new NotImplementedException( message );
437 }
438
439
440
441
442
443
444 public AttributeType getAttributeType()
445 {
446 return attributeType;
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460
461 public boolean instanceOf( AttributeType attributeType ) throws NamingException
462 {
463 if ( this.attributeType.equals( attributeType ) )
464 {
465 return true;
466 }
467
468 return this.attributeType.isDescentantOf( attributeType );
469 }
470
471
472
473
474
475
476
477
478
479 public int hashCode()
480 {
481
482
483 if ( isNull() )
484 {
485 return 0;
486 }
487
488 return Arrays.hashCode( getNormalizedValueReference() );
489 }
490
491
492
493
494
495
496
497
498
499
500 public boolean equals( Object obj )
501 {
502 if ( this == obj )
503 {
504 return true;
505 }
506
507 if ( ! ( obj instanceof ServerBinaryValue ) )
508 {
509 return false;
510 }
511
512 ServerBinaryValue other = ( ServerBinaryValue ) obj;
513
514 if ( !attributeType.equals( other.attributeType ) )
515 {
516 return false;
517 }
518
519 if ( isNull() )
520 {
521 return other.isNull();
522 }
523
524
525
526 if ( Arrays.equals( wrapped, other.get() ) )
527 {
528 return true;
529 }
530 else
531 {
532 try
533 {
534 Comparator<byte[]> comparator = getComparator();
535
536
537 if ( comparator == null )
538 {
539 return Arrays.equals( getNormalizedValueReference(), other.getNormalizedValueReference() );
540 }
541 else
542 {
543 return comparator.compare( getNormalizedValueReference(), other.getNormalizedValueReference() ) == 0;
544 }
545 }
546 catch ( NamingException ne )
547 {
548 return false;
549 }
550 }
551 }
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566 private MatchingRule getMatchingRule() throws NamingException
567 {
568 MatchingRule mr = attributeType.getEquality();
569
570 if ( mr == null )
571 {
572 mr = attributeType.getOrdering();
573 }
574
575 if ( mr == null )
576 {
577 mr = attributeType.getSubstr();
578 }
579
580 return mr;
581 }
582
583
584
585
586
587
588
589
590
591 private Normalizer getNormalizer() throws NamingException
592 {
593 MatchingRule mr = getMatchingRule();
594
595 if ( mr == null )
596 {
597 return null;
598 }
599
600 return mr.getNormalizer();
601 }
602
603
604
605
606
607
608
609
610
611 private Comparator getComparator() throws NamingException
612 {
613 MatchingRule mr = getMatchingRule();
614
615 if ( mr == null )
616 {
617 return null;
618 }
619
620 return mr.getComparator();
621 }
622
623
624
625
626
627 public ServerBinaryValue clone()
628 {
629 ServerBinaryValue clone = (ServerBinaryValue)super.clone();
630
631 if ( normalizedValue != null )
632 {
633 clone.normalizedValue = new byte[ normalizedValue.length ];
634 System.arraycopy( normalizedValue, 0, clone.normalizedValue, 0, normalizedValue.length );
635 }
636
637 return clone;
638 }
639
640
641
642
643
644
645
646
647 public void writeExternal( ObjectOutput out ) throws IOException
648 {
649 throw new IllegalStateException( "Cannot use standard serialization for a ServerStringValue" );
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 public void serialize( ObjectOutput out ) throws IOException
672 {
673 if ( wrapped != null )
674 {
675
676 out.writeInt( wrapped.length );
677
678
679 if ( wrapped.length > 0 )
680 {
681
682 out.write( wrapped );
683
684
685 try
686 {
687 normalize();
688
689 if ( !normalized )
690 {
691
692
693 out.writeBoolean( false );
694 }
695 else
696 {
697
698 out.writeBoolean( true );
699
700 if ( Arrays.equals( getReference(), normalizedValue ) )
701 {
702
703 out.writeBoolean( true );
704 }
705 else
706 {
707
708 out.writeBoolean( false );
709
710
711 out.write( normalizedValue.length );
712
713 if ( normalizedValue.length > 0 )
714 {
715
716 out.write( normalizedValue );
717 }
718 }
719 }
720 }
721 catch ( NamingException ne )
722 {
723
724
725 normalizedValue = null;
726 out.writeBoolean( false );
727 }
728 }
729 }
730 else
731 {
732
733 out.writeInt( -1 );
734 }
735 }
736
737
738
739
740
741
742
743
744 public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
745 {
746 throw new IllegalStateException( "Cannot use standard serialization for a ServerStringValue" );
747 }
748
749
750
751
752
753
754
755
756
757
758 public void deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
759 {
760
761 int wrappedLength = in.readInt();
762
763 if ( wrappedLength == -1 )
764 {
765
766 same = true;
767 wrapped = null;
768 }
769 else if ( wrappedLength == 0 )
770 {
771 wrapped = StringTools.EMPTY_BYTES;
772 same = true;
773 normalized = true;
774 normalizedValue = wrapped;
775 }
776 else
777 {
778 wrapped = new byte[wrappedLength];
779
780
781 in.readFully( wrapped );
782
783
784 normalized = in.readBoolean();
785
786 if ( normalized )
787 {
788
789 same = in.readBoolean();
790
791 if ( !same )
792 {
793
794 int normalizedLength = in.readInt();
795
796 if ( normalizedLength > 0 )
797 {
798 normalizedValue = new byte[normalizedLength];
799
800
801 in.read( normalizedValue, 0, normalizedLength );
802 }
803 else
804 {
805 normalizedValue = StringTools.EMPTY_BYTES;
806 }
807 }
808 else
809 {
810 normalizedValue = new byte[wrappedLength];
811 System.arraycopy( wrapped, 0, normalizedValue, 0, wrappedLength );
812 }
813 }
814 }
815 }
816 }