1 17 18 package org.apache.avalon.fortress.util; 19 20 import org.apache.avalon.framework.context.Context; 21 import org.apache.avalon.framework.logger.AbstractLogEnabled; 22 import org.apache.avalon.lifecycle.Accessor; 23 import org.apache.avalon.lifecycle.Creator; 24 25 import java.util.ArrayList ; 26 import java.util.Collections ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 30 51 public final class LifecycleExtensionManager 52 extends AbstractLogEnabled 53 { 54 public static final String ROLE = LifecycleExtensionManager.class.getName(); 55 56 private final CachedArrayList m_accessorExtensions = new CachedArrayList(); 58 private final CachedArrayList m_creatorExtensions = new CachedArrayList(); 59 private boolean m_readOnly = false; 60 61 64 public void makeReadOnly() 65 { 66 m_readOnly = true; 67 } 68 69 72 public LifecycleExtensionManager writeableCopy() 73 { 74 final LifecycleExtensionManager copy = new LifecycleExtensionManager(); 75 copy.m_accessorExtensions.copyFrom( m_accessorExtensions ); 76 copy.m_creatorExtensions.copyFrom( m_creatorExtensions ); 77 78 return copy; 79 } 80 81 89 public void executeAccessExtensions( final Object component, final Context context ) 90 throws Exception 91 { 92 executeExtensions( m_accessorExtensions.toArray(), component, context, ACCESS ); 93 } 94 95 103 public void executeReleaseExtensions( final Object component, final Context context ) 104 throws Exception 105 { 106 executeExtensions( m_accessorExtensions.toArray(), component, context, RELEASE ); 107 } 108 109 117 public void executeCreationExtensions( final Object component, final Context context ) 118 throws Exception 119 { 120 executeExtensions( m_creatorExtensions.toArray(), component, context, CREATE ); 121 } 122 123 131 public void executeDestructionExtensions( final Object component, final Context context ) 132 throws Exception 133 { 134 executeExtensions( m_creatorExtensions.toArray(), component, context, DESTROY ); 135 } 136 137 153 158 public void addAccessorExtension( final Accessor extension ) 159 { 160 checkWriteable(); 161 m_accessorExtensions.add( extension ); 162 } 163 164 169 public void addCreatorExtension( final Creator extension ) 170 { 171 checkWriteable(); 172 m_creatorExtensions.add( extension ); 173 } 174 175 181 public void insertAccessorExtension( final int position, final Accessor extension ) 182 { 183 checkWriteable(); 184 m_accessorExtensions.insert( position, extension ); 185 } 186 187 193 public void insertCreatorExtension( final int position, final Creator extension ) 194 { 195 checkWriteable(); 196 m_creatorExtensions.insert( position, extension ); 197 } 198 199 205 public Accessor removeAccessorExtension( final int position ) 206 { 207 checkWriteable(); 208 return (Accessor) m_accessorExtensions.remove( position ); 209 } 210 211 217 public Creator removeCreatorExtension( final int position ) 218 { 219 checkWriteable(); 220 return (Creator) m_creatorExtensions.remove( position ); 221 } 222 223 228 public Iterator accessorExtensionsIterator() 229 { 230 return m_accessorExtensions.iterator(); 231 } 232 233 238 public Iterator creatorExtensionsIterator() 239 { 240 return m_creatorExtensions.iterator(); 241 } 242 243 248 public int accessorExtensionsCount() 249 { 250 return m_accessorExtensions.size(); 251 } 252 253 258 public int creatorExtensionsCount() 259 { 260 return m_creatorExtensions.size(); 261 } 262 263 269 public Accessor getAccessorExtension( final int index ) 270 { 271 return (Accessor) m_accessorExtensions.get( index ); 272 } 273 274 280 public Creator getCreatorExtension( final int index ) 281 { 282 return (Creator) m_creatorExtensions.get( index ); 283 } 284 285 288 public void clearAccessorExtensions() 289 { 290 checkWriteable(); 291 m_accessorExtensions.clear(); 292 } 293 294 297 public void clearCreatorExtensions() 298 { 299 checkWriteable(); 300 m_creatorExtensions.clear(); 301 } 302 303 protected static final int ACCESS = 0; 305 protected static final int RELEASE = 1; 306 protected static final int CREATE = 2; 307 protected static final int DESTROY = 3; 308 309 320 protected void executeExtensions( final Object [] extensions, 321 final Object component, 322 final Context context, 323 final int type ) 324 throws Exception 325 { 326 switch ( type ) 327 { 328 case ACCESS: 329 for ( int i = 0; i < extensions.length; ++i ) 330 { 331 ( (Accessor) extensions[i] ).access( component, context ); 332 } 333 break; 334 335 case RELEASE: 336 for ( int i = 0; i < extensions.length; ++i ) 337 { 338 ( (Accessor) extensions[i] ).release( component, context ); 339 } 340 break; 341 342 case CREATE: 343 for ( int i = 0; i < extensions.length; ++i ) 344 { 345 ( (Creator) extensions[i] ).create( component, context ); 346 } 347 break; 348 349 case DESTROY: 350 for ( int i = 0; i < extensions.length; ++i ) 351 { 352 ( (Creator) extensions[i] ).destroy( component, context ); 353 } 354 break; 355 356 default: 357 if ( getLogger().isErrorEnabled() ) 358 { 359 final String message = 360 "Incorrect extension phase specified: " + type; 361 getLogger().error( message ); 362 } 363 } 364 } 365 366 372 protected final void checkWriteable() 373 throws IllegalStateException 374 { 375 if ( m_readOnly ) 376 { 377 final String message = 378 "LifecycleExtensionsManager is read only and can not be modified"; 379 throw new IllegalStateException ( message ); 380 } 381 } 382 383 409 private final class CachedArrayList 410 { 411 private final Object [] EMPTY_ARRAY = new Object [0]; 413 414 private final List m_proxy = Collections.synchronizedList( new ArrayList () ); 416 417 private Object [] m_cache = EMPTY_ARRAY; 419 420 423 public void copyFrom( final CachedArrayList original ) 424 { 425 m_proxy.clear(); 426 m_proxy.addAll( original.m_proxy ); 427 m_cache = original.m_cache; } 429 430 435 public void add( final Object object ) 436 { 437 m_proxy.add( object ); 438 m_cache = m_proxy.toArray(); 439 } 440 441 447 public void insert( final int position, final Object object ) 448 { 449 m_proxy.add( position, object ); 450 m_cache = m_proxy.toArray(); 451 } 452 453 459 public Object remove( final int position ) 460 { 461 final Object object = m_proxy.remove( position ); 462 m_cache = m_proxy.toArray(); 463 return object; 464 } 465 466 471 public Iterator iterator() 472 { 473 final Iterator base = m_proxy.iterator(); 474 return new UnmodifiableIterator( base ); 475 } 476 477 482 public int size() 483 { 484 return m_proxy.size(); 485 } 486 487 493 public Object get( final int index ) 494 { 495 return m_proxy.get( index ); 496 } 497 498 504 public int indexOf( final Object object ) 505 { 506 return m_proxy.indexOf( object ); 507 } 508 509 512 public void clear() 513 { 514 m_proxy.clear(); 515 m_cache = EMPTY_ARRAY; 516 } 517 518 525 public Object [] toArray() 526 { 527 return m_cache; 528 } 529 } 530 531 534 private static class UnmodifiableIterator implements Iterator 535 { 536 private final Iterator m_base; 537 538 UnmodifiableIterator( final Iterator base ) 539 { 540 if ( base == null ) throw new NullPointerException ( "base can not be null" ); 541 m_base = base; 542 } 543 544 public boolean hasNext() 545 { 546 return m_base.hasNext(); 547 } 548 549 public Object next() 550 { 551 return m_base.next(); 552 } 553 554 public void remove() 555 { 556 throw new UnsupportedOperationException ( "Unmodifiable iterator" ); 557 } 558 } 559 } 560 | Popular Tags |