View Javadoc

1   package cz.cuni.amis.pogamut.base.factory.guice;
2   
3   import com.google.inject.AbstractModule;
4   import com.google.inject.Module;
5   
6   import cz.cuni.amis.pogamut.base.agent.IAgent;
7   import cz.cuni.amis.pogamut.base.agent.params.IAgentParameters;
8   import cz.cuni.amis.pogamut.base.communication.command.ICommandSerializer;
9   import cz.cuni.amis.pogamut.base.communication.command.impl.StringCommandSerializer;
10  import cz.cuni.amis.pogamut.base.communication.connection.IWorldConnection;
11  import cz.cuni.amis.pogamut.base.communication.connection.IWorldReaderProvider;
12  import cz.cuni.amis.pogamut.base.communication.connection.IWorldWriterProvider;
13  import cz.cuni.amis.pogamut.base.communication.mediator.IMediator;
14  import cz.cuni.amis.pogamut.base.communication.mediator.impl.Mediator;
15  import cz.cuni.amis.pogamut.base.communication.messages.InfoMessage;
16  import cz.cuni.amis.pogamut.base.communication.parser.IWorldMessageParser;
17  import cz.cuni.amis.pogamut.base.communication.parser.impl.yylex.IYylex;
18  import cz.cuni.amis.pogamut.base.communication.parser.impl.yylex.IYylexObserver;
19  import cz.cuni.amis.pogamut.base.communication.translator.IWorldMessageTranslator;
20  import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEvent;
21  import cz.cuni.amis.pogamut.base.communication.translator.event.IWorldChangeEventOutput;
22  import cz.cuni.amis.pogamut.base.communication.translator.impl.WorldMessageTranslator;
23  import cz.cuni.amis.pogamut.base.communication.worldview.IWorldChangeEventInput;
24  import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
25  import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEvent;
26  
27  /**
28   * Base GaviaLib Guice module that covers the simple bindings for Pogamut's communication chain.
29   * <p><p>
30   * <table>
31   * <tr><th>Mapped class</th>                    <th>  </th> <th>Target</th>                          <th>Description</th></tr>
32   * 
33   * <tr><td>{@link IWorldReaderProvider}</td>    <td>-></td> <td.{@link IWorldConnection}</td>        <td>Reader of the world's information.</td></tr>
34   * <tr><td>{@link IWorldWriterProvider}</td>    <td>-></td> <td.{@link IWorldConnection}</td>        <td>Writer that sends commands to the agent's body in the world.</td></tr>
35   * <tr><td>{@link ICommandSerializer}</td>      <td>-></td> <td>{@link StringCommandSerializer}</td> <td>Serializes commands using .toString() method.</td></tr>
36   * <tr><td>{@link IWorldChangeEventOutput}</td> <td>-></td> <td>{@link WorldMessageTranslator}</td>  <td>Translator of {@link InfoMessage}s into {@link IWorldChangeEvent}s. Relies on the wrapped (world-dependent) implementation of {@link IWorldMessageTranslator}</td></tr>
37   * <tr><td>{@link IMediator}</td>               <td>-></td> <td>{@link Mediator}</td>                <td>Thread-wrapper, reader of {@link IWorldChangeEventOutput} that passes {@link IWorldChangeEvent} into {@link IWorldChangeEventInput}.</td></tr>
38   * <tr><td>{@link IWorldChangeEventInput}</td>  <td>-></td> <td>{@link IWorldView}</td>              <td>Consumer of {@link IWorldChangeEvent}s.</td></tr> 
39   * </table>
40   * <p><p>
41   * To have <b>successful module</b> the descendant <b>must specify</b> these <b>missing bindings</b>:
42   * <table>
43   * <tr><th>Mapped class</th>                    <th>Description</th></tr>
44   * 
45   * <tr><td>{@link IAgent}</td>                  <td>Agent that should be instantiated</td></tr>
46   * <tr><td>{@link IWorldConnection}</td>        <td>Connection to the agent's world.</td></tr>
47   * <tr><td>{@link IWorldMessageParser}</td>     <td>Line oriented parser based on Yylex.</td></tr>
48   * <tr><td>{@link IYylex}</td>                  <td>World message parser implementation.</td></tr>
49   * <tr><td>{@link IYylexObserver}</td>          <td>Yylex observer reporting errors.</td></tr>
50   * <tr><td>{@link IWorldMessageTranslator}</td> <td>World-dependent implementation of {@link InfoMessage}s translator into {@link IWorldChangeEvent} that can be consumed by {@link IWorldView}.</td></tr>
51   * <tr><td>{@link IWorldView</td>               <td>World view processing {@link IWorldChangeEvent}s into {@link IWorldEvent}s that should be consumed by {@link IAgent} implementation.</td></tr>
52   * </table>
53   * ... plus all newly introduced dependencies (by various implementors of mentioned interfaces).<p>
54   * ... <b>don't forget to call super.configureModules()</b> in the subclasses. ;-)
55   * <p><p>
56   * If you want to bind custom (your own) class to one of the interface that is already binded (meaning you need to alter GaviaLib), do it this way:
57   * <ol>
58   * <li>BE TOTALY SURE WHAT YOU'RE DOING :-) or it will fail horribly or you may cripple the IDE...</li>
59   * <li>Copy-paste (YES, COPY-PASTE IS THE BEST WAY) the implementation of the class you want to change and alter it to suits your needs.</li>
60   * <li>Always make those classes <b>AgentScoped</b>!</li>
61   * <li>Create new module where you re-specify the binding of desired interface.</li> 
62   * </ol> 
63   * 
64   * @author Jimmy
65   * @param PARAMS
66   */
67  public class GuiceCommunicationModule<PARAMS extends IAgentParameters> extends GuiceAgentModule<PARAMS> {
68  
69  	/**
70  	 * Override to create new module with your own bindings adding it into {@link GuiceCommunicationModule#modules} using {@link GuiceCommunicationModule#addModule(Module)}.
71  	 * <p><p>
72  	 * See {@link GuiceCommunicationModule#configureModules()} source code for the example (utilizes anonymous class, instantiating {@link AbstractModule}).
73  	 */
74  	protected void configureModules() {
75  		super.configureModules();
76  		addModule(
77  			new AbstractModule() {
78  				@Override
79  				protected void configure() {
80  					bind(IWorldChangeEventOutput.class).to(WorldMessageTranslator.class);
81  					bind(IMediator.class).to(Mediator.class);
82  					bind(IWorldChangeEventInput.class).to(IWorldView.class);
83  				}				
84  			}
85  		);
86  	}
87  
88  }