org.sape.carbon.core.component
Class DefaultComponentKeeper

java.lang.Object
  |
  +--org.sape.carbon.core.component.DefaultComponentKeeper
All Implemented Interfaces:
ComponentKeeper

public class DefaultComponentKeeper
extends Object
implements ComponentKeeper

The default implemetation of ComponentKeeper. This implementation uses a HashMap to store references to all live components. If requested component does not exist, it delegates to a ComponentFactory to create the requested component. It uses a HashMap of locks to ensure that a component is constructed only once.

Copyright 2002 Sapient

Since:
carbon 1.0
Version:
$Revision: 1.43 $($Author: dvoet $ / $Date: 2003/05/05 21:21:11 $)
Author:
Douglas Voet, January 2002

Field Summary
private  ComponentFactory componentFactory
          ComponentFactory used to build all components in the system.
private  Map componentMap
          Map of all Components known to the system keyed by (String) logicalComponentName.
private  List componentNameList
          List of all component names known to the keeper in order of their creation.
private  Map creationLocks
          Map of locks used to ensure that component are built only once.
private  org.apache.commons.logging.Log log
          Provides handle to Apache-commons logger.
private  Map nascentComponents
          Storage for components that have been created and intialized, but not configured or started.
private  Thread shutdownHook
          Maintains a reference to the thread for shutting down the component system on JVM exit.
 
Constructor Summary
protected DefaultComponentKeeper(ComponentKeeperConfiguration configuration)
          protected constructor prevents direct instantiation but does not prevent extenstion, this is meant to be called by DefaultComponentKeeperFactory
 
Method Summary
private  void addComponent(String logicalComponentName, Component component)
          Puts a component into componentMap using logicalComponentName as the key and adds logicalComponentName to the end of componentNameList.
private  void configure(ComponentKeeperConfiguration keeperConfiguration)
          Lifecycle method to configure the keeper.
 void destroyAllComponents()
          Destroys all components.
 void destroyComponent(String logicalComponentName)
          Destroys the component specified by the name parameter.
 Component fetchComponent(String logicalComponentName)
          Gets a reference to the component specified by the name parameter.
private  Component fetchNewComponent(String logicalComponentName)
          This method fetches a new component.
private  Component getComponent(String logicalComponentName)
          Gets a component from componentMap using logicalComponentName as the key.
 Collection getComponentNames()
          This implementation returns a copy of the keySet of the internal map of components.
private  Object getCreationLock(String name)
          Gets the lock object used to synchronize the creation of the component signified by the supplied name.
protected  void registerShutdownHook()
          Creates a new shutdown hook, if one does not already exist, and registers it with the JVM shutdown hook.
private  Component removeComponent(String logicalComponentName)
          Removes the component keyed by logicalComponentName from componentMap and removes logicalComponentName from componentNameList.
private  void startComponent(String logicalComponentName, Component component)
          Calls the Lifecycle subsystem to configure and start the component.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

private org.apache.commons.logging.Log log
Provides handle to Apache-commons logger.


componentFactory

private ComponentFactory componentFactory

ComponentFactory used to build all components in the system.


creationLocks

private Map creationLocks
Map of locks used to ensure that component are built only once. Key = (String) logicalComponentName, Value = (Object) lock.


componentMap

private Map componentMap

Map of all Components known to the system keyed by (String) logicalComponentName.


nascentComponents

private Map nascentComponents
Storage for components that have been created and intialized, but not configured or started. Used only in fetchNewComponent().


componentNameList

private List componentNameList

List of all component names known to the keeper in order of their creation. Used in destroyAllComponents to determine the order in which to destroy components.

The List implementation used is LinkedList. This is because it is fast when it comes to appending or removing items. LikedLists are not optimized for Random access, but this will be rare (only when destroyComponent is called outside of destroyAllComponents).


shutdownHook

private Thread shutdownHook
Maintains a reference to the thread for shutting down the component system on JVM exit.

Constructor Detail

DefaultComponentKeeper

protected DefaultComponentKeeper(ComponentKeeperConfiguration configuration)
protected constructor prevents direct instantiation but does not prevent extenstion, this is meant to be called by DefaultComponentKeeperFactory

Parameters:
configuration - the configuration of this component keeper
Method Detail

registerShutdownHook

protected void registerShutdownHook()

Creates a new shutdown hook, if one does not already exist, and registers it with the JVM shutdown hook.

See Also:
Runtime.addShutdownHook(java.lang.Thread)

fetchComponent

public Component fetchComponent(String logicalComponentName)

Gets a reference to the component specified by the name parameter. Builds the component if it has not yet been created.

This implementation delegates to a ComponentFactory to build components.

Specified by:
fetchComponent in interface ComponentKeeper
Parameters:
logicalComponentName - the name of the component
Returns:
a reference to the component specified by name
Throws:
ComponentNotFoundException - if the component specified by logicalComponentName cannot be found in configuration.
InvalidParameterException - if logicalComponentName is an empty string or logicalComponentName is null

destroyAllComponents

public void destroyAllComponents()

Destroys all components.

This implementation destroys components in the order in which they were created. Note that this will halt all requests for components until all existing components are destroyed.

Specified by:
destroyAllComponents in interface ComponentKeeper
Since:
carbon 1.0

destroyComponent

public void destroyComponent(String logicalComponentName)

Destroys the component specified by the name parameter.

Specified by:
destroyComponent in interface ComponentKeeper
Parameters:
logicalComponentName - the name of the component

getComponentNames

public Collection getComponentNames()
This implementation returns a copy of the keySet of the internal map of components.

Specified by:
getComponentNames in interface ComponentKeeper
Returns:
a collection of all components in this keeper
See Also:
ComponentKeeper.getComponentNames()

configure

private void configure(ComponentKeeperConfiguration keeperConfiguration)

Lifecycle method to configure the keeper. This method instantiates ComponentFactory. This must be called prior to using the keeper.

Parameters:
keeperConfiguration - the configuration of this component keeper

getComponent

private Component getComponent(String logicalComponentName)
Gets a component from componentMap using logicalComponentName as the key. Syncronized on componentMap.

Parameters:
logicalComponentName - name of the component
Returns:
Component the requested component or null if it is not in componentMap

addComponent

private void addComponent(String logicalComponentName,
                          Component component)
Puts a component into componentMap using logicalComponentName as the key and adds logicalComponentName to the end of componentNameList. Syncronized on componentMap.

Parameters:
logicalComponentName - name of the component
component - component object to add

removeComponent

private Component removeComponent(String logicalComponentName)
Removes the component keyed by logicalComponentName from componentMap and removes logicalComponentName from componentNameList. Syncronized on componentMap.

Parameters:
logicalComponentName - name of the component to remove
Returns:
Component the removed component or null if it is not in componentMap

fetchNewComponent

private Component fetchNewComponent(String logicalComponentName)

This method fetches a new component. It deals with the concurency issues associated with multiple threads requesting a component that has not yet been created at the same time. It ensures that only one thread will create the component. This is done through the follwing logic:

  1. Synchrnize on the lock for the requested component. Once this is done, it is guranteed that the current thread is the only one manipulating the component.
  2. Check the main component map (this.componentMap) to see if the requested component is there. If it is, another thread has created it and started it. Return the component from the main map.
  3. Check the nacentComponents to see the component is there. If it is, this is a circular dependency and the thread is reentering the method looking for the component for the nth time. The component has been created and initialized, but not configured or started. Return the component from nacentComponents
  4. If we have gotten this far, no other thread has created the component so build the component using the component factory.
  5. Place the component in nacentComponents so reentrant requests can see the component.
  6. Start the component (calls the lifecycle methods configure and start). This is where circular references may be initiated.
  7. Remove the component from nacentComponents, put it in the main component map and return the newly constructed component.

Parameters:
logicalComponentName - the name of the new component
Returns:
the new component

startComponent

private void startComponent(String logicalComponentName,
                            Component component)

Calls the Lifecycle subsystem to configure and start the component. When this call completes, the component should be in a LifecycleStateEnum.RUNNING state.

Parameters:
logicalComponentName - the name of component to start
component - the component to start

getCreationLock

private Object getCreationLock(String name)
Gets the lock object used to synchronize the creation of the component signified by the supplied name.

Parameters:
name - the name of the component to get the lock for
Returns:
Object the lock object used to synchronize the creation of any components with the given name


Copyright 1999-2003 Sapient Corporation. All Rights Reserved.