1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.partition;
21
22
23 import java.util.Collection;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Set;
27
28 import javax.naming.Context;
29 import javax.naming.ServiceUnavailableException;
30 import javax.naming.directory.SearchControls;
31 import javax.naming.ldap.LdapContext;
32
33 import org.apache.directory.server.core.DirectoryService;
34 import org.apache.directory.server.core.entry.ClonedServerEntry;
35 import org.apache.directory.server.core.entry.ServerEntry;
36 import org.apache.directory.server.core.filtering.EntryFilter;
37 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
38 import org.apache.directory.server.core.interceptor.InterceptorChain;
39 import org.apache.directory.server.core.interceptor.context.AddContextPartitionOperationContext;
40 import org.apache.directory.server.core.interceptor.context.AddOperationContext;
41 import org.apache.directory.server.core.interceptor.context.BindOperationContext;
42 import org.apache.directory.server.core.interceptor.context.CompareOperationContext;
43 import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
44 import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
45 import org.apache.directory.server.core.interceptor.context.GetMatchedNameOperationContext;
46 import org.apache.directory.server.core.interceptor.context.GetRootDSEOperationContext;
47 import org.apache.directory.server.core.interceptor.context.GetSuffixOperationContext;
48 import org.apache.directory.server.core.interceptor.context.ListOperationContext;
49 import org.apache.directory.server.core.interceptor.context.ListSuffixOperationContext;
50 import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
51 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
52 import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
53 import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
54 import org.apache.directory.server.core.interceptor.context.OperationContext;
55 import org.apache.directory.server.core.interceptor.context.RemoveContextPartitionOperationContext;
56 import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
57 import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
58 import org.apache.directory.server.core.interceptor.context.SearchingOperationContext;
59 import org.apache.directory.server.core.interceptor.context.UnbindOperationContext;
60 import org.apache.directory.server.core.invocation.InvocationStack;
61 import org.apache.directory.shared.ldap.NotImplementedException;
62 import org.apache.directory.shared.ldap.constants.SchemaConstants;
63 import org.apache.directory.shared.ldap.exception.LdapSizeLimitExceededException;
64 import org.apache.directory.shared.ldap.exception.LdapTimeLimitExceededException;
65 import org.apache.directory.shared.ldap.name.LdapDN;
66
67
68
69
70
71
72
73
74
75
76
77
78 public class PartitionNexusProxy extends PartitionNexus
79 {
80
81
82
83
84 private static ServerEntry ROOT_DSE_ALL;
85
86
87
88
89 private static ServerEntry ROOT_DSE_NO_OPERATIONNAL;
90
91
92
93
94 private static final Object ROOT_DSE_ALL_MUTEX = new Object();
95
96
97
98
99 private static final Object ROOT_DSE_NOOP_MUTEX = new Object();
100
101 private final DirectoryService service;
102
103
104
105
106
107
108
109
110 public PartitionNexusProxy( DirectoryService service ) throws Exception
111 {
112 this.service = service;
113 }
114
115
116 public LdapContext getLdapContext()
117 {
118 return service.getPartitionNexus().getLdapContext();
119 }
120
121
122 public String getId()
123 {
124 throw new UnsupportedOperationException( "Nexus partition proxy objects do not have an Id." );
125 }
126
127
128 public void setId( String id )
129 {
130 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
131 }
132
133
134 public ClonedServerEntry getContextEntry()
135 {
136 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
137 }
138
139
140 public void setContextEntry( ServerEntry contextEntry )
141 {
142 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
143 }
144
145
146 public String getSuffix()
147 {
148 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
149 }
150
151
152 public void setSuffix( String suffix )
153 {
154 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
155 }
156
157
158 public void setCacheSize( int cacheSize )
159 {
160 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
161 }
162
163
164 public int getCacheSize()
165 {
166 throw new UnsupportedOperationException( "Not supported by PartitionNexusProxy" );
167 }
168
169
170 public void init( DirectoryService core ) throws Exception
171 {
172 }
173
174
175 public void destroy()
176 {
177 }
178
179
180 public Partition getSystemPartition()
181 {
182 return service.getPartitionNexus().getSystemPartition();
183 }
184
185
186 public Partition getPartition( LdapDN dn ) throws Exception
187 {
188 return service.getPartitionNexus().getPartition( dn );
189 }
190
191
192 public LdapDN getSuffixDn() throws Exception
193 {
194 return service.getPartitionNexus().getSuffixDn();
195 }
196
197 public LdapDN getUpSuffixDn() throws Exception
198 {
199 return service.getPartitionNexus().getUpSuffixDn();
200 }
201
202
203 public void sync() throws Exception
204 {
205 this.service.sync();
206 }
207
208
209 public void close() throws Exception
210 {
211 this.service.shutdown();
212 }
213
214
215 public boolean isInitialized()
216 {
217 return this.service.isStarted();
218 }
219
220
221 public LdapDN getMatchedName( GetMatchedNameOperationContext opContext ) throws Exception
222 {
223 return getMatchedName( opContext, null );
224 }
225
226
227 private void push( OperationContext opContext )
228 {
229 InvocationStack.getInstance().push( opContext );
230 }
231
232
233 private OperationContext pop()
234 {
235 return InvocationStack.getInstance().pop();
236 }
237
238
239 public LdapDN getMatchedName( GetMatchedNameOperationContext opContext, Collection<String> byPassed ) throws Exception
240 {
241 ensureStarted();
242 opContext.setByPassed( byPassed );
243 push( opContext );
244
245 try
246 {
247 return service.getInterceptorChain().getMatchedName( opContext );
248 }
249 finally
250 {
251 pop();
252 }
253 }
254
255
256 public LdapDN getSuffix( GetSuffixOperationContext opContext ) throws Exception
257 {
258 return getSuffix( opContext, null );
259 }
260
261
262 public LdapDN getSuffix( GetSuffixOperationContext opContext, Collection<String> byPassed ) throws Exception
263 {
264 ensureStarted();
265 opContext.setByPassed( byPassed );
266 push( opContext );
267
268 try
269 {
270 return service.getInterceptorChain().getSuffix( opContext );
271 }
272 finally
273 {
274 pop();
275 }
276 }
277
278
279 public Iterator<String> listSuffixes( ListSuffixOperationContext opContext ) throws Exception
280 {
281 return listSuffixes( opContext, null );
282 }
283
284
285 public Iterator<String> listSuffixes( ListSuffixOperationContext opContext, Collection<String> byPassed ) throws Exception
286 {
287 ensureStarted();
288 opContext.setByPassed( byPassed );
289 push( opContext );
290
291 try
292 {
293 return service.getInterceptorChain().listSuffixes( opContext );
294 }
295 finally
296 {
297 pop();
298 }
299 }
300
301
302 public boolean compare( CompareOperationContext opContext ) throws Exception
303 {
304 return compare( opContext, null );
305 }
306
307
308 public boolean compare( CompareOperationContext opContext, Collection<String> byPassed ) throws Exception
309 {
310 ensureStarted();
311 opContext.setByPassed( byPassed );
312 push( opContext );
313
314 try
315 {
316 return service.getInterceptorChain().compare( opContext );
317 }
318 finally
319 {
320 pop();
321 }
322 }
323
324
325 public void delete( DeleteOperationContext opContext ) throws Exception
326 {
327 delete( opContext, null );
328 }
329
330
331 public void delete( DeleteOperationContext opContext, Collection<String> byPassed ) throws Exception
332 {
333 ensureStarted();
334 opContext.setByPassed( byPassed );
335 push( opContext );
336
337 try
338 {
339 service.getInterceptorChain().delete( opContext );
340 }
341 finally
342 {
343 pop();
344 }
345 }
346
347
348 public void add( AddOperationContext opContext ) throws Exception
349 {
350 add( opContext, null );
351 }
352
353
354 public void add( AddOperationContext opContext, Collection<String> byPassed ) throws Exception
355 {
356 ensureStarted();
357 opContext.setByPassed( byPassed );
358 push( opContext );
359
360 try
361 {
362 service.getInterceptorChain().add( opContext );
363 }
364 finally
365 {
366 pop();
367 }
368 }
369
370
371 public void modify( ModifyOperationContext opContext ) throws Exception
372 {
373 modify( opContext, null );
374 }
375
376
377 public void modify( ModifyOperationContext opContext, Collection<String> byPassed ) throws Exception
378 {
379 ensureStarted();
380 opContext.setByPassed( byPassed );
381 push( opContext );
382
383 try
384 {
385 service.getInterceptorChain().modify( opContext );
386 }
387 finally
388 {
389 pop();
390 }
391 }
392
393
394 public EntryFilteringCursor list( ListOperationContext opContext ) throws Exception
395 {
396 return list( opContext, null );
397 }
398
399
400 public EntryFilteringCursor list( ListOperationContext opContext, Collection<String> byPassed ) throws Exception
401 {
402 ensureStarted();
403 opContext.setByPassed( byPassed );
404 push( opContext );
405
406 try
407 {
408 return service.getInterceptorChain().list( opContext );
409 }
410 finally
411 {
412 pop();
413 }
414 }
415
416
417 public EntryFilteringCursor search( SearchOperationContext opContext ) throws Exception
418 {
419 EntryFilteringCursor cursor = search( opContext, null );
420 final SearchControls searchCtls = opContext.getSearchControls();
421
422 if ( searchCtls.getTimeLimit() + searchCtls.getCountLimit() > 0 )
423 {
424
425
426
427 cursor.addEntryFilter( new EntryFilter()
428 {
429 final long startTime = System.currentTimeMillis();
430 int count = 0;
431
432 public boolean accept( SearchingOperationContext operation, ClonedServerEntry entry )
433 throws Exception
434 {
435 if ( searchCtls.getTimeLimit() > 0 )
436 {
437 long runtime = System.currentTimeMillis() - startTime;
438 if ( runtime > searchCtls.getTimeLimit() )
439 {
440 throw new LdapTimeLimitExceededException();
441 }
442 }
443
444 if ( searchCtls.getCountLimit() > 0 )
445 {
446 if ( count > searchCtls.getCountLimit() )
447 {
448 throw new LdapSizeLimitExceededException();
449 }
450 }
451
452 count++;
453 return true;
454 }
455 } );
456 }
457
458 return cursor;
459 }
460
461
462 public EntryFilteringCursor search( SearchOperationContext opContext, Collection<String> byPassed )
463 throws Exception
464 {
465 ensureStarted();
466 opContext.setByPassed( byPassed );
467 push( opContext );
468
469 try
470 {
471 return service.getInterceptorChain().search( opContext );
472 }
473 finally
474 {
475 pop();
476 }
477 }
478
479
480 public ClonedServerEntry lookup( LookupOperationContext opContext ) throws Exception
481 {
482 if ( opContext.getDn().size() == 0 )
483 {
484 List<String> attrs = opContext.getAttrsId();
485
486 if ( ( attrs == null ) || ( attrs.size() == 0 ) )
487 {
488 synchronized ( ROOT_DSE_NOOP_MUTEX )
489 {
490 if ( ROOT_DSE_NO_OPERATIONNAL == null )
491 {
492 ROOT_DSE_NO_OPERATIONNAL = lookup( opContext, null );
493 }
494 }
495
496 return new ClonedServerEntry( ROOT_DSE_NO_OPERATIONNAL );
497 }
498 else if ( ( attrs.size() == 1 ) && ( attrs.contains( SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES ) ) )
499 {
500 synchronized ( ROOT_DSE_ALL_MUTEX )
501 {
502 if ( ROOT_DSE_ALL == null )
503 {
504 ROOT_DSE_ALL = lookup( opContext, null );
505 }
506 }
507
508 return new ClonedServerEntry( ROOT_DSE_ALL );
509 }
510
511 }
512
513 return lookup( opContext, null );
514 }
515
516
517 public ClonedServerEntry lookup( LookupOperationContext opContext, Collection<String> byPassed ) throws Exception
518 {
519 ensureStarted();
520 opContext.setByPassed( byPassed );
521 push( opContext );
522
523 try
524 {
525 return service.getInterceptorChain().lookup( opContext );
526 }
527 finally
528 {
529 pop();
530 }
531 }
532
533 public boolean hasEntry( EntryOperationContext opContext ) throws Exception
534 {
535 return hasEntry( opContext, null );
536 }
537
538
539 public boolean hasEntry( EntryOperationContext opContext, Collection<String> byPassed ) throws Exception
540 {
541 ensureStarted();
542 opContext.setByPassed( byPassed );
543 push( opContext );
544
545 try
546 {
547 return service.getInterceptorChain().hasEntry( opContext );
548 }
549 finally
550 {
551 pop();
552 }
553 }
554
555
556 public void rename( RenameOperationContext opContext ) throws Exception
557 {
558 rename( opContext, null );
559 }
560
561
562 public void rename( RenameOperationContext opContext, Collection<String> byPassed ) throws Exception
563 {
564 ensureStarted();
565 opContext.setByPassed( byPassed );
566 push( opContext );
567
568 try
569 {
570 service.getInterceptorChain().rename( opContext );
571 }
572 finally
573 {
574 pop();
575 }
576 }
577
578
579 public void move( MoveOperationContext opContext ) throws Exception
580 {
581 move( opContext, null );
582 }
583
584
585 public void move( MoveOperationContext opContext, Collection<String> byPassed ) throws Exception
586 {
587 ensureStarted();
588 opContext.setByPassed( byPassed );
589 push( opContext );
590
591 try
592 {
593 service.getInterceptorChain().move( opContext );
594 }
595 finally
596 {
597 pop();
598 }
599 }
600
601
602 public void moveAndRename( MoveAndRenameOperationContext opContext ) throws Exception
603 {
604 moveAndRename( opContext, null );
605 }
606
607
608 public void moveAndRename( MoveAndRenameOperationContext opContext, Collection<String> byPassed )
609 throws Exception
610 {
611 ensureStarted();
612 opContext.setByPassed( byPassed );
613 push( opContext );
614
615 try
616 {
617 service.getInterceptorChain().moveAndRename( opContext );
618 }
619 finally
620 {
621 pop();
622 }
623 }
624
625
626
627
628
629
630
631
632 public void bind( BindOperationContext opContext, Collection<String> byPassed )
633 throws Exception
634 {
635 ensureStarted();
636 opContext.setByPassed( byPassed );
637 push( opContext );
638
639 try
640 {
641 service.getInterceptorChain().bind( opContext );
642 }
643 finally
644 {
645 pop();
646 }
647 }
648
649
650 public void unbind( UnbindOperationContext opContext, Collection<String> byPassed ) throws Exception
651 {
652 ensureStarted();
653 opContext.setByPassed( byPassed );
654 push( opContext );
655
656 try
657 {
658 service.getInterceptorChain().unbind( opContext );
659 }
660 finally
661 {
662 pop();
663 }
664 }
665
666
667 public void bind( BindOperationContext opContext ) throws Exception
668 {
669 bind( opContext, null );
670 }
671
672
673 public void unbind( UnbindOperationContext opContext ) throws Exception
674 {
675 unbind( opContext, null );
676 }
677
678
679 public ClonedServerEntry getRootDSE( GetRootDSEOperationContext opContext ) throws Exception
680 {
681 if ( opContext.getDn().size() == 0 )
682 {
683 synchronized ( ROOT_DSE_ALL_MUTEX )
684 {
685 if ( ROOT_DSE_ALL == null )
686 {
687 ROOT_DSE_ALL = getRootDSE( opContext, null );
688 }
689 }
690
691 return new ClonedServerEntry( ROOT_DSE_ALL );
692 }
693
694 return getRootDSE( opContext, null );
695 }
696
697
698 public ClonedServerEntry getRootDSE( GetRootDSEOperationContext opContext, Collection<String> byPassed )
699 throws Exception
700 {
701 ensureStarted();
702 opContext.setByPassed( byPassed );
703 push( opContext );
704
705 try
706 {
707 return service.getInterceptorChain().getRootDSE( opContext );
708 }
709 finally
710 {
711 pop();
712 }
713 }
714
715
716 public void addContextPartition( AddContextPartitionOperationContext opContext ) throws Exception
717 {
718 addContextPartition( opContext, null );
719 }
720
721
722 public void addContextPartition( AddContextPartitionOperationContext opContext, Collection<String> byPassed )
723 throws Exception
724 {
725 ensureStarted();
726 opContext.setByPassed( byPassed );
727 push( opContext );
728
729 try
730 {
731 service.getInterceptorChain().addContextPartition( opContext );
732 }
733 finally
734 {
735 pop();
736 }
737 }
738
739
740 public void removeContextPartition( RemoveContextPartitionOperationContext opContext ) throws Exception
741 {
742 removeContextPartition( opContext, null );
743 }
744
745
746 public void removeContextPartition( RemoveContextPartitionOperationContext opContext, Collection<String> byPassed )
747 throws Exception
748 {
749 ensureStarted();
750 opContext.setByPassed( byPassed );
751 push( opContext );
752
753 try
754 {
755 service.getInterceptorChain().removeContextPartition( opContext );
756 }
757 finally
758 {
759 pop();
760 }
761 }
762
763
764 private void ensureStarted() throws ServiceUnavailableException
765 {
766 if ( !service.isStarted() )
767 {
768 throw new ServiceUnavailableException( "Directory service is not started." );
769 }
770 }
771
772
773 public void registerSupportedExtensions( Set<String> extensionOids ) throws Exception
774 {
775 service.getPartitionNexus().registerSupportedExtensions( extensionOids );
776 }
777
778
779 public void registerSupportedSaslMechanisms( Set<String> supportedSaslMechanisms ) throws Exception
780 {
781 service.getPartitionNexus().registerSupportedSaslMechanisms( supportedSaslMechanisms );
782 }
783
784
785 public ClonedServerEntry lookup( Long id ) throws Exception
786 {
787
788
789 throw new NotImplementedException();
790 }
791 }