1
2
3
4
5
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 }