1 8 package org.apache.avalon.excalibur.system; 9 10 import org.apache.avalon.framework.activity.*; 11 import org.apache.avalon.framework.component.*; 12 import org.apache.avalon.framework.configuration.*; 13 import org.apache.avalon.framework.context.*; 14 import org.apache.avalon.framework.logger.*; 15 16 import org.apache.avalon.excalibur.collections.FixedSizeBuffer; 17 import org.apache.avalon.excalibur.command.*; 18 import org.apache.avalon.excalibur.system.handler.*; 19 import org.apache.avalon.excalibur.logger.LoggerManager; 20 import org.apache.avalon.excalibur.event.Queue; 21 import org.apache.avalon.excalibur.pool.PoolManager; 22 import org.apache.avalon.excalibur.util.ComponentStateValidator; 23 24 import java.util.ArrayList ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 31 import java.lang.reflect.Constructor ; 32 33 41 public abstract class AbstractContainer 42 extends AbstractLogEnabled 43 implements Contextualizable, Composable, Configurable, Initializable, Disposable 44 { 45 private final ComponentStateValidator m_validator = new ComponentStateValidator( this ); 46 47 private Context m_context; 48 private ComponentManager m_manager; 49 private ComponentManager m_childManager; 50 private LoggerManager m_logManager; 51 private PoolManager m_poolManager; 52 private Queue m_commandQueue; 53 private ClassLoader m_classLoader; 54 private RoleManager m_roleManager; 55 private Configuration m_configuration; 56 private List m_components; 57 private Map m_configs; 58 59 62 public void enableLogging( Logger logger ) 63 { 64 m_validator.checkLogEnabled(); 65 super.enableLogging( logger ); 66 } 67 68 72 public void contextualize( Context containerContext ) 73 throws ContextException 74 { 75 m_validator.checkContextualized(); 76 77 m_context = containerContext; 78 79 m_logManager = (LoggerManager) m_context.get(Container.LOGGER_MANAGER); 80 m_poolManager = (PoolManager) m_context.get(Container.POOL_MANAGER); 81 82 try 83 { 84 m_classLoader = (ClassLoader ) m_context.get(Container.CONTEXT_CLASSLOADER); 85 } 86 catch ( ContextException ce ) 87 { 88 m_classLoader = Thread.currentThread().getContextClassLoader(); 89 } 90 91 try 92 { 93 m_commandQueue = (Queue) m_context.get(Container.COMMAND_QUEUE); 94 } 95 catch ( ContextException ce ) 96 { 97 m_commandQueue = null; 98 getLogger().warn("No Container.COMMAND_QUEUE is given, all management will be performed synchronously"); 99 } 100 101 try 102 { 103 m_roleManager = (RoleManager) m_context.get(Container.ROLE_MANAGER); 104 } 105 catch ( ContextException ce ) 106 { 107 m_roleManager = new ExcaliburRoleManager(); 108 } 109 } 110 111 116 public void configure( Configuration configElement ) 117 throws ConfigurationException 118 { 119 m_validator.checkConfigured(); 120 m_configuration = configElement; 121 Map managerMap = new HashMap (); 122 m_childManager = new ContainerComponentManager( managerMap, m_manager ); 123 124 Configuration[] components = configElement.getChildren(); 125 126 for ( int i = 0; i < components.length; i++ ) 127 { 128 final String name = components[ i ].getName(); 129 String role; 130 Class klass; 131 Class handlerKlass; 132 Configuration config = null; 133 134 if ( name.equals( "component" ) ) 135 { 136 config = components[ i ]; 137 role = config.getAttribute( "role" ); 138 139 try 140 { 141 klass = m_classLoader.loadClass( config.getAttribute( "class" ) ); 142 handlerKlass = m_classLoader.loadClass( config.getAttribute( "handler" ) ); 143 } 144 catch ( Exception e ) 145 { 146 if ( getLogger().isDebugEnabled() ) 147 { 148 getLogger().debug( "Component class '" + config.getAttribute( "class" ) + 149 "' is not valid.", e ); 150 } 151 continue; 152 } 153 154 assignHandler( getHandler( handlerKlass, klass, config ), config, managerMap ); 155 } 156 else 157 { 158 handleConfiguration( components[ i ], managerMap ); 159 } 160 } 161 } 162 163 168 protected void handleConfiguration( final Configuration configItem, 169 final Map managerMap ) 170 throws ConfigurationException 171 { 172 DefaultConfiguration temp = new DefaultConfiguration( "component", "AbstractContainer-rewrite" ); 173 Class klass = m_roleManager.getClassForName( configItem.getName() ); 174 Class handlerKlass = m_roleManager.getHandlerClassForClass( klass ); 175 String role = m_roleManager.getRoleForClass( klass ); 176 177 temp.setAttribute( "role", role ); 178 temp.setAttribute( "class", klass.getName() ); 179 temp.setAttribute( "handler", handlerKlass.getName() ); 180 181 final String id = configItem.getAttribute( "id", null ); 182 if ( null != id ) 183 { 184 temp.setAttribute( "id", id ); 185 } 186 187 Configuration[] children = configItem.getChildren(); 188 for ( int i = 0; i < children.length; i++ ) 189 { 190 temp.addChild( children[ i ] ); 191 } 192 193 temp.makeReadOnly(); 194 195 assignHandler( getHandler( klass, handlerKlass, temp ), temp, managerMap ); 196 } 197 198 201 protected void assignHandler( ComponentHandler handler, Configuration config, Map managerMap ) 202 throws ConfigurationException 203 { 204 m_components.add( handler ); 205 m_configs.put( handler, config ); 206 String role = config.getAttribute( "role" ); 207 208 Object contents = managerMap.get( role ); 209 if ( null == contents ) 210 { 211 managerMap.put( role, handler ); 212 } 213 else 214 { 215 if ( contents instanceof ComponentHandler ) 216 { 217 Map selectorMap = new HashMap ( 3 ); 218 selectorMap.put( ( (Configuration) m_configs.get(contents) ) 219 .getAttribute( "id", "1" ), contents ); 220 selectorMap.put( config.getAttribute( "id", "2" ), contents ); 221 222 assignSelector( role, new ContainerComponentSelector( selectorMap ), managerMap ); 223 } 224 else if ( contents instanceof ContainerComponentSelector ) 225 { 226 ( (ContainerComponentSelector) contents ) 227 .addComponentHandler( config.getAttribute( "id", null ), 228 handler); 229 } 230 } 231 } 232 233 236 protected void assignSelector( String role, ComponentSelector selector, Map managerMap ) 237 throws ConfigurationException 238 { 239 managerMap.put( role, selector ); 240 } 241 242 246 protected ComponentHandler getHandler( Class handlerKlass, 247 Class klass, 248 Configuration configuration ) 249 { 250 Constructor constructor; 251 ComponentHandler handler = null; 252 253 try 254 { 255 constructor = handlerKlass.getConstructor( ComponentHandler.HANDLER_CONSTRUCTOR ); 256 handler = (ComponentHandler) constructor.newInstance(new Object [] { 257 klass, configuration, m_childManager, m_context 258 }); 259 } 260 catch ( Exception e ) 261 { 262 if ( getLogger().isDebugEnabled() ) 263 { 264 getLogger().debug( "Could not create the '" + handlerKlass.getName() + 265 "' handler for the '" + klass.getName() + 266 "' component.", e ); 267 } 268 } 269 270 return handler; 271 } 272 273 277 public void compose( ComponentManager manager ) 278 throws ComponentException 279 { 280 m_validator.checkComposed(); 281 m_manager = manager; 282 } 283 284 287 public void initialize() 288 throws Exception 289 { 290 m_validator.checkInitialized(); 291 292 Iterator i = m_components.iterator(); 293 FixedSizeBuffer buffer = new FixedSizeBuffer( m_components.size() ); 294 295 while ( i.hasNext() ) 296 { 297 try 298 { 299 if ( null != m_commandQueue ) 300 { 301 m_commandQueue.enqueue( 302 new InitComponentHandlerCommand( (ComponentHandler) i.next(), 303 getLogger() ) 304 ); 305 } 306 else 307 { 308 ( (ComponentHandler) i.next() ).initialize(); 309 } 310 } 311 catch ( Exception e ) 312 { 313 getLogger().warn( "Could not initialize component", e ); 314 buffer.add( e ); 315 } 316 } 317 318 if ( buffer.size() > 0 ) 319 { 320 StringBuffer message = new StringBuffer (); 321 322 while ( ! buffer.isEmpty() ) 323 { 324 message.append( ( (Exception ) buffer.remove() ).getMessage() ); 325 } 326 327 throw new Exception ( message.toString() ); 328 } 329 } 330 331 334 public void dispose() 335 { 336 m_validator.checkDisposed(); 337 338 Iterator i = m_components.iterator(); 339 340 while ( i.hasNext() ) 341 { 342 if ( null != m_commandQueue ) 343 { 344 try 345 { 346 m_commandQueue.enqueue( 347 new DisposeComponentHandlerCommand( (ComponentHandler) i.next(), 348 getLogger() ) 349 ); 350 351 i.remove(); 352 } 353 catch ( Exception e ) 354 { 355 if ( getLogger().isWarnEnabled() ) 356 { 357 getLogger().warn( "Could not dispose component", e ); 358 } 359 } 360 } 361 else 362 { 363 ( (ComponentHandler) i.next() ).dispose(); 364 } 365 } 366 } 367 368 373 protected final static class ContainerComponentManager 374 implements ComponentManager 375 { 376 private final Map m_components; 377 private final Map m_used; 378 private final ComponentManager m_parent; 379 380 384 protected ContainerComponentManager( Map componentMap ) 385 { 386 this( componentMap, null ); 387 } 388 389 393 protected ContainerComponentManager( Map componentMap, ComponentManager parent ) 394 { 395 m_parent = null; 396 m_components = componentMap; 397 m_used = new HashMap ( m_components.size() ); 398 } 399 400 public Component lookup( String role ) 401 throws ComponentException 402 { 403 Object temp = m_components.get( role ); 404 405 if ( temp instanceof ComponentSelector ) 406 { 407 return (ComponentSelector) temp; 408 } 409 410 if ( ! ( temp instanceof ComponentHandler ) ) 411 { 412 throw new ComponentException( "Invalid entry in component manager: " + temp ); 413 } 414 415 ComponentHandler handler = (ComponentHandler) temp; 416 417 if ( null == handler ) 418 { 419 if ( null != m_parent ) 420 { 421 return m_parent.lookup( role ); 422 } 423 else 424 { 425 throw new ComponentException( "The role does not exist in the ComponentManager" ); 426 } 427 } 428 429 final Component component; 430 431 try 432 { 433 if ( ! handler.isInitialized() ) 434 { 435 handler.initialize(); 436 } 437 438 component = handler.get(); 439 } 440 catch ( Exception e ) 441 { 442 throw new ComponentException( "Could not return a reference to the Component", e ); 443 } 444 445 synchronized ( m_used ) 446 { 447 m_used.put( component, handler ); 448 } 449 450 return component; 451 } 452 453 public boolean hasComponent( String role ) 454 { 455 final boolean hasComponent = m_components.containsKey( role ); 456 457 if ( ! hasComponent && null != m_parent ) 458 { 459 return m_parent.hasComponent( role ); 460 } 461 462 return hasComponent; 463 } 464 465 public void release( Component component ) 466 { 467 final ComponentHandler handler; 468 469 synchronized ( m_used ) 470 { 471 handler = (ComponentHandler) m_used.remove( component ); 472 } 473 474 if ( null == handler && null != m_parent ) 475 { 476 m_parent.release( component ); 477 return; 478 } 479 480 handler.put( component ); 481 } 482 } 483 484 489 protected final static class ContainerComponentSelector 490 implements ComponentSelector 491 { 492 private final Map m_components; 493 private final Map m_used; 494 495 protected ContainerComponentSelector( Map selectorMap ) 496 { 497 m_components = selectorMap; 498 m_used = new HashMap ( m_components.size() ); 499 } 500 501 public Component select( Object hint ) 502 throws ComponentException 503 { 504 ComponentHandler handler = (ComponentHandler) m_components.get( hint ); 505 506 if ( null == handler ) 507 { 508 throw new ComponentException( "The role does not exist in the ComponentSelector" ); 509 } 510 511 final Component component; 512 513 try 514 { 515 if ( ! handler.isInitialized() ) 516 { 517 handler.initialize(); 518 } 519 520 component = handler.get(); 521 } 522 catch ( Exception e ) 523 { 524 throw new ComponentException( "Could not return a reference to the Component", e ); 525 } 526 527 synchronized ( m_used ) 528 { 529 m_used.put( component, handler ); 530 } 531 532 return component; 533 } 534 535 public boolean hasComponent( Object hint ) 536 { 537 return m_components.containsKey( hint ); 538 } 539 540 public void release( Component component ) 541 { 542 final ComponentHandler handler; 543 544 synchronized ( m_used ) 545 { 546 handler = (ComponentHandler) m_used.remove( component ); 547 } 548 549 handler.put( component ); 550 } 551 552 protected void addComponentHandler( Object hint, ComponentHandler handler ) 553 { 554 if ( null == hint ) 555 { 556 hint = new Integer ( m_components.size() ).toString(); 557 } 558 559 m_components.put( hint, handler ); 560 } 561 } 562 563 566 private final static class InitComponentHandlerCommand implements Command 567 { 568 private final ComponentHandler m_handler; 569 private final Logger m_logger; 570 571 protected InitComponentHandlerCommand( ComponentHandler handler, Logger logger ) 572 { 573 m_handler = handler; 574 m_logger = logger; 575 } 576 577 public void execute() 578 throws Exception 579 { 580 try 581 { 582 if ( ! m_handler.isInitialized() ) 583 { 584 m_handler.initialize(); 585 } 586 } 587 catch ( Exception e ) 588 { 589 if ( m_logger.isErrorEnabled() ) 590 { 591 m_logger.error( "Could not initialize ComponentHandler", e ); 592 } 593 594 throw e; 595 } 596 } 597 } 598 599 602 private final static class DisposeComponentHandlerCommand implements Command 603 { 604 private final ComponentHandler m_handler; 605 private final Logger m_logger; 606 607 protected DisposeComponentHandlerCommand( ComponentHandler handler, Logger logger ) 608 { 609 m_handler = handler; 610 m_logger = logger; 611 } 612 613 public void execute() 614 { 615 m_handler.dispose(); 616 } 617 } 618 } 619 620 | Popular Tags |