1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml2.invoke;
18
19 import java.io.IOException;
20 import java.io.Serializable;
21 import java.net.URL;
22 import java.util.Map;
23
24 import javax.xml.stream.XMLStreamException;
25
26 import org.apache.commons.scxml2.Context;
27 import org.apache.commons.scxml2.SCXMLExecutor;
28 import org.apache.commons.scxml2.SCXMLIOProcessor;
29 import org.apache.commons.scxml2.TriggerEvent;
30 import org.apache.commons.scxml2.env.SimpleSCXMLListener;
31 import org.apache.commons.scxml2.io.SCXMLReader;
32 import org.apache.commons.scxml2.model.ModelException;
33 import org.apache.commons.scxml2.model.SCXML;
34
35
36
37
38
39 public class SimpleSCXMLInvoker implements Invoker, Serializable {
40
41
42 private static final long serialVersionUID = 1L;
43
44 private String parentStateId;
45
46 private SCXMLExecutor parentSCXMLExecutor;
47
48 private SCXMLExecutor executor;
49
50 private boolean cancelled;
51
52
53
54
55
56 @Override
57 public String getInvokeId() {
58 return parentStateId;
59 }
60
61
62
63
64 @Override
65 public void setInvokeId(final String invokeId) {
66 this.parentStateId = invokeId;
67 this.cancelled = false;
68 }
69
70
71
72
73 @Override
74 public void setParentSCXMLExecutor(SCXMLExecutor parentSCXMLExecutor) {
75 this.parentSCXMLExecutor = parentSCXMLExecutor;
76 }
77
78
79
80
81 @Override
82 public SCXMLIOProcessor getChildIOProcessor() {
83
84 return executor;
85 }
86
87
88
89
90 @Override
91 public void invoke(final String source, final Map<String, Object> params)
92 throws InvokerException {
93 SCXML scxml;
94 try {
95 scxml = SCXMLReader.read(new URL(source));
96 } catch (ModelException me) {
97 throw new InvokerException(me.getMessage(), me.getCause());
98 } catch (IOException ioe) {
99 throw new InvokerException(ioe.getMessage(), ioe.getCause());
100 } catch (XMLStreamException xse) {
101 throw new InvokerException(xse.getMessage(), xse.getCause());
102 }
103 executor = new SCXMLExecutor(parentSCXMLExecutor);
104 try {
105 executor.setStateMachine(scxml);
106 }
107 catch (ModelException me) {
108 throw new InvokerException(me);
109 }
110 Context rootCtx = executor.getRootContext();
111 for (Map.Entry<String, Object> entry : params.entrySet()) {
112 rootCtx.setLocal(entry.getKey(), entry.getValue());
113 }
114 executor.addListener(scxml, new SimpleSCXMLListener());
115 try {
116 executor.go();
117 } catch (ModelException me) {
118 throw new InvokerException(me.getMessage(), me.getCause());
119 }
120 if (executor.getStatus().isFinal()) {
121 TriggerEvent te = new TriggerEvent("done.invoke."+parentStateId, TriggerEvent.SIGNAL_EVENT);
122 new AsyncTrigger(parentSCXMLExecutor, te).start();
123 }
124 }
125
126
127
128
129 @Override
130 public void parentEvent(final TriggerEvent evt)
131 throws InvokerException {
132 if (cancelled) {
133 return;
134 }
135 boolean doneBefore = executor.getStatus().isFinal();
136 executor.addEvent(evt);
137 if (!doneBefore && executor.getStatus().isFinal()) {
138 TriggerEvent te = new TriggerEvent("done.invoke."+parentStateId,TriggerEvent.SIGNAL_EVENT);
139 new AsyncTrigger(parentSCXMLExecutor, te).start();
140 }
141 }
142
143
144
145
146 @Override
147 public void cancel()
148 throws InvokerException {
149 cancelled = true;
150 executor.addEvent(new TriggerEvent("cancel.invoke."+parentStateId, TriggerEvent.CANCEL_EVENT));
151 }
152 }
153