1 17 18 package org.sape.carbon.core.component; 19 20 import java.util.Collection ; 21 import java.util.HashMap ; 22 import java.util.HashSet ; 23 import java.util.LinkedList ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import org.sape.carbon.core.component.factory.ComponentFactory; 28 import org.sape.carbon.core.component.factory.ComponentFactoryConfiguration; 29 import org.sape.carbon.core.component.lifecycle.LifecycleInterceptor; 30 import org.sape.carbon.core.component.lifecycle.LifecycleStateEnum; 31 import org.sape.carbon.core.config.Config; 32 import org.sape.carbon.core.config.InvalidConfigurationException; 33 import org.sape.carbon.core.exception.ExceptionUtility; 34 import org.sape.carbon.core.exception.InvalidParameterException; 35 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 39 40 54 public class DefaultComponentKeeper implements ComponentKeeper { 55 56 57 private Log log = LogFactory.getLog(this.getClass()); 58 59 60 private ComponentFactory componentFactory = null; 61 62 66 private Map creationLocks = new HashMap (); 67 68 75 private Map componentMap = new HashMap (); 76 77 82 private Map nascentComponents = new HashMap (); 83 84 94 private List componentNameList = new LinkedList (); 95 96 100 private Thread shutdownHook; 101 102 103 104 105 112 protected DefaultComponentKeeper( 113 ComponentKeeperConfiguration configuration) { 114 115 if (log.isTraceEnabled()) { 116 log.trace("Configuring the default component keeper"); 117 } 118 119 configure(configuration); 120 121 } 122 123 129 protected void registerShutdownHook() { 130 if (log.isInfoEnabled()) { 131 log.info("Registering JVM shutdown hook for ComponentKeeper."); 132 } 133 134 if (this.shutdownHook == null) { 135 this.shutdownHook = new Thread (new Runnable () { 136 public void run() { 137 System.out.println( 138 "System shutting down. Destroying all components."); 139 try { 140 destroyAllComponents(); 141 } catch (Exception e) { 142 System.out.println( 143 ExceptionUtility.printStackTracesToString(e)); 144 } 145 System.out.println( 146 "System shut down complete."); 147 } 148 }, "Carbon Shutdown Thread"); 149 this.shutdownHook.setName("Carbon Shutdown Hook"); 150 Runtime.getRuntime().addShutdownHook(this.shutdownHook); 151 } 152 } 153 154 170 public Component fetchComponent(String logicalComponentName) { 171 if (logicalComponentName == null || logicalComponentName.equals("")) { 172 throw new InvalidParameterException(this.getClass(), 173 "logicalComponentName was an empty String"); 174 } 175 176 if (log.isTraceEnabled()) { 177 log.trace("fetching component: [" 178 + logicalComponentName 179 + "]"); 180 } 181 182 Component requestedComponent = getComponent(logicalComponentName); 183 184 if (requestedComponent != null 185 && ((LifecycleInterceptor) requestedComponent).getLifecycleState() 186 == LifecycleStateEnum.DESTROYED) { 187 188 destroyComponent(logicalComponentName); 192 requestedComponent = null; 196 } 197 198 if (requestedComponent == null) { 199 requestedComponent = fetchNewComponent(logicalComponentName); 201 } 202 return requestedComponent; 203 } 204 205 214 public void destroyAllComponents() { 215 synchronized (this.componentMap) { 217 if (log.isTraceEnabled()) { 218 log.trace("destroying all components"); 219 } 220 while (!this.componentNameList.isEmpty()) { 221 destroyComponent((String ) this.componentNameList.get(0)); 222 } 223 } 224 } 225 226 231 public void destroyComponent(String logicalComponentName) { 232 233 if (log.isTraceEnabled()) { 234 log.trace("destroying component: " + logicalComponentName); 235 } 236 237 LifecycleInterceptor requestedComponent; 238 requestedComponent = 241 (LifecycleInterceptor) removeComponent(logicalComponentName); 242 243 if (requestedComponent != null) { 244 requestedComponent.destroyComponent(); 245 } 246 } 247 248 255 public Collection getComponentNames() { 256 synchronized (this.componentMap) { 257 return new HashSet (this.componentMap.keySet()); 258 } 259 } 260 261 267 private void configure(ComponentKeeperConfiguration keeperConfiguration) { 268 ComponentFactoryConfiguration factoryConfiguration = 269 keeperConfiguration.getComponentFactoryConfiguration(); 270 271 try { 272 273 this.componentFactory = 274 (ComponentFactory) factoryConfiguration 275 .getComponentFactoryClass() 276 .newInstance(); 277 278 if (log.isTraceEnabled()) { 279 log.trace("Initialized [" 280 + this.componentFactory.getClass().getName() 281 + "] as component factory"); 282 } 283 284 } catch (ClassCastException cce) { 285 throw new InvalidConfigurationException( 286 this.getClass(), 287 keeperConfiguration.getConfigurationName(), 288 "ComponentFactoryClass", 289 "Specifed ComponentFactory [" 290 + factoryConfiguration.getComponentFactoryClass() 291 + "] does not implement ComponentFactory", 292 cce); 293 294 } catch (InstantiationException ie) { 295 throw new InvalidConfigurationException( 296 this.getClass(), 297 keeperConfiguration.getConfigurationName(), 298 "ComponentFactoryClass", 299 "Could not instantiate ComponentFactory [" 300 + factoryConfiguration.getComponentFactoryClass() 301 + "]", 302 ie); 303 304 } catch (IllegalAccessException iae) { 305 throw new InvalidConfigurationException( 306 this.getClass(), 307 keeperConfiguration.getConfigurationName(), 308 "ComponentFactoryClass", 309 "Could not instantiate ComponentFactory [" 310 + factoryConfiguration.getComponentFactoryClass() 311 + "]", 312 iae); 313 } 314 315 if (keeperConfiguration.isRegisterShutdownHook()) { 316 registerShutdownHook(); 317 } 318 } 319 320 328 private Component getComponent(String logicalComponentName) { 329 synchronized (this.componentMap) { 330 return (Component) this.componentMap.get(logicalComponentName); 331 } 332 } 333 334 342 private void addComponent( 343 String logicalComponentName, 344 Component component) { 345 346 synchronized (this.componentMap) { 347 this.componentMap.put(logicalComponentName, component); 350 this.componentNameList.add(logicalComponentName); 352 } 353 } 354 355 364 private Component removeComponent(String logicalComponentName) { 365 synchronized (this.componentMap) { 366 this.componentNameList.remove(logicalComponentName); 367 return (Component) this.componentMap.remove(logicalComponentName); 368 } 369 } 370 371 402 private Component fetchNewComponent(String logicalComponentName) { 403 404 if (log.isTraceEnabled()) { 405 log.trace("fetching new component: " + logicalComponentName); 406 } 407 408 Object requestedComponentLock = getCreationLock(logicalComponentName); 411 412 synchronized (requestedComponentLock) { 413 Component requestedComponent = getComponent(logicalComponentName); 414 415 if (requestedComponent == null) { 416 synchronized (this.nascentComponents) { 419 requestedComponent = 420 (Component) this.nascentComponents.get( 421 logicalComponentName); 422 } 423 424 if (requestedComponent == null) { 425 requestedComponent = 427 this.componentFactory.getInstance(logicalComponentName); 428 429 synchronized (this.nascentComponents) { 432 this.nascentComponents.put( 433 logicalComponentName, 434 requestedComponent); 435 } 436 437 try { 439 startComponent( 440 logicalComponentName, 441 requestedComponent); 442 443 } finally { 444 synchronized (this.nascentComponents) { 448 this.nascentComponents.remove(logicalComponentName); 449 } 450 } 451 452 addComponent(logicalComponentName, requestedComponent); 454 } 455 } 456 457 return requestedComponent; 458 } 459 460 } 461 462 470 private void startComponent( 471 String logicalComponentName, 472 Component component) { 473 474 if (log.isTraceEnabled()) { 475 log.trace("starting component: " + logicalComponentName); 476 } 477 478 LifecycleInterceptor lifecycleComponentView = 479 (LifecycleInterceptor) component; 480 481 ComponentConfiguration configuration = 482 (ComponentConfiguration) Config.getInstance().fetchConfiguration( 483 logicalComponentName); 484 lifecycleComponentView.configureComponent(configuration); 485 lifecycleComponentView.startComponent(); 486 } 487 488 495 private Object getCreationLock(String name) { 496 synchronized (this.creationLocks) { 497 Object lock = this.creationLocks.get(name); 498 if (lock == null) { 499 lock = new Object (); 500 this.creationLocks.put(name, lock); 501 } 502 503 return lock; 504 } 505 } 506 } 507 | Popular Tags |