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 import java.util.ArrayList;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.NoSuchElementException;
25 import java.util.Set;
26
27 import javax.naming.NamingEnumeration;
28 import javax.naming.NamingException;
29 import javax.naming.directory.Attribute;
30 import javax.naming.directory.Attributes;
31 import javax.naming.directory.BasicAttribute;
32 import javax.naming.directory.BasicAttributes;
33 import javax.naming.directory.DirContext;
34 import javax.naming.directory.InvalidAttributeIdentifierException;
35 import javax.naming.directory.ModificationItem;
36 import javax.naming.directory.SearchResult;
37
38 import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
39 import org.apache.directory.server.schema.registries.Registries;
40 import org.apache.directory.shared.ldap.constants.SchemaConstants;
41 import org.apache.directory.shared.ldap.entry.EntryAttribute;
42 import org.apache.directory.shared.ldap.entry.Modification;
43 import org.apache.directory.shared.ldap.entry.ModificationOperation;
44 import org.apache.directory.shared.ldap.entry.Value;
45 import org.apache.directory.shared.ldap.name.LdapDN;
46 import org.apache.directory.shared.ldap.schema.AttributeType;
47 import org.apache.directory.shared.ldap.schema.SchemaUtils;
48 import org.apache.directory.shared.ldap.util.EmptyEnumeration;
49 import org.apache.directory.shared.ldap.util.StringTools;
50
51
52
53
54
55
56
57 public class ServerEntryUtils
58 {
59
60
61
62
63
64
65
66 public static Attribute toBasicAttribute( ServerAttribute entryAttribute )
67 {
68 AttributeType attributeType = entryAttribute.getAttributeType();
69
70 Attribute attribute = new BasicAttribute( attributeType.getName() );
71
72 for ( Value<?> value: entryAttribute )
73 {
74 attribute.add( value.get() );
75 }
76
77 return attribute;
78 }
79
80
81
82
83
84
85
86
87
88 public static Attributes toBasicAttributes( ServerEntry entry )
89 {
90 if ( entry == null )
91 {
92 return null;
93 }
94
95 Attributes attributes = new BasicAttributes( true );
96
97 for ( AttributeType attributeType:entry.getAttributeTypes() )
98 {
99 EntryAttribute attr = entry.get( attributeType );
100
101
102 if ( attributeType.getOid().equals( SchemaConstants.OBJECT_CLASS_AT_OID ) )
103 {
104 if ( attr.size() == 0 )
105 {
106
107 continue;
108 }
109 }
110
111 attributes.put( toBasicAttribute( (ServerAttribute)attr ) );
112 }
113
114 return attributes;
115 }
116
117
118
119
120
121
122
123
124
125
126
127 public static ServerAttribute toServerAttribute( Attribute attribute, AttributeType attributeType )
128 {
129 if ( attribute == null )
130 {
131 return null;
132 }
133
134 try
135 {
136 ServerAttribute serverAttribute = new DefaultServerAttribute( attributeType );
137
138 for ( NamingEnumeration<?> values = attribute.getAll(); values.hasMoreElements(); )
139 {
140 Object value = values.nextElement();
141
142 if ( serverAttribute.isHR() )
143 {
144 if ( value instanceof String )
145 {
146 serverAttribute.add( (String)value );
147 }
148 else if ( value instanceof byte[] )
149 {
150 serverAttribute.add( StringTools.utf8ToString( (byte[])value ) );
151 }
152 else
153 {
154 return null;
155 }
156 }
157 else
158 {
159 if ( value instanceof String )
160 {
161 serverAttribute.add( StringTools.getBytesUtf8( (String)value ) );
162 }
163 else if ( value instanceof byte[] )
164 {
165 serverAttribute.add( (byte[])value );
166 }
167 else
168 {
169 return null;
170 }
171 }
172 }
173
174 return serverAttribute;
175 }
176 catch ( NamingException ne )
177 {
178 return null;
179 }
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193 public static ServerEntry toServerEntry( Attributes attributes, LdapDN dn, Registries registries )
194 throws InvalidAttributeIdentifierException
195 {
196 if ( attributes instanceof BasicAttributes )
197 {
198 try
199 {
200 ServerEntry entry = new DefaultServerEntry( registries, dn );
201
202 for ( NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMoreElements(); )
203 {
204 Attribute attr = attrs.nextElement();
205
206 String attributeId = attr.getID();
207 String id = SchemaUtils.stripOptions( attributeId );
208 Set<String> options = SchemaUtils.getOptions( attributeId );
209
210 AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( id );
211 ServerAttribute serverAttribute = ServerEntryUtils.toServerAttribute( attr, attributeType );
212
213 if ( serverAttribute != null )
214 {
215 entry.put( serverAttribute );
216 }
217 }
218
219 return entry;
220 }
221 catch ( NamingException ne )
222 {
223 throw new InvalidAttributeIdentifierException( ne.getMessage() );
224 }
225 }
226 else
227 {
228 return null;
229 }
230 }
231
232
233
234
235
236
237
238
239
240
241
242 public static ServerEntry getTargetEntry( Modification mod, ServerEntry entry, Registries registries ) throws NamingException
243 {
244 ServerEntry targetEntry = ( ServerEntry ) entry.clone();
245 ModificationOperation modOp = mod.getOperation();
246 String id = mod.getAttribute().getId();
247 AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( id );
248
249 switch ( modOp )
250 {
251 case REPLACE_ATTRIBUTE :
252 targetEntry.put( (ServerAttribute)mod.getAttribute() );
253 break;
254
255 case REMOVE_ATTRIBUTE :
256 ServerAttribute toBeRemoved = (ServerAttribute)mod.getAttribute();
257
258 if ( toBeRemoved.size() == 0 )
259 {
260 targetEntry.removeAttributes( id );
261 }
262 else
263 {
264 EntryAttribute existing = targetEntry.get( id );
265
266 if ( existing != null )
267 {
268 for ( Value<?> value:toBeRemoved )
269 {
270 existing.remove( value );
271 }
272 }
273 }
274 break;
275
276 case ADD_ATTRIBUTE :
277 ServerAttribute combined = new DefaultServerAttribute( id, attributeType );
278 ServerAttribute toBeAdded = (ServerAttribute)mod.getAttribute();
279 EntryAttribute existing = entry.get( id );
280
281 if ( existing != null )
282 {
283 for ( Value<?> value:existing )
284 {
285 combined.add( value );
286 }
287 }
288
289 for ( Value<?> value:toBeAdded )
290 {
291 combined.add( value );
292 }
293
294 targetEntry.put( combined );
295 break;
296
297 default:
298 throw new IllegalStateException( "undefined modification type: " + modOp );
299 }
300
301 return targetEntry;
302 }
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 public static ServerAttribute getUnion( ServerAttribute attr0, ServerAttribute attr1 )
319 {
320 if ( attr0 == null && attr1 == null )
321 {
322 throw new IllegalArgumentException( "Cannot figure out attribute ID if both args are null" );
323 }
324 else if ( attr0 == null )
325 {
326 return (ServerAttribute)attr1.clone();
327 }
328 else if ( attr1 == null )
329 {
330 return (ServerAttribute)attr0.clone();
331 }
332 else if ( !attr0.getAttributeType().equals( attr1.getAttributeType() ) )
333 {
334 throw new IllegalArgumentException( "Cannot take union of attributes with different IDs!" );
335 }
336
337 ServerAttribute attr = (ServerAttribute)attr0.clone();
338
339 for ( Value<?> value:attr1 )
340 {
341 attr.add( value );
342 }
343
344 return attr;
345 }
346
347
348
349
350
351
352
353
354
355 private static Modification toServerModification( ModificationItem modificationImpl, AttributeType attributeType )
356 {
357 ModificationOperation operation;
358
359 switch ( modificationImpl.getModificationOp() )
360 {
361 case DirContext.REMOVE_ATTRIBUTE :
362 operation = ModificationOperation.REMOVE_ATTRIBUTE;
363 break;
364
365 case DirContext.REPLACE_ATTRIBUTE :
366 operation = ModificationOperation.REPLACE_ATTRIBUTE;
367 break;
368
369 case DirContext.ADD_ATTRIBUTE :
370 default :
371 operation = ModificationOperation.ADD_ATTRIBUTE;
372 break;
373
374 }
375
376 Modification modification = new ServerModification(
377 operation,
378 ServerEntryUtils.toServerAttribute( modificationImpl.getAttribute(), attributeType ) );
379
380 return modification;
381
382 }
383
384
385
386
387
388
389
390
391
392
393
394 public static List<Modification> convertToServerModification( List<ModificationItem> modificationItems,
395 AttributeTypeRegistry atRegistry ) throws NamingException
396 {
397 if ( modificationItems != null )
398 {
399 List<Modification> modifications = new ArrayList<Modification>( modificationItems.size() );
400
401 for ( ModificationItem modificationItem: modificationItems )
402 {
403 AttributeType attributeType = atRegistry.lookup( modificationItem.getAttribute().getID() );
404 modifications.add( toServerModification( modificationItem, attributeType ) );
405 }
406
407 return modifications;
408 }
409 else
410 {
411 return null;
412 }
413 }
414
415
416
417
418
419
420
421
422
423 private static Modification toServerModification( Modification modification, AttributeType attributeType )
424 {
425 if ( modification instanceof ServerModification )
426 {
427 return modification;
428 }
429
430 Modification serverModification = new ServerModification(
431 modification.getOperation(),
432 new DefaultServerAttribute( attributeType, modification.getAttribute() ) );
433
434 return serverModification;
435
436 }
437
438
439 public static List<Modification> toServerModification( Modification[] modifications,
440 AttributeTypeRegistry atRegistry ) throws NamingException
441 {
442 if ( modifications != null )
443 {
444 List<Modification> modificationsList = new ArrayList<Modification>();
445
446 for ( Modification modification: modifications )
447 {
448 String attributeId = modification.getAttribute().getId();
449 String id = stripOptions( attributeId );
450 modification.getAttribute().setId( id );
451 Set<String> options = getOptions( attributeId );
452
453
454
455
456
457
458
459
460
461 if ( ! atRegistry.hasAttributeType( id )
462 && modification.getAttribute().size() == 0
463 && modification.getOperation() == ModificationOperation.REPLACE_ATTRIBUTE )
464 {
465 continue;
466 }
467
468
469
470
471
472
473
474 AttributeType attributeType = atRegistry.lookup( id );
475 modificationsList.add( toServerModification( modification, attributeType ) );
476 }
477
478 return modificationsList;
479 }
480 else
481 {
482 return null;
483 }
484 }
485
486
487 public static List<Modification> toServerModification( ModificationItem[] modifications,
488 AttributeTypeRegistry atRegistry ) throws NamingException
489 {
490 if ( modifications != null )
491 {
492 List<Modification> modificationsList = new ArrayList<Modification>();
493
494 for ( ModificationItem modification: modifications )
495 {
496 String attributeId = modification.getAttribute().getID();
497 String id = stripOptions( attributeId );
498 Set<String> options = getOptions( attributeId );
499
500
501
502
503
504
505
506
507
508 if ( ! atRegistry.hasAttributeType( id )
509 && modification.getAttribute().size() == 0
510 && modification.getModificationOp() == DirContext.REPLACE_ATTRIBUTE )
511 {
512 continue;
513 }
514
515
516
517
518
519
520
521 AttributeType attributeType = atRegistry.lookup( id );
522 modificationsList.add( toServerModification( (ModificationItem)modification, attributeType ) );
523 }
524
525 return modificationsList;
526 }
527 else
528 {
529 return null;
530 }
531 }
532
533
534
535
536
537
538
539
540
541 public static final Modification getModificationItem( List<Modification> mods, AttributeType type )
542 {
543 for ( Modification modification:mods )
544 {
545 ServerAttribute attribute = (ServerAttribute)modification.getAttribute();
546
547 if ( attribute.getAttributeType() == type )
548 {
549 return modification;
550 }
551 }
552
553 return null;
554 }
555
556
557
558
559
560
561
562
563
564 public static ServerAttribute getAttribute( List<Modification> mods, AttributeType type )
565 {
566 Modification mod = getModificationItem( mods, type );
567
568 if ( mod != null )
569 {
570 return (ServerAttribute)mod.getAttribute();
571 }
572
573 return null;
574 }
575
576
577
578
579
580
581
582 public static NamingEnumeration<SearchResult> toSearchResultEnum( final NamingEnumeration<ServerSearchResult> result )
583 {
584 if ( result instanceof EmptyEnumeration<?> )
585 {
586 return new EmptyEnumeration<SearchResult>();
587 }
588
589 return new NamingEnumeration<SearchResult> ()
590 {
591 public void close() throws NamingException
592 {
593 result.close();
594 }
595
596
597
598
599
600 public boolean hasMore() throws NamingException
601 {
602 return result.hasMore();
603 }
604
605
606
607
608
609 public SearchResult next() throws NamingException
610 {
611 ServerSearchResult rec = result.next();
612
613 SearchResult searchResult = new SearchResult(
614 rec.getDn().getUpName(),
615 rec.getObject(),
616 toBasicAttributes( rec.getServerEntry() ),
617 rec.isRelative() );
618
619 return searchResult;
620 }
621
622
623
624
625
626 public boolean hasMoreElements()
627 {
628 return result.hasMoreElements();
629 }
630
631
632
633
634
635 public SearchResult nextElement()
636 {
637 try
638 {
639 ServerSearchResult rec = result.next();
640
641 SearchResult searchResult = new SearchResult(
642 rec.getDn().getUpName(),
643 rec.getObject(),
644 toBasicAttributes( rec.getServerEntry() ),
645 rec.isRelative() );
646
647 return searchResult;
648 }
649 catch ( NamingException ne )
650 {
651 NoSuchElementException nsee =
652 new NoSuchElementException( "Encountered NamingException on underlying enumeration." );
653 nsee.initCause( ne );
654 throw nsee;
655 }
656 }
657 };
658 }
659
660
661
662
663
664
665
666
667
668
669
670 private static String stripOptions( String attributeId )
671 {
672 int optionsPos = attributeId.indexOf( ";" );
673
674 if ( optionsPos != -1 )
675 {
676 return attributeId.substring( 0, optionsPos );
677 }
678 else
679 {
680 return attributeId;
681 }
682 }
683
684
685
686
687
688
689
690
691
692
693 private static Set<String> getOptions( String attributeId )
694 {
695 int optionsPos = attributeId.indexOf( ";" );
696
697 if ( optionsPos != -1 )
698 {
699 Set<String> options = new HashSet<String>();
700
701 String[] res = attributeId.substring( optionsPos + 1 ).split( ";" );
702
703 for ( String option:res )
704 {
705 if ( !StringTools.isEmpty( option ) )
706 {
707 options.add( option );
708 }
709 }
710
711 return options;
712 }
713 else
714 {
715 return null;
716 }
717 }
718 }