cz.cuni.amis.pogamut.base.component.controller
Class SharedComponentController<COMPONENT extends ISharedComponent>

java.lang.Object
  extended by cz.cuni.amis.pogamut.base.component.controller.AbstractComponentControllerBase<COMPONENT>
      extended by cz.cuni.amis.pogamut.base.component.controller.SharedComponentController<COMPONENT>
All Implemented Interfaces:
IComponentControllerBase<COMPONENT>, ISharedComponentController<COMPONENT>, IComponent, ISharedComponent

public class SharedComponentController<COMPONENT extends ISharedComponent>
extends AbstractComponentControllerBase<COMPONENT>
implements ISharedComponentController<COMPONENT>

Shared component controller is meant to provide management of lifecycle methods of the ISharedComponent while providing methods that has to be implemented by any ISharedComponent.

You can't actualy create ISharedComponent by extending this class, you have to create your own class implementing ISharedComponent interface and instantiate this class (wrap it) for yourself (and delegete all calls to methods from ISharedComponent to this class).

This decision has been deliberately made in order to allow anybody to create their shared components out of blue and add lifecycle-management later on using this object.

To get the impression of what this class is doing, first read javadoc for ComponentController. Read? Good! So this object does something similar as ComponentController but not for simple IComponent but for ISharedComponent which means that we're dealing with the component that is shared by multiple agent instances, i.e., component that will be active on multiple ILifecycleBuses. Which means that we must auto-start/stop controlled component differently than ComponentController is doing.

The component should be started when any agent using it is starting and should be stop when the last agent that is using it is stopping. Similar things applies for pause/resume. Simple to say, harder to perform. Nevertheless, the implementation is here ;-)


Nested Class Summary
protected  class SharedComponentController.ComponentStateListener
           
protected  class SharedComponentController.ControlHelper
           
protected  class SharedComponentController.LocalController
          Used as IComponentControlHelper that is passed to every ILifecycleBus.addLifecycleManagement(IComponent, IComponentControlHelper, ComponentDependencies) sensing decisions of ordinary ComponentController that signalizes when the component should be started for a given bus.
 
Nested classes/interfaces inherited from class cz.cuni.amis.pogamut.base.component.controller.AbstractComponentControllerBase
AbstractComponentControllerBase.AwaitState
 
Field Summary
protected  java.util.Map<ComponentState,java.lang.Integer> componentStateCount
          Map tracking count of states of dependencies.
protected  java.util.Map<IAgentId,ComponentState> componentStates
          This map holds the currently desired AbstractComponentControllerBase.component state inside the agent's bus.
protected  java.lang.Object ctrlMutex
          Mutex that is synchronizing access to internal data structures of the controller.
protected  IFatalErrorEvent fatalError
          Last fatal error sensed.
protected  java.util.Map<IAgentId,SharedComponentController.ControlHelper> localControlHelpers
          Control helpers that are used to signalizes starting/stopping of the controlled AbstractComponentControllerBase.component inside bus of respective agents.
protected  java.util.Map<IAgentId,SharedComponentController.LocalController> localControllers
          Controllers that are used to store IComponentController provided by respective ILifecycleBus.addLifecycleManagement(IComponent, IComponentControlHelper, ComponentDependencies) of agents using the component.
 
Fields inherited from class cz.cuni.amis.pogamut.base.component.controller.AbstractComponentControllerBase
broadcastingEvents, component, componentState, control, controllerId, log
 
Constructor Summary
SharedComponentController(COMPONENT component, ISharedComponentControlHelper componentControl, java.util.logging.Logger log)
          Default constructor.
 
Method Summary
 void addComponentBus(IAgentId agentId, ILifecycleBus bus, ComponentDependencies dependencies)
          Informs the component that it is part of another ILifecycleBus, i.e., it has become used by new agent with 'agentId'.
protected  void agentStoppedUsingTheComponent(IAgentId agentId, ComponentState oldState)
           
protected  int alterStateCount(ComponentState state, int change)
          Changes the count (by 'change') of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().
protected  void checkStateCount(int newCount, ComponentState state)
          Checks sanity of the 'state' count 'newCount'
protected  void componentStateChanged(IAgentId origin, ComponentState oldState, ComponentState newState)
           
protected  void componentStateCountChanged(IAgentId origin, ComponentState oldState, ComponentState newState)
           
protected  int decreaseStateCount(ComponentState state)
          Decreases (-1) count of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().
protected  int decreaseStateCount(ComponentState state, int n)
          Decreases (-n) count of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().
 void fatalError(java.lang.String message)
          Broadcasts fatal error with controlled component as source.
 void fatalError(java.lang.String message, java.lang.Throwable e)
          Broadcasts fatal error with controlled component as source.
 ISharedComponentControlHelper getComponentControl()
          Returns component control with lifecycle methods of the component controlled by this instance.
 IFatalErrorEvent getFatalError()
          Returns last fatal error event that has triggered the system failure.
 int getStateCount(ComponentState... states)
          Return how many components are in one of 'states'
protected  int increaseStateCount(ComponentState state)
          Increases (+1) count of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().
protected  int increaseStateCount(ComponentState state, int n)
          Increases count (+n) of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().
 boolean isDependent(IAgentId agentId, IComponent component)
          Whether the controlled component is dependent on 'component' of the agent identified by 'agentId'.
 boolean isDependent(IAgentId agentId, IToken componentId)
          Whether the controlled component is dependent on component (identified by 'componentId') of the agent identified by 'agentId'.
 boolean isUsedBy(IAgentId agentId)
          Tells whether the agent identified by 'agentId' is currently using the controlled component, i.e., this component controller registers the component to agent's ILifecycleBus and is watching it for auto start/stop/pause/resume/...
protected  void kill(IAgentId agentId, java.lang.String message, java.lang.Throwable cause)
          AgentId has broadcast IFatalErrorEvent, tear down the whole system!
protected  void localKill(IAgentId agentId)
           
protected  void localPause(IAgentId agentId)
           
protected  void localPrePause(IAgentId agentId)
           
protected  void localPreResume(IAgentId agentId)
           
protected  void localPreStart(IAgentId agentId)
           
protected  void localPreStartPaused(IAgentId agentId)
           
protected  void localPreStop(IAgentId agentId)
           
protected  void localReset(IAgentId agentId)
           
protected  void localResume(IAgentId agentId)
           
protected  void localStart(IAgentId agentId)
           
protected  void localStartPaused(IAgentId agentId)
           
protected  void localStop(IAgentId agentId)
           
 void manualKill(java.lang.String reason)
          Provides the way to kill the component (constructor of this controller).
 void manualPause(java.lang.String reason)
          Provides the way to pause the component (constructor of this controller).
 void manualResume(java.lang.String reason)
          Provides the way to pause the component (constructor of this controller).
 void manualStart(java.lang.String reason)
          Provides the way to manually start the component.
 void manualStartPaused(java.lang.String reason)
          Provides the way to manually start the component into paused state.
 void manualStop(java.lang.String reason)
          Provides the way to stop the component (constructor of this controller).
protected  void newAgentIsUsingTheComponent(IAgentId agentId, ComponentState state)
           
protected  void pause()
           
 void removeComponentBus(IAgentId agentId, ILifecycleBus bus)
          Informs the component that it ceased to be the part of the ILifecycleBus, i.e., it has stopped to be used by agent with 'agentId'.
protected  void reset()
           
protected  void resume()
           
protected  void setState(IAgentId agentId, ComponentState newState)
          Changes the state of the component for given agentId, triggers SharedComponentController#componentStateCountChanged().
protected  void setState(IAgentId agentId, ComponentState oldState, ComponentState newState)
          Changes the state of the component for given agentId, triggers SharedComponentController#componentStateCountChanged().
protected  void start()
           
protected  void startPaused()
           
protected  void stateChanged(IAgentId agentId, ComponentState changedValue)
          Signal that the component in the bus of agent identified by 'agentId' has changed into 'changedValue'.
protected  void stop()
           
 
Methods inherited from class cz.cuni.amis.pogamut.base.component.controller.AbstractComponentControllerBase
awaitState, awaitState, getComponent, getComponentId, getLog, getState, id, inState, isBroadcastingEvents, isPaused, isRunning, notInState, setBroadcastingEvents, setState, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface cz.cuni.amis.pogamut.base.component.controller.IComponentControllerBase
awaitState, awaitState, getComponent, getState, inState, isBroadcastingEvents, isPaused, isRunning, notInState, setBroadcastingEvents
 
Methods inherited from interface cz.cuni.amis.pogamut.base.component.IComponent
getComponentId
 

Field Detail

ctrlMutex

protected java.lang.Object ctrlMutex
Mutex that is synchronizing access to internal data structures of the controller.


localControlHelpers

protected java.util.Map<IAgentId,SharedComponentController.ControlHelper> localControlHelpers
Control helpers that are used to signalizes starting/stopping of the controlled AbstractComponentControllerBase.component inside bus of respective agents.


localControllers

protected java.util.Map<IAgentId,SharedComponentController.LocalController> localControllers
Controllers that are used to store IComponentController provided by respective ILifecycleBus.addLifecycleManagement(IComponent, IComponentControlHelper, ComponentDependencies) of agents using the component.


componentStates

protected java.util.Map<IAgentId,ComponentState> componentStates
This map holds the currently desired AbstractComponentControllerBase.component state inside the agent's bus.


componentStateCount

protected java.util.Map<ComponentState,java.lang.Integer> componentStateCount
Map tracking count of states of dependencies.


fatalError

protected IFatalErrorEvent fatalError
Last fatal error sensed.

Constructor Detail

SharedComponentController

public SharedComponentController(COMPONENT component,
                                 ISharedComponentControlHelper componentControl,
                                 java.util.logging.Logger log)
Default constructor. Nothing fancy...

Parameters:
component -
componentControl -
log -
Method Detail

getComponentControl

public ISharedComponentControlHelper getComponentControl()
Description copied from interface: IComponentControllerBase
Returns component control with lifecycle methods of the component controlled by this instance. I.e., methods that are directly controlling the component IComponentControllerBase.getComponent().

IT IS DISCOURAGED TO USE METHODS OF THE IComponentControlHelper DIRECTLY! IT DEFIES THE PURPOSE OF THE CONTROLLER TOTALLY AND THE CONTROLLER WILL PROBABLY WON'T COPE WITH SUCH BEHAVIOR.

But what the hell, if it solves your problem, go ahead ;-)

Specified by:
getComponentControl in interface IComponentControllerBase<COMPONENT extends ISharedComponent>
Overrides:
getComponentControl in class AbstractComponentControllerBase<COMPONENT extends ISharedComponent>
Returns:

addComponentBus

public void addComponentBus(IAgentId agentId,
                            ILifecycleBus bus,
                            ComponentDependencies dependencies)
Description copied from interface: ISharedComponent
Informs the component that it is part of another ILifecycleBus, i.e., it has become used by new agent with 'agentId'.

The component is obliged to register to that bus a watch for the lifecycle state of various components inside the bus.

Specified by:
addComponentBus in interface ISharedComponent

removeComponentBus

public void removeComponentBus(IAgentId agentId,
                               ILifecycleBus bus)
Description copied from interface: ISharedComponent
Informs the component that it ceased to be the part of the ILifecycleBus, i.e., it has stopped to be used by agent with 'agentId'.

Specified by:
removeComponentBus in interface ISharedComponent

isUsedBy

public boolean isUsedBy(IAgentId agentId)
Description copied from interface: ISharedComponentController
Tells whether the agent identified by 'agentId' is currently using the controlled component, i.e., this component controller registers the component to agent's ILifecycleBus and is watching it for auto start/stop/pause/resume/...

Specified by:
isUsedBy in interface ISharedComponentController<COMPONENT extends ISharedComponent>
Returns:

isDependent

public boolean isDependent(IAgentId agentId,
                           IToken componentId)
Description copied from interface: ISharedComponentController
Whether the controlled component is dependent on component (identified by 'componentId') of the agent identified by 'agentId'.

Note that two IComponent belonging to different agents may have the same 'componentId'.

Specified by:
isDependent in interface ISharedComponentController<COMPONENT extends ISharedComponent>
Returns:

isDependent

public boolean isDependent(IAgentId agentId,
                           IComponent component)
Description copied from interface: ISharedComponentController
Whether the controlled component is dependent on 'component' of the agent identified by 'agentId'.

Specified by:
isDependent in interface ISharedComponentController<COMPONENT extends ISharedComponent>
Returns:

fatalError

public void fatalError(java.lang.String message)
Description copied from interface: IComponentControllerBase
Broadcasts fatal error with controlled component as source.

Sets state to KILLING, broadcasts IFatalErrorEvent and then sets the state to KILLED.

WARNING: Note that the ComponentController assumes that you will kill your component yourself before or after you call this method. Therefore the components kill() method won't be called. That's because whenever fatal error occurs, the component is in undefined state and you have to decide what to do based on that fatal error.

Specified by:
fatalError in interface IComponentControllerBase<COMPONENT extends ISharedComponent>

fatalError

public void fatalError(java.lang.String message,
                       java.lang.Throwable e)
Description copied from interface: IComponentControllerBase
Broadcasts fatal error with controlled component as source.

Sets state to KILLING, broadcasts IFatalErrorEvent and then sets the state to KILLED.

WARNING: Note that the ComponentController assumes that you will kill your component yourself before or after you call this method. Therefore the components kill() method won't be called. That's because whenever fatal error occurs, the component is in undefined state and you have to decide what to do based on that fatal error.

Specified by:
fatalError in interface IComponentControllerBase<COMPONENT extends ISharedComponent>

getFatalError

public IFatalErrorEvent getFatalError()
Description copied from interface: IComponentControllerBase
Returns last fatal error event that has triggered the system failure.

Specified by:
getFatalError in interface IComponentControllerBase<COMPONENT extends ISharedComponent>

manualStart

public void manualStart(java.lang.String reason)
Description copied from interface: IComponentControllerBase
Provides the way to manually start the component.

Specified by:
manualStart in interface IComponentControllerBase<COMPONENT extends ISharedComponent>

manualStartPaused

public void manualStartPaused(java.lang.String reason)
Description copied from interface: IComponentControllerBase
Provides the way to manually start the component into paused state.

Specified by:
manualStartPaused in interface IComponentControllerBase<COMPONENT extends ISharedComponent>

manualPause

public void manualPause(java.lang.String reason)
Description copied from interface: IComponentControllerBase
Provides the way to pause the component (constructor of this controller).

Note that you should not use IComponentControlHelper.pause() alone to stop your component as it won't produce IPausingEvent and IPausedEvent.

Specified by:
manualPause in interface IComponentControllerBase<COMPONENT extends ISharedComponent>
Parameters:
reason - why the component is pausing

manualResume

public void manualResume(java.lang.String reason)
Description copied from interface: IComponentControllerBase
Provides the way to pause the component (constructor of this controller).

Note that you should not use IComponentControlHelper.pause() alone to stop your component as it won't produce IPausingEvent and IPausedEvent.

Specified by:
manualResume in interface IComponentControllerBase<COMPONENT extends ISharedComponent>
Parameters:
reason - why the component is pausing

manualStop

public void manualStop(java.lang.String reason)
Description copied from interface: IComponentControllerBase
Provides the way to stop the component (constructor of this controller).

Note that you should not use IComponentControlHelper.stop() alone to stop your component as it won't produce IStoppingEvent and IStoppedEvent.

If you require your component to stop prematurely - call this method.

Specified by:
manualStop in interface IComponentControllerBase<COMPONENT extends ISharedComponent>
Parameters:
reason - why the component is stopping

manualKill

public void manualKill(java.lang.String reason)
Description copied from interface: IComponentControllerBase
Provides the way to kill the component (constructor of this controller).

Note that you should not use IComponentControlHelper.kill() alone to stop your component as it won't produce IFatalErrorEvent.

If you require your component to stop prematurely - call this method.

Specified by:
manualKill in interface IComponentControllerBase<COMPONENT extends ISharedComponent>
Parameters:
reason - why the component is stopping

getStateCount

public int getStateCount(ComponentState... states)
Return how many components are in one of 'states'

Parameters:
states -
Returns:
number of components in one of 'states'

checkStateCount

protected void checkStateCount(int newCount,
                               ComponentState state)
Checks sanity of the 'state' count 'newCount'

Parameters:
newCount -
state -

alterStateCount

protected int alterStateCount(ComponentState state,
                              int change)
Changes the count (by 'change') of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().

Parameters:
state -

increaseStateCount

protected int increaseStateCount(ComponentState state)
Increases (+1) count of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().

Parameters:
state -

increaseStateCount

protected int increaseStateCount(ComponentState state,
                                 int n)
Increases count (+n) of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().

Parameters:
state -

decreaseStateCount

protected int decreaseStateCount(ComponentState state)
Decreases (-1) count of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().

Parameters:
state -

decreaseStateCount

protected int decreaseStateCount(ComponentState state,
                                 int n)
Decreases (-n) count of the 'state', DOES NOT TRIGGER SharedComponentController#componentStateCountChanged().

Parameters:
state -

localPreStart

protected void localPreStart(IAgentId agentId)

localStart

protected void localStart(IAgentId agentId)

localPreStartPaused

protected void localPreStartPaused(IAgentId agentId)

localStartPaused

protected void localStartPaused(IAgentId agentId)

localPrePause

protected void localPrePause(IAgentId agentId)

localPause

protected void localPause(IAgentId agentId)

localPreResume

protected void localPreResume(IAgentId agentId)

localResume

protected void localResume(IAgentId agentId)

localPreStop

protected void localPreStop(IAgentId agentId)

localStop

protected void localStop(IAgentId agentId)

localKill

protected void localKill(IAgentId agentId)

localReset

protected void localReset(IAgentId agentId)

stateChanged

protected void stateChanged(IAgentId agentId,
                            ComponentState changedValue)
Signal that the component in the bus of agent identified by 'agentId' has changed into 'changedValue'.


setState

protected void setState(IAgentId agentId,
                        ComponentState newState)
Changes the state of the component for given agentId, triggers SharedComponentController#componentStateCountChanged().

Parameters:
agentId -
newState - may be null (== agentId has been deleted)

setState

protected void setState(IAgentId agentId,
                        ComponentState oldState,
                        ComponentState newState)
Changes the state of the component for given agentId, triggers SharedComponentController#componentStateCountChanged().

Parameters:
agentId -
oldState - may be null (== there was no previous state stored), MUST BE CORRECT!
newState - may be null (== agentId has been deleted)

componentStateCountChanged

protected void componentStateCountChanged(IAgentId origin,
                                          ComponentState oldState,
                                          ComponentState newState)

newAgentIsUsingTheComponent

protected void newAgentIsUsingTheComponent(IAgentId agentId,
                                           ComponentState state)

agentStoppedUsingTheComponent

protected void agentStoppedUsingTheComponent(IAgentId agentId,
                                             ComponentState oldState)

componentStateChanged

protected void componentStateChanged(IAgentId origin,
                                     ComponentState oldState,
                                     ComponentState newState)

start

protected void start()

startPaused

protected void startPaused()

pause

protected void pause()

resume

protected void resume()

stop

protected void stop()

kill

protected void kill(IAgentId agentId,
                    java.lang.String message,
                    java.lang.Throwable cause)
AgentId has broadcast IFatalErrorEvent, tear down the whole system!

Parameters:
agentId - may be null

reset

protected void reset()