cz.cuni.amis.pogamut.base.factory.guice
Class GuiceAgentModule<PARAMS extends IAgentParameters>

java.lang.Object
  extended by com.google.inject.AbstractModule
      extended by cz.cuni.amis.pogamut.base.factory.guice.GuiceAgentModule<PARAMS>
All Implemented Interfaces:
com.google.inject.Module
Direct Known Subclasses:
GuiceCommunicationModule

public class GuiceAgentModule<PARAMS extends IAgentParameters>
extends com.google.inject.AbstractModule

GuiceAgentModule, implementation of AbstractModule, provides a way to hierarchically specify the bindings for interfaces and classes.

The module is a place where you assemble the pieces of the dependency puzzle. You're specifying which implementor should be created for specific interface, etc. This sounds good but then you find out that it is somehow hard to override once set bindings.

The GuiceAgentModule solves this by providing addModule(AbstractModule) method that should be called from configureModules() (see their javadocs). The configureModules() is meant to be overridden in every descendant of the GuiceAgentModule where it should call super.configureModules() and than add another module to the queue via addModule(AbstractModule). We're simply collecting respective modules in every configureModules() implementation. These collected modules are than applied inside standard Guice's method configure() where they are applied in the order they have been added (that's why you have to call super.configureModules as a first command in the descendants).

Additionally, we're introducing AgentScope under annotation AgentScoped (concrete scope implementation can be changed by in descendants via overriding createAgentScope()) and convenient providers for IAgentId and IAgentParameters exposed via getAgentIdProvider() and getAgentParamsProvider().

IMPORTANT the GuiceAgentModule introduces public method prepareNewAgent(IAgentParameters) that is meant to configure run-time dependencies inside the module before another agent is instantiated (i.e., for passing run-time parameters such as IAgentParameters. The method contains only one parameter - PARAMS, therefore it forces you to create new descendants of IAgentParameters if you want to introduce new run-time parameters (which follows the philosophy that every AbstractAgent implementation should also defines: 1) own parameters (IAgentParameters descendants), 2) own module (GuiceAgentModule descendants), 3) own runners (AgentRunner descendants).

NOTE that this method MUST BE CALLED before the factory creates another agent (but rest assured, it's already done in GuiceAgentFactory for you automatically}).

FINALLY the module is providing basic bindings that are always needed for AbstractAgent

Mapped class Target Description
IComponentBus -> ComponentBus Agent bus synchronizing starting/stopping/etc. events.
IAgentId -> provided by the agentIdProvider. Id that is provided during runtime, you may use AgentId implementation of IAgentId.
IAgentParameters -> provided by the agentParamsProvider.
IAgentLogger -> AgentLogger Takes care about logging.

To have successful module the descendant must specify these missing bindings:

Mapped class Description
IAgent Agent that should be instantiated (preferable descendant of AbstractAgent.
... plus all newly introduced dependencies (by various implementors of mentioned interfaces).

... don't forget to call super.configureModules() in the subclasses. ;-)


Constructor Summary
GuiceAgentModule()
          Initializes agentScope via createAgentScope().
 
Method Summary
protected  void addModule(com.google.inject.AbstractModule module)
          Adds next modules containing new bindings that extend (and/or override) previous bindings.
protected  void configure()
          Binds agentScope into the module and then it iterates over modules and adds all their bindings to the module - each module always overrides previous ones (uses Modules.override(Module...)).
protected  void configureModules()
          Meant to introduce new AbstractModule into the module's queue modules via addModule(AbstractModule).
protected  IAgentScope createAgentScope()
          Method called from the GuiceAgentModule() to initialize the agentScope, override if you need you own AgentScope implementation.
protected  AdaptableProvider<IAgentId> getAgentIdProvider()
          Returns a provider for the IAgentId interface.
protected  AdaptableProvider<PARAMS> getAgentParamsProvider()
          Returns a provider for the IAgentParameters interface.
protected  IAgentScope getAgentScope()
          AgentScope that is holding agent-scope-singletons (classes annotated with AgentScoped).
 void prepareNewAgent(PARAMS agentParameters)
          Must be called before another agent instance can be created.
 
Methods inherited from class com.google.inject.AbstractModule
addError, addError, addError, bind, bind, bind, bindConstant, binder, bindInterceptor, bindListener, bindScope, configure, convertToTypes, currentStage, getMembersInjector, getMembersInjector, getProvider, getProvider, install, requestInjection, requestStaticInjection, requireBinding, requireBinding
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

GuiceAgentModule

public GuiceAgentModule()
Initializes agentScope via createAgentScope().

Method Detail

prepareNewAgent

public void prepareNewAgent(PARAMS agentParameters)
Must be called before another agent instance can be created. It clears the agentScope and binds IAgentParameters.getAgentId() to the agentIdProvider.

Whenever you create your own IAgentParameters you may need to override this method to utilize your new run-time dependencies. In such case, always call super.prepareNewAgent(agentParameters) as a first command.

Parameters:
agentParameters -

addModule

protected final void addModule(com.google.inject.AbstractModule module)
Adds next modules containing new bindings that extend (and/or override) previous bindings.

Designed to be used from configureModules().

Parameters:
module -

configureModules

protected void configureModules()
Meant to introduce new AbstractModule into the module's queue modules via addModule(AbstractModule).

See configureModules() source code for the example (utilizes anonymous class instantiation, instantiating AbstractModule where you only have to override AbstractModule.configure() method where you use AbstractModule.bind(Class) method to specify the bindings).


createAgentScope

protected IAgentScope createAgentScope()
Method called from the GuiceAgentModule() to initialize the agentScope, override if you need you own AgentScope implementation.

Returns:

getAgentScope

protected IAgentScope getAgentScope()
AgentScope that is holding agent-scope-singletons (classes annotated with AgentScoped).

Use AgentScope.clearScope() to release the objects thus preparing the scope for the next initialization of the IAgent (automatically called from prepareNewAgent(IAgentParameters).

Returns:

getAgentIdProvider

protected AdaptableProvider<IAgentId> getAgentIdProvider()
Returns a provider for the IAgentId interface. Use when utilizing descendants of IAgentId to provide the same instance for new interface/implementors.

Returns:

getAgentParamsProvider

protected AdaptableProvider<PARAMS> getAgentParamsProvider()
Returns a provider for the IAgentParameters interface. Use when utilizing descendants of IAgentParameters to provide the same instace for new interface/implementors.

Returns:

configure

protected final void configure()
Binds agentScope into the module and then it iterates over modules and adds all their bindings to the module - each module always overrides previous ones (uses Modules.override(Module...)).

The advantage over classical AbstractModule.configure() method is that you may easily re-bind already bound classes (which is unachievable by simple subclassing).

Specified by:
configure in class com.google.inject.AbstractModule