1 17 package org.apache.ldap.server.interceptor; 18 19 20 import org.apache.ldap.server.authn.AuthenticationService; 21 import org.apache.ldap.server.invocation.Invocation; 22 import org.apache.ldap.server.authz.AuthorizationService; 23 import org.apache.ldap.server.schema.SchemaService; 24 import org.apache.ldap.server.operational.OperationalAttributeService; 25 import org.apache.ldap.server.exception.ExceptionService; 26 import org.apache.ldap.server.normalization.NormalizationService; 27 28 import javax.naming.NamingException ; 29 import java.util.*; 30 31 32 44 public class InterceptorChain implements Interceptor 45 { 46 50 public static final String NEXT_INTERCEPTOR = "nextInterceptor"; 51 52 53 56 public static InterceptorChain newDefaultChain() 57 { 58 InterceptorChain chain = new InterceptorChain(); 59 60 chain.addFirst( "normalizationService", new NormalizationService() ); 61 62 chain.addBefore( NEXT_INTERCEPTOR, "authenticationService", new AuthenticationService() ); 63 64 chain.addBefore( NEXT_INTERCEPTOR, "authorizationService", new AuthorizationService() ); 65 66 chain.addBefore( NEXT_INTERCEPTOR, "exceptionService", new ExceptionService() ); 67 68 chain.addBefore( NEXT_INTERCEPTOR, "schemaService", new SchemaService() ); 69 70 chain.addBefore( NEXT_INTERCEPTOR, "operationalAttributeService", new OperationalAttributeService() ); 71 72 return chain; 73 } 74 75 76 private final Interceptor NEXT_INTERCEPTOR0 = new Interceptor() 77 { 78 public void init( InterceptorContext context ) 79 { 80 } 81 82 83 public void destroy() 84 { 85 } 86 87 88 public void process( NextInterceptor nextInterceptor, Invocation invocation ) throws NamingException 89 { 90 if( parent != null ) 91 { 92 Entry e = ( Entry ) parent.interceptor2entry.get( InterceptorChain.this ); 93 94 e.nextInterceptor.process( invocation ); 95 } 96 97 nextInterceptor.process( invocation ); 98 } 99 }; 100 101 102 private final Interceptor FINAL_INTERCEPTOR = new Interceptor() 103 { 104 private InterceptorContext ctx; 105 106 107 public void init( InterceptorContext context ) 108 { 109 ctx = context; 110 } 111 112 113 public void destroy() 114 { 115 } 117 118 119 public void process( NextInterceptor nextInterceptor, Invocation call ) throws NamingException 120 { 121 if ( parent == null ) 122 { 123 125 call.execute( ctx.getRootNexus() ); 126 } 127 } 128 }; 129 130 private InterceptorChain parent; 131 132 private final Map name2entry = new HashMap(); 133 134 private final Map interceptor2entry = new IdentityHashMap(); 135 136 private Entry head = new Entry( null, null, NEXT_INTERCEPTOR, NEXT_INTERCEPTOR0 ); 137 138 private final Entry tail = new Entry( null, null, "end", FINAL_INTERCEPTOR ); 139 140 141 144 public InterceptorChain() 145 { 146 head.nextEntry = tail; 147 148 tail.prevEntry = head; 149 150 register( NEXT_INTERCEPTOR, head ); 151 } 152 153 154 157 public synchronized void init( InterceptorContext ctx ) throws NamingException 158 { 159 ListIterator it = getAll().listIterator(); 160 161 Interceptor interceptor = null; 162 163 try 164 { 165 while ( it.hasNext() ) 166 { 167 interceptor = ( Interceptor ) it.next(); 168 169 String name = getName( interceptor ); 170 171 Map config = InterceptorConfigBuilder.build( ctx.getConfig(), ( name == null ) ? "" : name ); 172 173 InterceptorContext newCtx = new InterceptorContext( ctx.getEnvironment(), 174 ctx.getSystemPartition(), ctx.getGlobalRegistries(), ctx.getRootNexus(), config ); 175 176 interceptor.init( newCtx ); 177 } 178 } 179 catch ( Throwable t ) 180 { 181 while ( it.hasPrevious() ) 182 { 183 Interceptor i = ( Interceptor ) it.previous(); 184 185 try 186 { 187 i.destroy(); 188 } 189 catch ( Throwable t2 ) 190 { 191 t2.printStackTrace(); 192 } 193 } 194 195 if ( t instanceof NamingException ) 196 { 197 throw ( NamingException ) t; 198 } 199 else 200 { 201 throw new InterceptorException( interceptor, null, "Failed to initialize interceptor chain.", t ); 202 } 203 } 204 } 205 206 207 210 public synchronized void destroy() 211 { 212 ListIterator it = getAllReversed().listIterator(); 213 214 while ( it.hasNext() ) 215 { 216 Interceptor interceptor = ( Interceptor ) it.next(); 217 218 try 219 { 220 interceptor.destroy(); 221 } 222 catch ( Throwable t ) 223 { 224 t.printStackTrace(); 225 } 226 } 227 } 228 229 230 235 public Interceptor get( String name ) 236 { 237 Entry e = ( Entry ) name2entry.get( name ); 238 239 if ( e == null ) 240 { 241 return null; 242 } 243 244 return e.interceptor; 245 } 246 247 248 private String getName( Interceptor interceptor ) 249 { 250 Entry e = ( Entry ) interceptor2entry.get( interceptor ); 251 252 if ( e == null ) 253 { 254 return null; 255 } 256 257 return e.name; 258 } 259 260 261 264 public synchronized void addFirst( String name, 265 Interceptor interceptor ) 266 { 267 checkAddable( name, interceptor ); 268 269 Entry newEntry = new Entry( null, head, name, interceptor ); 270 271 head.prevEntry = newEntry; 272 273 head = newEntry; 274 275 register( name, newEntry ); 276 } 277 278 279 282 public synchronized void addLast( String name, 283 Interceptor interceptor ) 284 { 285 checkAddable( name, interceptor ); 286 287 Entry newEntry = new Entry( tail.prevEntry, tail, name, interceptor ); 288 289 if ( tail.prevEntry != null ) 290 { 291 tail.prevEntry.nextEntry = newEntry; 292 } 293 else 294 { 295 head = newEntry; 296 } 297 298 tail.prevEntry = newEntry; 299 300 register( name, newEntry ); 301 } 302 303 304 308 public synchronized void addBefore( String baseName, String name, Interceptor interceptor ) 309 { 310 Entry baseEntry = checkOldName( baseName ); 311 312 checkAddable( name, interceptor ); 313 314 Entry prevEntry = baseEntry.prevEntry; 315 316 Entry newEntry = new Entry( prevEntry, baseEntry, name, interceptor ); 317 318 if ( prevEntry == null ) 319 { 320 baseEntry.prevEntry = newEntry; 321 322 head = newEntry; 323 324 } 325 else 326 { 327 baseEntry.prevEntry = newEntry; 328 329 prevEntry.nextEntry = newEntry; 330 } 331 332 register( name, newEntry ); 333 } 334 335 336 340 public synchronized void addAfter( String baseName, String name, Interceptor interceptor ) 341 { 342 Entry baseEntry = checkOldName( baseName ); 343 344 checkAddable( name, interceptor ); 345 346 Entry nextEntry = baseEntry.nextEntry; 347 348 Entry newEntry = new Entry( baseEntry, nextEntry, name, interceptor ); 349 350 if ( nextEntry == null ) 351 { 352 throw new IllegalStateException (); 353 } 354 355 nextEntry.prevEntry.nextEntry = newEntry; 356 357 nextEntry.prevEntry = newEntry; 358 359 register( name, newEntry ); 360 } 361 362 363 366 public synchronized void remove( String name ) 367 { 368 Entry entry = checkOldName( name ); 369 370 Entry prevEntry = entry.prevEntry; 371 372 Entry nextEntry = entry.nextEntry; 373 374 if ( prevEntry == null ) 375 { 376 nextEntry.prevEntry = null; 377 378 head = entry; 379 } 380 else 381 { 382 prevEntry.nextEntry = nextEntry; 383 384 nextEntry.prevEntry = prevEntry; 385 } 386 387 name2entry.remove( name ); 388 389 Interceptor interceptor = entry.interceptor; 390 391 interceptor2entry.remove( interceptor ); 392 393 if ( interceptor instanceof InterceptorChain ) 394 { 395 ( ( InterceptorChain ) interceptor ).parent = null; 396 } 397 } 398 399 400 403 public synchronized void clear() 404 { 405 Iterator it = new ArrayList( name2entry.keySet() ).iterator(); 406 407 while ( it.hasNext() ) 408 { 409 this.remove( ( String ) it.next() ); 410 } 411 } 412 413 414 private void register( String name, Entry newEntry ) 415 { 416 Interceptor interceptor = newEntry.interceptor; 417 418 name2entry.put( name, newEntry ); 419 420 interceptor2entry.put( newEntry.interceptor, newEntry ); 421 422 if ( interceptor instanceof InterceptorChain ) 423 { 424 ( ( InterceptorChain ) interceptor ).parent = this; 425 } 426 } 427 428 429 434 private Entry checkOldName( String baseName ) 435 { 436 Entry e = ( Entry ) name2entry.get( baseName ); 437 438 if ( e == null ) 439 { 440 throw new IllegalArgumentException ( "Unknown interceptor name:" + baseName ); 441 } 442 443 return e; 444 } 445 446 447 450 private void checkAddable( String name, Interceptor interceptor ) 451 { 452 if ( name2entry.containsKey( name ) ) 453 { 454 throw new IllegalArgumentException ( "Other interceptor is using name '" + name + "'" ); 455 } 456 457 if ( interceptor instanceof InterceptorChain ) 458 { 459 if ( ( ( InterceptorChain ) interceptor ).parent != null ) 460 { 461 throw new IllegalArgumentException ( "This interceptor chain has its parent already." ); 462 } 463 } 464 } 465 466 467 472 public void process( NextInterceptor nextInterceptor, Invocation invocation ) throws NamingException 473 { 474 Entry head = this.head; 475 476 try 477 { 478 head.interceptor.process( head.nextInterceptor, invocation ); 479 } 480 catch ( NamingException ne ) 481 { 482 throw ne; 483 } 484 catch ( Throwable e ) 485 { 486 throw new InterceptorException( head.interceptor, invocation, "Unexpected exception.", e ); 487 } 488 } 489 490 491 494 public List getAll() 495 { 496 List list = new ArrayList(); 497 498 Entry e = head; 499 500 do 501 { 502 list.add( e.interceptor ); 503 504 e = e.nextEntry; 505 } 506 while ( e != null ); 507 508 return list; 509 } 510 511 512 515 public List getAllReversed() 516 { 517 List list = new ArrayList(); 518 519 Entry e = tail; 520 521 do 522 { 523 list.add( e.interceptor ); 524 525 e = e.prevEntry; 526 } 527 528 while ( e != null ); 529 530 return list; 531 } 532 533 534 537 private class Entry 538 { 539 private Entry prevEntry; 540 541 private Entry nextEntry; 542 543 private final String name; 544 545 private final Interceptor interceptor; 546 547 private final NextInterceptor nextInterceptor; 548 549 550 private Entry( Entry prevEntry, Entry nextEntry, 551 String name, Interceptor interceptor ) 552 { 553 if ( interceptor == null ) 554 { 555 throw new NullPointerException ( "interceptor" ); 556 } 557 if ( name == null ) 558 { 559 throw new NullPointerException ( "name" ); 560 } 561 562 this.prevEntry = prevEntry; 563 564 this.nextEntry = nextEntry; 565 566 this.name = name; 567 568 this.interceptor = interceptor; 569 570 this.nextInterceptor = new NextInterceptor() 571 { 572 public void process( Invocation call ) throws NamingException 573 { 574 Interceptor interceptor = Entry.this.nextEntry.interceptor; 575 576 try 577 { 578 interceptor.process( Entry.this.nextEntry.nextInterceptor, call ); 579 } 580 catch ( NamingException ne ) 581 { 582 throw ne; 583 } 584 catch ( Throwable e ) 585 { 586 throw new InterceptorException( interceptor, call, "Unexpected exception.", e ); 587 } 588 } 589 }; 590 } 591 } 592 } 593 | Popular Tags |