KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jbpm > graph > exe > SuperStateActionExecutionTest


1 package org.jbpm.graph.exe;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.List JavaDoc;
5
6 import junit.framework.TestCase;
7
8 import org.jbpm.graph.def.Action;
9 import org.jbpm.graph.def.ActionHandler;
10 import org.jbpm.graph.def.Event;
11 import org.jbpm.graph.def.GraphElement;
12 import org.jbpm.graph.def.Node;
13 import org.jbpm.graph.def.ProcessDefinition;
14
15 public class SuperStateActionExecutionTest extends TestCase {
16
17   ProcessDefinition processDefinition = null;
18   ProcessInstance processInstance = null;
19
20   static List JavaDoc executedActions = null;
21   
22   public static class ExecutedAction {
23     // ExectionContext members
24
Token token = null;
25     Event event = null;
26     GraphElement eventSource = null;
27     Action action = null;
28     Throwable JavaDoc exception = null;
29     // The node returned by the ExecutionContext at the time of execution
30
Node node = null;
31   }
32   
33   public static class Recorder implements ActionHandler {
34     private static final long serialVersionUID = 1L;
35
36     public void execute(ExecutionContext executionContext) throws Exception JavaDoc {
37       ExecutedAction executedAction = new ExecutedAction();
38       executedAction.token = executionContext.getToken();
39       executedAction.event = executionContext.getEvent();
40       executedAction.eventSource = executionContext.getEventSource();
41       executedAction.action = executionContext.getAction();
42       executedAction.exception = executionContext.getException();
43       executedAction.node = executionContext.getNode();
44       executedActions.add(executedAction);
45     }
46   }
47   
48   public void setUp() {
49     executedActions = new ArrayList JavaDoc();
50   }
51
52   public void testSuperStateEnter() {
53     processDefinition = ProcessDefinition.parseXmlString(
54       "<process-definition>" +
55       " <start-state name='start'>" +
56       " <transition to='superstate/insidesuperstate'/>" +
57       " </start-state>" +
58       " <super-state name='superstate'>" +
59       " <event type='superstate-enter'>" +
60       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
61       " </event>" +
62       " <state name='insidesuperstate' />" +
63       " </super-state>" +
64       "</process-definition>"
65     );
66     // create the process instance
67
processInstance = new ProcessInstance(processDefinition);
68     processInstance.signal();
69     assertEquals(1, executedActions.size());
70     ExecutedAction executedAction = (ExecutedAction) executedActions.get(0);
71     assertEquals("superstate-enter", executedAction.event.getEventType());
72     assertSame(processDefinition.getNode("superstate"), executedAction.event.getGraphElement());
73     assertSame(processDefinition.getNode("superstate"), executedAction.eventSource);
74     assertSame(processInstance.getRootToken(), executedAction.token);
75     assertNull(executedAction.node);
76   }
77
78   public void testNestedSuperStateEnter() {
79     processDefinition = ProcessDefinition.parseXmlString(
80       "<process-definition>" +
81       " <start-state name='start'>" +
82       " <transition to='superstate/nestedsuperstate/insidenestedsuperstate'/>" +
83       " </start-state>" +
84       " <super-state name='superstate'>" +
85       " <event type='superstate-enter'>" +
86       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
87       " </event>" +
88       " <super-state name='nestedsuperstate'>" +
89       " <event type='superstate-enter'>" +
90       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
91       " </event>" +
92       " <state name='insidenestedsuperstate' />" +
93       " </super-state>" +
94       " </super-state>" +
95       "</process-definition>"
96     );
97     // create the process instance
98
processInstance = new ProcessInstance(processDefinition);
99     processInstance.signal();
100     assertEquals(3, executedActions.size());
101
102     // the first action called is the superstate-enter on the 'superstate'
103
ExecutedAction executedAction = (ExecutedAction) executedActions.get(0);
104     assertEquals("superstate-enter", executedAction.event.getEventType());
105     assertSame(processDefinition.getNode("superstate"), executedAction.event.getGraphElement());
106     assertSame(processDefinition.getNode("superstate"), executedAction.eventSource);
107     assertSame(processInstance.getRootToken(), executedAction.token);
108     assertNull(executedAction.node);
109     
110     // the second action called is the superstate-enter on the 'nestedsuperstate'
111
executedAction = (ExecutedAction) executedActions.get(1);
112     assertEquals("superstate-enter", executedAction.event.getEventType());
113     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.event.getGraphElement());
114     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
115     assertSame(processInstance.getRootToken(), executedAction.token);
116     assertNull(executedAction.node);
117
118     // the third action called is the *propagated* event of the 'nestedsuperstate' to the 'superstate'
119
executedAction = (ExecutedAction) executedActions.get(2);
120     assertEquals("superstate-enter", executedAction.event.getEventType());
121     assertSame(processDefinition.findNode("superstate"), executedAction.event.getGraphElement());
122     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
123     assertSame(processInstance.getRootToken(), executedAction.token);
124     assertNull(executedAction.node);
125   }
126
127   public void testSuperStateEnterViaTransitionToSuperState() {
128     processDefinition = ProcessDefinition.parseXmlString(
129       "<process-definition>" +
130       " <start-state name='start'>" +
131       " <transition to='superstate'/>" +
132       " </start-state>" +
133       " <super-state name='superstate'>" +
134       " <event type='superstate-enter'>" +
135       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
136       " </event>" +
137       " <super-state name='nestedsuperstate'>" +
138       " <event type='superstate-enter'>" +
139       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
140       " </event>" +
141       " <state name='insidenestedsuperstate' />" +
142       " </super-state>" +
143       " </super-state>" +
144       "</process-definition>"
145     );
146     // create the process instance
147
processInstance = new ProcessInstance(processDefinition);
148     processInstance.signal();
149     assertEquals(3, executedActions.size());
150
151     // the first action called is the superstate-enter on the 'superstate'
152
ExecutedAction executedAction = (ExecutedAction) executedActions.get(0);
153     assertEquals("superstate-enter", executedAction.event.getEventType());
154     assertSame(processDefinition.getNode("superstate"), executedAction.event.getGraphElement());
155     assertSame(processDefinition.getNode("superstate"), executedAction.eventSource);
156     assertSame(processInstance.getRootToken(), executedAction.token);
157     assertNull(executedAction.node);
158     
159     // the second action called is the superstate-enter on the 'nestedsuperstate'
160
executedAction = (ExecutedAction) executedActions.get(1);
161     assertEquals("superstate-enter", executedAction.event.getEventType());
162     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.event.getGraphElement());
163     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
164     assertSame(processInstance.getRootToken(), executedAction.token);
165     assertNull(executedAction.node);
166
167     // the third action called is the *propagated* event of the 'nestedsuperstate' to the 'superstate'
168
executedAction = (ExecutedAction) executedActions.get(2);
169     assertEquals("superstate-enter", executedAction.event.getEventType());
170     assertSame(processDefinition.findNode("superstate"), executedAction.event.getGraphElement());
171     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
172     assertSame(processInstance.getRootToken(), executedAction.token);
173     assertNull(executedAction.node);
174   }
175
176   public void testSuperStateLeave() {
177     processDefinition = ProcessDefinition.parseXmlString(
178       "<process-definition>" +
179       " <start-state name='start'>" +
180       " <transition to='superstate/stateinside'/>" +
181       " </start-state>" +
182       " <super-state name='superstate'>" +
183       " <event type='superstate-leave'>" +
184       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
185       " </event>" +
186       " <state name='stateinside'>" +
187       " <transition to='../toplevelstate' />" +
188       " </state>" +
189       " </super-state>" +
190       " <state name='toplevelstate' />" +
191       "</process-definition>"
192     );
193     // create the process instance
194
processInstance = new ProcessInstance(processDefinition);
195     // put the execution in the nestedsuperstate
196
processInstance.signal();
197     assertEquals(0, executedActions.size());
198     
199     // the next signal results in a node-enter internally to the superstate so it should have no effect.
200
// by default, event propagation is turned on. that is why we decided to have a separated event type for superstate leave and enter.
201
processInstance.signal();
202     assertEquals(1, executedActions.size());
203     ExecutedAction executedAction = (ExecutedAction) executedActions.get(0);
204     assertEquals("superstate-leave", executedAction.event.getEventType());
205     assertSame(processDefinition.getNode("superstate"), executedAction.event.getGraphElement());
206     assertSame(processDefinition.getNode("superstate"), executedAction.eventSource);
207     assertSame(processInstance.getRootToken(), executedAction.token);
208     assertNull(executedAction.node);
209   }
210
211   public void testNestedSuperStateLeave() {
212     processDefinition = ProcessDefinition.parseXmlString(
213       "<process-definition>" +
214       " <start-state name='start'>" +
215       " <transition to='superstate/nestedsuperstate/stateinside'/>" +
216       " </start-state>" +
217       " <super-state name='superstate'>" +
218       " <event type='superstate-leave'>" +
219       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
220       " </event>" +
221       " <super-state name='nestedsuperstate'>" +
222       " <event type='superstate-leave'>" +
223       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
224       " </event>" +
225       " <state name='stateinside'>" +
226       " <transition to='../../toplevelstate' />" +
227       " </state>" +
228       " </super-state>" +
229       " </super-state>" +
230       " <state name='toplevelstate' />" +
231       "</process-definition>"
232     );
233     // create the process instance
234
processInstance = new ProcessInstance(processDefinition);
235     // put the execution in the nestedsuperstate
236
processInstance.signal();
237     assertEquals(0, executedActions.size());
238     
239     // the next signal results in a node-enter internally to the superstate so it should have no effect.
240
// by default, event propagation is turned on. that is why we decided to have a separated event type for superstate leave and enter.
241
processInstance.signal();
242     assertEquals(3, executedActions.size());
243     ExecutedAction executedAction = (ExecutedAction) executedActions.get(0);
244     assertEquals("superstate-leave", executedAction.event.getEventType());
245     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.event.getGraphElement());
246     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
247     assertSame(processInstance.getRootToken(), executedAction.token);
248     assertNull(executedAction.node);
249
250     executedAction = (ExecutedAction) executedActions.get(1);
251     assertEquals("superstate-leave", executedAction.event.getEventType());
252     assertSame(processDefinition.findNode("superstate"), executedAction.event.getGraphElement());
253     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
254     assertSame(processInstance.getRootToken(), executedAction.token);
255     assertNull(executedAction.node);
256
257     executedAction = (ExecutedAction) executedActions.get(2);
258     assertEquals("superstate-leave", executedAction.event.getEventType());
259     assertSame(processDefinition.findNode("superstate"), executedAction.event.getGraphElement());
260     assertSame(processDefinition.findNode("superstate"), executedAction.eventSource);
261     assertSame(processInstance.getRootToken(), executedAction.token);
262     assertNull(executedAction.node);
263   }
264
265   public void testNestedSuperStateLeaveViaSuperStateTransition() {
266     processDefinition = ProcessDefinition.parseXmlString(
267       "<process-definition>" +
268       " <start-state name='start'>" +
269       " <transition to='superstate/nestedsuperstate/stateinside'/>" +
270       " </start-state>" +
271       " <super-state name='superstate'>" +
272       " <event type='superstate-leave'>" +
273       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
274       " </event>" +
275       " <super-state name='nestedsuperstate'>" +
276       " <event type='superstate-leave'>" +
277       " <action class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
278       " </event>" +
279       " <state name='stateinside' />" +
280       " </super-state>" +
281       " <transition to='toplevelstate' />" +
282       " </super-state>" +
283       " <state name='toplevelstate' />" +
284       "</process-definition>"
285     );
286     // create the process instance
287
processInstance = new ProcessInstance(processDefinition);
288     // put the execution in the nestedsuperstate
289
processInstance.signal();
290     assertEquals(0, executedActions.size());
291     
292     // the next signal results in a node-enter internally to the superstate so it should have no effect.
293
// by default, event propagation is turned on. that is why we decided to have a separated event type for superstate leave and enter.
294
processInstance.signal();
295     assertEquals(3, executedActions.size());
296     ExecutedAction executedAction = (ExecutedAction) executedActions.get(0);
297     assertEquals("superstate-leave", executedAction.event.getEventType());
298     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.event.getGraphElement());
299     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
300     assertSame(processInstance.getRootToken(), executedAction.token);
301     assertNull(executedAction.node);
302
303     executedAction = (ExecutedAction) executedActions.get(1);
304     assertEquals("superstate-leave", executedAction.event.getEventType());
305     assertSame(processDefinition.findNode("superstate"), executedAction.event.getGraphElement());
306     assertSame(processDefinition.findNode("superstate/nestedsuperstate"), executedAction.eventSource);
307     assertSame(processInstance.getRootToken(), executedAction.token);
308     assertNull(executedAction.node);
309
310     executedAction = (ExecutedAction) executedActions.get(2);
311     assertEquals("superstate-leave", executedAction.event.getEventType());
312     assertSame(processDefinition.findNode("superstate"), executedAction.event.getGraphElement());
313     assertSame(processDefinition.findNode("superstate"), executedAction.eventSource);
314     assertSame(processInstance.getRootToken(), executedAction.token);
315     assertNull(executedAction.node);
316   }
317
318   public void testInterNestedSuperStateTransition() {
319     // +--------------------------------------+
320
// |one |
321
// | +---------------+ +---------------+ |
322
// | |one.one | |one.two | |
323
// | | +-----------+ | | +-----------+ | |
324
// | | |one.one.one| | | |one.two.one| | |
325
// +-----+ | | | +---+ | | | | +---+ | | |
326
// |start|-+-+-+>| a |-----+-+--+-+->| b | | | |
327
// +-----+ | | | +---+ | | | | +---+ | | |
328
// | | +-----------+ | | +-----------+ | |
329
// | +---------------+ +---------------+ |
330
// +--------------------------------------+
331
processDefinition = ProcessDefinition.parseXmlString(
332       "<process-definition>" +
333       " <start-state name='start'>" +
334       " <transition to='one/one.one/one.one.one/a'/>" +
335       " </start-state>" +
336       " <super-state name='one'>" +
337       " <event type='superstate-enter'><action ref-name='record' /></event>" +
338       " <event type='superstate-leave'><action ref-name='record' /></event>" +
339       " <super-state name='one.one'>" +
340       " <event type='superstate-leave'><action ref-name='record' /></event>" +
341       " <super-state name='one.one.one'>" +
342       " <event type='superstate-leave'><action ref-name='record' /></event>" +
343       " <state name='a'>" +
344       " <transition to='../../one.two/one.two.one/b' />" +
345       " </state>" +
346       " </super-state>" +
347       " </super-state>" +
348       " <super-state name='one.two'>" +
349       " <event type='superstate-enter'><action ref-name='record' /></event>" +
350       " <super-state name='one.two.one'>" +
351       " <event type='superstate-enter'><action ref-name='record' /></event>" +
352       " <state name='b' />" +
353       " </super-state>" +
354       " </super-state>" +
355       " </super-state>" +
356       " <action name='record' class='org.jbpm.graph.exe.SuperStateActionExecutionTest$Recorder' />" +
357       "</process-definition>"
358     );
359     // create the process instance
360
processInstance = new ProcessInstance(processDefinition);
361     // put the execution in the nestedsuperstate
362
processInstance.signal();
363     assertEquals(3, executedActions.size());
364     
365     // the next signal results in a node-enter internally to the superstate so it should have no effect.
366
// by default, event propagation is turned on. that is why we decided to have a separated event type for superstate leave and enter.
367
processInstance.signal();
368     assertEquals(13, executedActions.size());
369
370     ExecutedAction executedAction = (ExecutedAction) executedActions.get(3);
371     assertEquals("superstate-leave", executedAction.event.getEventType());
372     assertSame(processDefinition.findNode("one/one.one/one.one.one"), executedAction.event.getGraphElement());
373     assertSame(processDefinition.findNode("one/one.one/one.one.one"), executedAction.eventSource);
374
375     executedAction = (ExecutedAction) executedActions.get(4);
376     assertEquals("superstate-leave", executedAction.event.getEventType());
377     assertSame(processDefinition.findNode("one/one.one"), executedAction.event.getGraphElement());
378     assertSame(processDefinition.findNode("one/one.one/one.one.one"), executedAction.eventSource);
379
380     executedAction = (ExecutedAction) executedActions.get(5);
381     assertEquals("superstate-leave", executedAction.event.getEventType());
382     assertSame(processDefinition.findNode("one"), executedAction.event.getGraphElement());
383     assertSame(processDefinition.findNode("one/one.one/one.one.one"), executedAction.eventSource);
384
385     executedAction = (ExecutedAction) executedActions.get(6);
386     assertEquals("superstate-leave", executedAction.event.getEventType());
387     assertSame(processDefinition.findNode("one/one.one"), executedAction.event.getGraphElement());
388     assertSame(processDefinition.findNode("one/one.one"), executedAction.eventSource);
389
390     executedAction = (ExecutedAction) executedActions.get(7);
391     assertEquals("superstate-leave", executedAction.event.getEventType());
392     assertSame(processDefinition.findNode("one"), executedAction.event.getGraphElement());
393     assertSame(processDefinition.findNode("one/one.one"), executedAction.eventSource);
394
395     executedAction = (ExecutedAction) executedActions.get(8);
396     assertEquals("superstate-enter", executedAction.event.getEventType());
397     assertSame(processDefinition.findNode("one/one.two"), executedAction.event.getGraphElement());
398     assertSame(processDefinition.findNode("one/one.two"), executedAction.eventSource);
399
400     executedAction = (ExecutedAction) executedActions.get(9);
401     assertEquals("superstate-enter", executedAction.event.getEventType());
402     assertSame(processDefinition.findNode("one"), executedAction.event.getGraphElement());
403     assertSame(processDefinition.findNode("one/one.two"), executedAction.eventSource);
404
405     executedAction = (ExecutedAction) executedActions.get(10);
406     assertEquals("superstate-enter", executedAction.event.getEventType());
407     assertSame(processDefinition.findNode("one/one.two/one.two.one"), executedAction.event.getGraphElement());
408     assertSame(processDefinition.findNode("one/one.two/one.two.one"), executedAction.eventSource);
409
410     executedAction = (ExecutedAction) executedActions.get(11);
411     assertEquals("superstate-enter", executedAction.event.getEventType());
412     assertSame(processDefinition.findNode("one/one.two"), executedAction.event.getGraphElement());
413     assertSame(processDefinition.findNode("one/one.two/one.two.one"), executedAction.eventSource);
414
415     executedAction = (ExecutedAction) executedActions.get(12);
416     assertEquals("superstate-enter", executedAction.event.getEventType());
417     assertSame(processDefinition.findNode("one"), executedAction.event.getGraphElement());
418     assertSame(processDefinition.findNode("one/one.two/one.two.one"), executedAction.eventSource);
419   }
420 }
421
Popular Tags