View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.communication.translator.observer.support;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import cz.cuni.amis.fsm.IFSMState;
7   import cz.cuni.amis.pogamut.base.communication.messages.InfoMessage;
8   import cz.cuni.amis.pogamut.ut2004.communication.translator.TranslatorContext;
9   import cz.cuni.amis.pogamut.ut2004.communication.translator.TranslatorMessages;
10  import cz.cuni.amis.pogamut.ut2004.communication.translator.UnexpectedMessageException;
11  
12  /**
13   * Support class that takes care of batch of messages in the form of:<p>
14   * START_MSG MSG MSG .... MSG END_MSG
15   * <p><p>
16   * Performs class checks over the symbols that are used to enter / leave the state.
17   * <p><p>
18   * Stores all the MSGs inside a list.
19   * <p><p>
20   * To use this state you have to subclass this abstract class, use correct super() inside the constructor of your class
21   * and override stateLeaving() method (first by calling super.stateLeaving()) and use getList() to obtain the list
22   * of all messages that came between START and END message. 
23   * 
24   * @author Jimmy
25   *
26   * @param <MESSAGE>
27   * @param <CONTEXT>
28   */
29  public abstract class ObserverListState<MESSAGE, CONTEXT extends TranslatorContext> extends AbstractObserverFSMState<InfoMessage, CONTEXT> {
30  	
31  	private List<MESSAGE> messages = null;
32  	@SuppressWarnings("unchecked")
33  	private Class beginMessage;
34  	private Class<MESSAGE> message;
35  	@SuppressWarnings("unchecked")
36  	private Class endMessage;
37  	
38  	/**
39  	 * @param beginMessage message class that should be used to enter this state
40  	 * @param message class of messages we should store inside the list (must be the same as generic type MESSAGE!)
41  	 * @param endMessage message class that should be used to leave this state
42  	 */
43  	@SuppressWarnings("unchecked")
44  	public ObserverListState(Class beginMessage, Class<MESSAGE> message, Class endMessage) {
45  		this.beginMessage = beginMessage;
46  		this.message = message;
47  		this.endMessage = endMessage;
48  	}
49  	
50  	protected List<MESSAGE> getList() {
51  		return messages;
52  	}
53  	
54  	protected void newList() {
55  		messages = new ArrayList<MESSAGE>();
56  	}
57  
58  	@Override
59  	public void init(CONTEXT context) {
60  		messages = new ArrayList<MESSAGE>();
61  	}
62  
63  	@Override
64  	public void restart(CONTEXT context) {
65  		messages = new ArrayList<MESSAGE>();
66  	}
67  
68  	@Override
69  	public void stateEntering(CONTEXT context, IFSMState<InfoMessage, CONTEXT> fromState, InfoMessage symbol) {
70  		if (!symbol.getClass().equals(beginMessage)) throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, beginMessage), context.getLogger(), this);
71  	}
72  
73  	@Override
74  	public void stateLeaving(CONTEXT context,
75  			IFSMState<InfoMessage, CONTEXT> toState, InfoMessage symbol) {
76  		if (!symbol.getClass().equals(endMessage)) throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, endMessage), context.getLogger(), this);		
77  	}
78  
79  	@Override
80  	protected void innerStateSymbol(CONTEXT context, InfoMessage symbol) {
81  		if (!symbol.getClass().equals(message)) {
82  			if (!message.isAssignableFrom(symbol.getClass())) {
83  				throw new UnexpectedMessageException(TranslatorMessages.unexpectedMessage(this, symbol, message), context.getLogger(), this);
84  			}
85  		}
86  		messages.add(message.cast(symbol));
87  	}
88  
89  }