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.Comparator;
26
27 import org.apache.directory.api.i18n.I18n;
28 import org.apache.directory.api.ldap.model.exception.LdapException;
29 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
30 import org.apache.directory.api.ldap.model.schema.AttributeType;
31 import org.apache.directory.api.ldap.model.schema.MatchingRule;
32 import org.apache.directory.api.ldap.model.schema.Normalizer;
33 import org.apache.directory.api.util.Serialize;
34 import org.apache.directory.api.util.Strings;
35 import org.apache.directory.api.util.exception.NotImplementedException;
36
37
38
39
40
41
42
43
44
45
46 public class StringValue extends AbstractValue<String>
47 {
48
49 private static final long serialVersionUID = 2L;
50
51
52 private byte[] bytes;
53
54
55
56
57
58
59
60
61
62
63 public StringValue( AttributeType attributeType )
64 {
65 if ( attributeType != null )
66 {
67
68 if ( attributeType.getSyntax() == null )
69 {
70 throw new IllegalArgumentException( I18n.err( I18n.ERR_04445 ) );
71 }
72
73 if ( !attributeType.getSyntax().isHumanReadable() )
74 {
75 LOG.warn( "Treating a value of a binary attribute {} as a String: "
76 + "\nthis could cause data corruption!", attributeType.getName() );
77 }
78
79 this.attributeType = attributeType;
80 }
81 }
82
83
84
85
86
87
88
89 public StringValue( String value )
90 {
91 this.upValue = value;
92 this.normalizedValue = value;
93 bytes = Strings.getBytesUtf8( value );
94 }
95
96
97
98
99
100
101
102
103 public StringValue( String value, String normalizedValue )
104 {
105 this.upValue = value;
106 this.normalizedValue = normalizedValue;
107 bytes = Strings.getBytesUtf8( normalizedValue );
108 }
109
110
111
112
113
114
115
116
117
118
119 public StringValue( AttributeType attributeType, String value ) throws LdapInvalidAttributeValueException
120 {
121 this( value, value );
122 apply( attributeType );
123 }
124
125
126
127
128
129
130
131
132
133
134
135 public StringValue( AttributeType attributeType, String value, String normValue ) throws LdapInvalidAttributeValueException
136 {
137 this( value, normValue );
138 apply( attributeType );
139 }
140
141
142
143
144
145
146
147
148 @Override
149 public String getValue()
150 {
151
152
153 return upValue;
154 }
155
156
157
158
159
160 @Override
161 public String getNormValue()
162 {
163 return normalizedValue;
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177 @Override
178 public int compareTo( Value<String> value )
179 {
180 if ( isNull() )
181 {
182 if ( ( value == null ) || value.isNull() )
183 {
184 return 0;
185 }
186 else
187 {
188 return -1;
189 }
190 }
191 else if ( ( value == null ) || value.isNull() )
192 {
193 return 1;
194 }
195
196 if ( !( value instanceof StringValue ) )
197 {
198 String message = I18n.err( I18n.ERR_04128, toString(), value.getClass() );
199 LOG.error( message );
200 throw new NotImplementedException( message );
201 }
202
203 StringValue stringValue = ( StringValue ) value;
204
205 if ( attributeType != null )
206 {
207 if ( stringValue.getAttributeType() == null )
208 {
209 return getNormValue().compareTo( stringValue.getNormValue() );
210 }
211 else
212 {
213 if ( !attributeType.equals( stringValue.getAttributeType() ) )
214 {
215 String message = I18n.err( I18n.ERR_04128, toString(), value.getClass() );
216 LOG.error( message );
217 throw new NotImplementedException( message );
218 }
219 }
220 }
221 else
222 {
223 return getNormValue().compareTo( stringValue.getNormValue() );
224 }
225
226 try
227 {
228 return getLdapComparator().compare( getNormValue(), stringValue.getNormValue() );
229 }
230 catch ( LdapException e )
231 {
232 String msg = I18n.err( I18n.ERR_04443, this, value );
233 LOG.error( msg, e );
234 throw new IllegalStateException( msg, e );
235 }
236 }
237
238
239
240
241
242
243
244
245 @Override
246 public StringValue clone()
247 {
248 return ( StringValue ) super.clone();
249 }
250
251
252
253
254
255
256
257
258
259 @Override
260 public int hashCode()
261 {
262 if ( h == 0 )
263 {
264
265
266 if ( isNull() )
267 {
268 return 0;
269 }
270
271
272
273
274
275 String normalized = getNormValue();
276
277 if ( normalized != null )
278 {
279 h = normalized.hashCode();
280 }
281 else
282 {
283 h = 17;
284 }
285 }
286
287 return h;
288 }
289
290
291
292
293
294
295
296 @Override
297 public boolean equals( Object obj )
298 {
299 if ( this == obj )
300 {
301 return true;
302 }
303
304 if ( !( obj instanceof StringValue ) )
305 {
306 return false;
307 }
308
309 StringValue other = ( StringValue ) obj;
310
311
312 if ( attributeType != null )
313 {
314
315 if ( other.attributeType != null )
316 {
317 if ( attributeType.getOid().equals( other.getAttributeType().getOid() ) )
318 {
319
320
321
322
323 if ( isNull() )
324 {
325 return other.isNull();
326 }
327
328
329
330 if ( upValue.equals( other.upValue ) )
331 {
332 return true;
333 }
334
335
336 try
337 {
338 Comparator<String> comparator = getLdapComparator();
339
340
341 if ( comparator == null )
342 {
343 return getNormReference().equals( other.getNormReference() );
344 }
345 else
346 {
347 return comparator.compare( getNormReference(), other.getNormReference() ) == 0;
348 }
349 }
350 catch ( LdapException ne )
351 {
352 return false;
353 }
354 }
355 else
356 {
357
358 return false;
359 }
360 }
361 else
362 {
363
364
365
366 if ( isNull() )
367 {
368 return other.isNull();
369 }
370
371
372 try
373 {
374 Comparator<String> comparator = getLdapComparator();
375
376
377
378 MatchingRule equality = getAttributeType().getEquality();
379
380 if ( equality == null )
381 {
382
383 return getNormReference().equals( other.getNormReference() );
384 }
385
386 Normalizer normalizer = equality.getNormalizer();
387
388 StringValue otherValue = ( StringValue ) normalizer.normalize( other );
389
390 if ( comparator == null )
391 {
392 return getNormReference().equals( otherValue.getNormReference() );
393 }
394 else
395 {
396 return comparator.compare( getNormReference(), otherValue.getNormReference() ) == 0;
397 }
398 }
399 catch ( LdapException ne )
400 {
401 return false;
402 }
403 }
404 }
405 else
406 {
407
408 if ( other.attributeType != null )
409 {
410
411
412
413 if ( isNull() )
414 {
415 return other.isNull();
416 }
417
418 try
419 {
420 Comparator<String> comparator = other.getLdapComparator();
421
422
423
424 MatchingRule equality = other.getAttributeType().getEquality();
425
426 if ( equality == null )
427 {
428
429 return getNormReference().equals( other.getNormReference() );
430 }
431
432 Normalizer normalizer = equality.getNormalizer();
433
434 StringValue thisValue = ( StringValue ) normalizer.normalize( this );
435
436 if ( comparator == null )
437 {
438 return thisValue.getNormReference().equals( other.getNormReference() );
439 }
440 else
441 {
442 return comparator.compare( thisValue.getNormReference(), other.getNormReference() ) == 0;
443 }
444 }
445 catch ( LdapException ne )
446 {
447 return false;
448 }
449 }
450 else
451 {
452
453 if ( isNull() )
454 {
455 return other.isNull();
456 }
457
458
459 return getNormReference().equals( other.getNormReference() );
460 }
461 }
462 }
463
464
465
466
467
468 @Override
469 public boolean isHumanReadable()
470 {
471 return true;
472 }
473
474
475
476
477
478 @Override
479 public int length()
480 {
481 return upValue != null ? upValue.length() : 0;
482 }
483
484
485
486
487
488
489 @Override
490 public byte[] getBytes()
491 {
492 return bytes;
493 }
494
495
496
497
498
499
500
501 @Override
502 public String getString()
503 {
504 return upValue != null ? upValue : "";
505 }
506
507
508
509
510
511
512
513
514
515
516 public static StringValue deserialize( ObjectInput in ) throws IOException, ClassNotFoundException
517 {
518 StringValue value = new StringValue( ( AttributeType ) null );
519 value.readExternal( in );
520
521 return value;
522 }
523
524
525
526
527
528
529
530
531
532
533
534 public static StringValue deserialize( AttributeType attributeType, ObjectInput in ) throws IOException,
535 ClassNotFoundException
536 {
537 StringValue value = new StringValue( attributeType );
538 value.readExternal( in );
539
540 return value;
541 }
542
543
544
545
546
547 @Override
548 public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
549 {
550
551 boolean isHR = in.readBoolean();
552
553 if ( !isHR )
554 {
555 throw new IOException( "The serialized value is not a String value" );
556 }
557
558
559 if ( in.readBoolean() )
560 {
561 upValue = in.readUTF();
562 bytes = Strings.getBytesUtf8( upValue );
563 }
564
565
566 boolean normalized = in.readBoolean();
567
568 if ( normalized )
569 {
570
571 if ( in.readBoolean() )
572 {
573 normalizedValue = in.readUTF();
574 }
575 }
576 else
577 {
578 if ( attributeType != null )
579 {
580 try
581 {
582 MatchingRule equality = attributeType.getEquality();
583
584 if ( equality == null )
585 {
586 normalizedValue = upValue;
587 }
588 else
589 {
590 Normalizer normalizer = equality.getNormalizer();
591
592 if ( normalizer != null )
593 {
594 normalizedValue = normalizer.normalize( upValue );
595 }
596 else
597 {
598 normalizedValue = upValue;
599 }
600 }
601 }
602 catch ( LdapException le )
603 {
604 normalizedValue = upValue;
605 }
606 }
607 else
608 {
609 normalizedValue = upValue;
610 }
611 }
612
613
614 h = in.readInt();
615 }
616
617
618
619
620
621
622
623
624
625 public int serialize( byte[] buffer, int pos )
626 {
627
628
629
630 int length = 1 + 1 + 1 + 4;
631
632 byte[] upValueBytes = null;
633 byte[] normalizedValueBytes = null;
634
635 if ( upValue != null )
636 {
637 upValueBytes = Strings.getBytesUtf8( upValue );
638 length += 4 + upValueBytes.length;
639 }
640
641 if ( attributeType != null )
642 {
643 if ( normalizedValue != null )
644 {
645 normalizedValueBytes = Strings.getBytesUtf8( normalizedValue );
646 length += 1 + 4 + normalizedValueBytes.length;
647 }
648 else
649 {
650 length += 1;
651 }
652 }
653
654
655 if ( buffer.length - pos < length )
656 {
657 throw new ArrayIndexOutOfBoundsException();
658 }
659
660
661 buffer[pos] = Serialize.TRUE;
662 pos++;
663
664
665 if ( upValue != null )
666 {
667 buffer[pos++] = Serialize.TRUE;
668 pos = Serialize.serialize( upValueBytes, buffer, pos );
669 }
670 else
671 {
672 buffer[pos++] = Serialize.FALSE;
673 }
674
675
676 if ( attributeType != null )
677 {
678
679
680
681 buffer[pos++] = Serialize.TRUE;
682
683
684 if ( normalizedValue != null )
685 {
686 buffer[pos++] = Serialize.TRUE;
687 pos = Serialize.serialize( normalizedValueBytes, buffer, pos );
688 }
689 else
690 {
691 buffer[pos++] = Serialize.FALSE;
692 }
693 }
694 else
695 {
696
697 buffer[pos++] = Serialize.FALSE;
698 }
699
700
701 pos = Serialize.serialize( h, buffer, pos );
702
703 return pos;
704 }
705
706
707
708
709
710
711
712
713
714
715 public int deserialize( byte[] buffer, int pos ) throws IOException
716 {
717 if ( ( pos < 0 ) || ( pos >= buffer.length ) )
718 {
719 throw new ArrayIndexOutOfBoundsException();
720 }
721
722
723 boolean isHR = Serialize.deserializeBoolean( buffer, pos );
724 pos++;
725
726 if ( !isHR )
727 {
728 throw new IOException( "The serialized value is not a String value" );
729 }
730
731
732 boolean hasWrappedValue = Serialize.deserializeBoolean( buffer, pos );
733 pos++;
734
735 if ( hasWrappedValue )
736 {
737 byte[] upValueBytes = Serialize.deserializeBytes( buffer, pos );
738 pos += 4 + upValueBytes.length;
739 upValue = Strings.utf8ToString( upValueBytes );
740 }
741
742
743 boolean hasAttributeType = Serialize.deserializeBoolean( buffer, pos );
744 pos++;
745
746 if ( hasAttributeType )
747 {
748
749 boolean hasNormalizedValue = Serialize.deserializeBoolean( buffer, pos );
750 pos++;
751
752 if ( hasNormalizedValue )
753 {
754 byte[] normalizedValueBytes = Serialize.deserializeBytes( buffer, pos );
755 pos += 4 + normalizedValueBytes.length;
756 normalizedValue = Strings.utf8ToString( normalizedValueBytes );
757 }
758 }
759 else
760 {
761 if ( attributeType != null )
762 {
763 try
764 {
765 MatchingRule equality = attributeType.getEquality();
766
767 if ( equality == null )
768 {
769 normalizedValue = upValue;
770 }
771 else
772 {
773 Normalizer normalizer = equality.getNormalizer();
774
775 if ( normalizer != null )
776 {
777 normalizedValue = normalizer.normalize( upValue );
778 }
779 else
780 {
781 normalizedValue = upValue;
782 }
783 }
784 }
785 catch ( LdapException le )
786 {
787 normalizedValue = upValue;
788 }
789 }
790 else
791 {
792 normalizedValue = upValue;
793 }
794 }
795
796
797 h = Serialize.deserializeInt( buffer, pos );
798 pos += 4;
799
800 return pos;
801 }
802
803
804
805
806
807 @Override
808 public void writeExternal( ObjectOutput out ) throws IOException
809 {
810
811 out.writeBoolean( STRING );
812
813
814 if ( upValue != null )
815 {
816 out.writeBoolean( true );
817 out.writeUTF( upValue );
818 }
819 else
820 {
821 out.writeBoolean( false );
822 }
823
824
825 if ( attributeType != null )
826 {
827
828
829 out.writeBoolean( true );
830
831
832 if ( normalizedValue != null )
833 {
834 out.writeBoolean( true );
835 out.writeUTF( normalizedValue );
836 }
837 else
838 {
839 out.writeBoolean( false );
840 }
841 }
842 else
843 {
844
845 out.writeBoolean( false );
846 }
847
848
849 out.writeInt( h );
850
851
852 out.flush();
853 }
854
855
856
857
858
859 @Override
860 public String toString()
861 {
862 return upValue == null ? "null" : upValue;
863 }
864 }