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