View Javadoc

1   /*
2    * Created on 18-ago-2005
3    *
4    * TODO To change the template for this generated file go to
5    * Window - Preferences - Java - Code Style - Code Templates
6    */
7   package org.state4j.sm;
8   
9   import org.apache.commons.logging.Log;
10  import org.apache.commons.logging.LogFactory;
11  import org.state4j.exceptions.LogicErrorException;
12  import org.state4j.exceptions.PreconditionViolatedException;
13  
14  
15  /***
16   * @author andrea
17   * 
18   */
19  public class SmEngineImpl<T extends SmTarget> implements SmEngine<T> {
20  	private SmState stateMachine;
21  
22  	private SmContext<T> context;
23  
24  	private static Log logger = LogFactory.getLog(SmEngineImpl.class.getName());
25  
26  	public void setTarget(T target) {
27  		this.getContext().setTarget(target);
28  	}
29  
30  	public synchronized void start() {
31  		getLogger().debug("start engine for state machine: " + this.getStateMachine().getName());
32  		if (this.getStateMachine() instanceof SmCompositeState) {
33  			this.getContext().setCurrentState(
34  					((SmCompositeState) this.getStateMachine())
35  							.getInitialState());
36  		} else {
37  			this.getContext().setCurrentState(this.getStateMachine());
38  		}
39  		this.fireEvent(new SmEventImpl((SmEventOriginator)this.getTarget()) {
40  
41  			public String getName() {
42  				return "an event for initiale engine";
43  			}
44  
45  			public void setName(String name) {
46  			}
47  
48  			public boolean hasName() {
49  				return true;
50  			}});
51  	}
52  
53  	public SmState getStateMachine() {
54  		if (!this.hasStateMachine()) {
55  			throw new PreconditionViolatedException(
56  					"Sorry!! cannot getStateMachine");
57  		}
58  		return this.stateMachine;
59  	}
60  
61  	public void setStateMachine(SmState sm) {
62  		this.stateMachine = sm;
63  	}
64  
65  	public boolean hasStateMachine() {
66  		return this.stateMachine != null;
67  	}
68  
69  	public SmContext<T> getContext() {
70  		if (!this.hasContext()) {
71  			throw new PreconditionViolatedException("Sorry!! cannot getContext");
72  		}
73  		return this.context;
74  	}
75  
76  	public void setContext(SmContext<T> cntx) {
77  		this.context = cntx;
78  	}
79  
80  	public boolean hasContext() {
81  		return this.context != null;
82  	}
83  
84  	public String getCurrentState() {
85  		try {
86  			return this.getContext().getCurrentState().getName();
87  		} catch (Exception exc) {
88  			return "UnknownState";
89  		}
90  	}
91  
92  	public synchronized void fireEvent(SmEvent event) {
93  		try {
94  			if(event != null) {
95  				getLogger().debug("fire event " + event.getClass().getName() + " from state " + this.getCurrentState());
96  			} else {
97  				getLogger().debug("fire event null from state " + this.getCurrentState());
98  			}
99  			SmContext<T> cntx = (SmContext<T>) getContext().clone();
100 			cntx.setCurrentEvent(event);
101 			this.getStateMachine().fire(cntx);
102 			setContext(cntx);
103 		} catch (CloneNotSupportedException e) {
104 			getLogger().error("Error", e);
105 			throw new LogicErrorException(e);
106 		}
107 	}
108 
109 	public Log getLogger() {
110 		return logger;
111 	}
112 
113 	public T getTarget() {
114 		return this.getContext().getTarget();
115 	}
116 
117 	public boolean hasTarget() {
118 		return this.getContext().hasTarget();
119 	}
120 
121 }