Source code: domain/Proc.java
1 /*
2 * Danet GmbH
3 * Beratung und Software-Entwicklung
4 * Geschäftstelle AN
5 *
6 * $Id: Proc.java,v 1.43 2003/04/26 16:12:36 lipp Exp $
7 *
8 * $Log: Proc.java,v $
9 * Revision 1.43 2003/04/26 16:12:36 lipp
10 * Moved some classes to reduce package dependencies.
11 *
12 * Revision 1.42 2003/03/31 16:50:28 huaiyang
13 * Logging using common-logging.
14 *
15 * Revision 1.41 2002/12/09 10:53:00 lipp
16 * Updated to abort() modifications.
17 *
18 * Revision 1.40 2002/11/26 11:23:29 lipp
19 * Modified RemoteException comment.
20 *
21 * Revision 1.39 2002/11/19 15:14:52 lipp
22 * New transition manager.
23 *
24 * Revision 1.38 2002/11/11 12:20:44 lipp
25 * Some fixes.
26 *
27 * Revision 1.37 2002/11/04 08:40:25 barzik
28 * adapted to several modifications in the workflow component
29 *
30 * Revision 1.36 2002/10/21 11:54:23 lipp
31 * Better suspend state handling.
32 *
33 * Revision 1.35 2002/10/18 13:46:02 lipp
34 * Getting on with adaptions...
35 *
36 * Revision 1.34 2002/10/09 15:17:51 lipp
37 * Improved start mode handling.
38 *
39 * Revision 1.33 2002/10/09 14:27:33 lipp
40 * Intermediate, compilable state.
41 *
42 * Revision 1.32 2002/09/11 14:17:22 lipp
43 * Execptions using msgs now.
44 *
45 * Revision 1.31 2002/08/30 13:37:05 lipp
46 * Using Workflow engine facade now.
47 *
48 * Revision 1.30 2002/08/30 09:06:40 lipp
49 * Renamed internal state to typed state and use polymorphism for type
50 * names where possible.
51 *
52 * Revision 1.29 2002/08/28 12:58:03 lipp
53 * Fixed unittests.
54 *
55 * Revision 1.28 2002/08/28 12:47:20 lipp
56 * Starting new process generation.
57 *
58 * Revision 1.27 2002/08/22 15:19:34 lipp
59 * Redesign of EJB persistence.
60 *
61 * Revision 1.26 2002/08/21 22:06:48 lipp
62 * Finished transition to ProcessMgrStub.
63 *
64 * Revision 1.25 2002/08/02 09:28:53 huaiyang
65 * Use JDOM.
66 *
67 * Revision 1.24 2002/06/27 10:47:35 lipp
68 * Adapted to change in return type.
69 *
70 * Revision 1.23 2002/05/27 14:55:29 lipp
71 * Adapted to API changes.
72 *
73 * Revision 1.22 2002/02/04 22:43:12 lipp
74 * Adapted tests to changed.
75 *
76 * Revision 1.21 2002/02/04 15:18:55 lipp
77 * Made ActivityFinderAndKey visible in EJB Remote interface.
78 *
79 * Revision 1.20 2002/02/03 21:41:41 lipp
80 * Cleaned up unittests.
81 *
82 * Revision 1.19 2002/01/23 15:42:04 lipp
83 * Adapted to interface changes.
84 *
85 * Revision 1.18 2001/12/18 22:16:53 lipp
86 * Restructured DOM generation, implemented "assignments" method from ras.
87 *
88 * Revision 1.17 2001/12/15 12:47:07 lipp
89 * Getting an ActivityFinder implemented.
90 *
91 * Revision 1.16 2001/12/13 22:11:48 lipp
92 * Simplified temporary implementation of a requester.
93 *
94 * Revision 1.15 2001/12/13 21:00:05 lipp
95 * Simplified temporary implementation of a requester.
96 *
97 * Revision 1.14 2001/12/11 09:54:45 lipp
98 * Introduced security for workflow.
99 *
100 * Revision 1.13 2001/11/07 11:39:00 montag
101 * changed to internal ejb references
102 *
103 * Revision 1.12 2001/10/25 17:15:51 lipp
104 * Renamed getTransitionsRefs() to getNextActivities() (more appropriate
105 * name) and added TransitionRefs to DOM representatiosn.
106 *
107 * Revision 1.11 2001/10/25 14:36:43 montag
108 * Obsolete test case removed.
109 *
110 * Revision 1.10 2001/10/23 14:07:15 lipp
111 * Adapted to interface changes.
112 *
113 * Revision 1.9 2001/10/09 07:43:51 montag
114 * BaseElement reactivated
115 *
116 * Revision 1.8 2001/10/08 10:58:24 lipp
117 * Adapted to interface/implementation separation in domain.
118 *
119 * Revision 1.7 2001/10/04 08:01:54 montag
120 * unittests adopt for new transitionmanager
121 *
122 * Revision 1.6 2001/09/25 12:12:03 montag
123 * unittests corrected
124 *
125 * Revision 1.5 2001/09/24 13:43:11 montag
126 * WfProcessPK, WfActivityPK and ContributorPK removed.
127 *
128 * Revision 1.4 2001/09/24 12:30:52 montag
129 * ProcessAttributes removed.
130 *
131 * Revision 1.3 2001/09/11 12:30:05 montag
132 * clean up refresh/dispose due to new db scheme
133 *
134 * Revision 1.2 2001/09/10 06:37:19 montag
135 * notify process not in setInternalState()
136 *
137 * Revision 1.1 2001/08/29 10:59:11 lipp
138 * Tests split in groups.
139 *
140 */
141 package domain;
142
143 import java.util.Collection;
144 import java.util.Iterator;
145 import java.util.Vector;
146
147 import java.rmi.RemoteException;
148
149 import de.danet.an.workflow.omgcore.AlreadySuspendedException;
150 import de.danet.an.workflow.omgcore.InvalidStateException;
151 import de.danet.an.workflow.omgcore.TransitionNotAllowedException;
152 import de.danet.an.workflow.omgcore.WfActivity;
153
154 import de.danet.an.workflow.api.Activity;
155 import de.danet.an.workflow.api.Activity.StartFinishMode;
156 import de.danet.an.workflow.api.Process;
157
158 import junit.framework.*;
159
160 /**
161 * Zusammenstellung aller domain Tests für (Abstract)Process.
162 * @author <a href="mailto:lipp@danet.de"></a>
163 * @version 1.0
164 */
165 public class Proc extends TestCase {
166
167 private static final org.apache.commons.logging.Log logger
168 = org.apache.commons.logging.LogFactory.getLog(Proc.class);
169
170 /**
171 * Konstruktor zum Erzeugen eines TestCase
172 * @param name a <code>String</code> value
173 */
174 public Proc(String name) {
175 super (name);
176 }
177
178 /**
179 * Stellt diese TestSuite zusammen.
180 * @return a <code>Test</code> value
181 */
182 public static Test suite() {
183 TestSuite suite = new TestSuite();
184 suite.addTest(new Proc("processTest"));
185 suite.addTest(new Proc("processTest2"));
186 suite.addTest(new Proc("processTest3"));
187 suite.addTest(new Proc("processTest4"));
188 suite.addTest(new Proc("activityTest"));
189 suite.addTest(new Proc("abortProcess"));
190 return suite;
191 }
192
193 /**
194 * Test for Process
195 * @exception Exception if an error occurs
196 */
197 public void processTest() throws Exception {
198 TestProcess p = getProcess();
199 assertTrue (p != null);
200 }
201
202 /**
203 * Test for Activity
204 * @exception Exception if an error occurs
205 */
206 public void activityTest() throws Exception {
207 Activity a = getActivity(null);
208 assertTrue (a != null);
209 }
210
211 /**
212 * Test for Process with activity
213 * @exception Exception if an error occurs
214 */
215 public void processTest2() throws Exception {
216 TestProcess p = getProcess();
217 assertTrue (p != null);
218 TestActivity a = getActivity(p);
219 assertTrue (a != null);
220 Collection c = new Vector();
221 c.add(a);
222 p.setActivities(c);
223
224 Collection d = p.steps();
225 Iterator it = d.iterator();
226 while (it.hasNext()) {
227 WfActivity wfa = (WfActivity)it.next();
228 assertTrue(wfa != null);
229 }
230 boolean allClosed = p.allActivitiesClosed();
231 assertTrue (allClosed == false);
232 p.start();
233 allClosed = p.allActivitiesClosed();
234 assertTrue (allClosed == true);
235
236 }
237
238
239 /**
240 * Test for Process with activities
241 * @exception Exception if an error occurs
242 */
243 public void processTest3() throws Exception {
244 TestProcess p = getProcess();
245 assertTrue (p != null);
246 TestActivity a1 = getActivity(p);
247 assertTrue (a1 != null);
248 TestActivity a2 = getActivity(p);
249 assertTrue (a2 != null);
250 p.addActivity(a1);
251 p.addActivity(a2);
252 p.addTransition ("t1", "t1", 0, a1, a2);
253
254 Collection d = p.steps();
255 Iterator it = d.iterator();
256 while (it.hasNext()) {
257 de.danet.an.workflow.omgcore.WfActivity
258 wfa = (de.danet.an.workflow.omgcore.WfActivity)
259 it.next();
260 assertTrue(wfa != null);
261 }
262 assertTrue (p.activitiesInState("open").size() == 2);
263 assertTrue (p.activitiesInState ("open.not_running").size() == 2);
264 assertTrue (p.activitiesInState
265 ("open.not_running.not_started").size() == 2);
266 assertTrue (p.activitiesInState("closed").size() == 0);
267 boolean allClosed = p.allActivitiesClosed();
268 assertTrue (allClosed == false);
269 p.start ();
270 allClosed = p.allActivitiesClosed();
271 assertTrue (allClosed == true);
272 assertTrue (p.activitiesInState("open").size() == 0);
273 assertTrue (p.activitiesInState("closed").size() == 2);
274 }
275
276 /**
277 * Test for Process with activities and transitions
278 * @exception Exception if an error occurs
279 */
280 public void processTest4() throws Exception {
281 TestProcess p = getProcess();
282 assertTrue (p != null);
283 TestActivity a1 = getActivity(p);
284 assertTrue (a1 != null);
285 TestActivity a2 = getActivity(p);
286 assertTrue (a2 != null);
287 Collection ca = new Vector();
288 ca.add(a1);
289 ca.add(a2);
290 p.setActivities(ca);
291 }
292
293 /**
294 * Test for aborting a Process and his activities
295 * @exception Exception if an error occurs
296 */
297 public void abortProcess() throws Exception {
298 TestProcess p = getProcess();
299 assertTrue (p != null);
300 TestActivity a1 = getActivity(p);
301 assertTrue (a1 != null);
302 a1.setStartMode (StartFinishMode.MANUAL);
303 TestActivity a2 = getActivity(p);
304 assertTrue (a2 != null);
305 a2.setStartMode (StartFinishMode.MANUAL);
306 Collection c = new Vector();
307 p.addActivity(a1);
308 p.addActivity(a2);
309 p.addTransition ("t1", "t1", 0, a1, a2);
310 p.start ();
311 assertTrue(a1.state().startsWith("open.not_running.suspended"));
312 assertTrue(a2.state().startsWith("open.not_running.not_started"));
313 p.changeState("open.not_running.suspended");
314 assertTrue(p.state().startsWith("open.not_running.suspended"));
315 boolean gotIt = false;
316 try {
317 p.suspend();
318 } catch (AlreadySuspendedException e) {
319 gotIt = true;
320 }
321 assertTrue (gotIt);
322 p.resume ();
323 assertTrue(p.state().startsWith("open.running"));
324 p.suspend();
325 assertTrue(p.state().startsWith("open.not_running.suspended"));
326 assertTrue(a1 + " is " + a1.state() + " should be open.not_running.suspended",
327 a1.state().startsWith("open.not_running.suspended"));
328 assertTrue(a2 + " is " + a2.state() + " should be open.not_running.not_started",
329 a2.state().startsWith("open.not_running.not_started"));
330 p.abort ();
331 assertTrue(p + " is " + p.state() + ", should be closed.aborted",
332 p.state().equals("closed.aborted"));
333 assertTrue(a1 + " is " + a1.state() + ", should be closed.aborted",
334 a1.state().equals("closed.aborted"));
335 assertTrue(a2 + " is " + a2.state() + ", should be open.not_running.not_started",
336 a2.state().startsWith("open.not_running.not_started"));
337 }
338
339 //////////////////////////////////////////////////////////
340
341 private TestProcess getProcess() {
342 return new TestProcess();
343 }
344
345 /**
346 * Describe class <code>TestProcess</code> here.
347 *
348 */
349 public class TestProcess extends VolatileProcess {
350 /**
351 * Creates a new <code>TestProcess</code> instance.
352 *
353 */
354 public TestProcess () {
355 super ("p1");
356 }
357
358 /**
359 * Checks if all activities of the process are closed.
360 * @return <code>true</code>, if all activities of the process
361 * are closed; <code>false</code> else.
362 * @throws RemoteException if a system-level error occurs.
363 */
364 public boolean allActivitiesClosed() throws RemoteException {
365 for (Iterator it = steps().iterator(); it.hasNext();) {
366 Activity act = (Activity)it.next();
367 if (! act.typedState().isSameOrSubState(State.CLOSED)) {
368 return false;
369 }
370 }
371 return true;
372 }
373 }
374
375 private TestActivity getActivity(Process p) {
376 return new TestActivity(p);
377 }
378
379 private static int actkeyGen = 1;
380
381 /**
382 * Describe class <code>TestActivity</code> here.
383 *
384 */
385 public class TestActivity extends VolatileActivity {
386
387 /**
388 * Creates a new <code>TestActivity</code> instance.
389 *
390 * @param p a <code>Process</code> value
391 */
392 public TestActivity(Process p) {
393 super (p, "a" + Integer.toString(actkeyGen++));
394 }
395
396 /**
397 * Describe <code>pubSetState</code> method here.
398 *
399 * @param s a <code>State</code> value
400 * @exception InvalidStateException if an error occurs
401 */
402 public void pubSetState (State s)
403 throws InvalidStateException, TransitionNotAllowedException {
404 try {
405 changeState (s);
406 } catch (RemoteException e) {
407 // would be a real suprise on the domain layer
408 assertTrue (false);
409 }
410 }
411
412 }
413 }
414