|
/usr/java/lib/xflow1.2.1/src_original/src/xflow/server/controller/WorkflowP.java
|
1 /*
2 * ====================================================================
3 *
4 * XFLOW - Process Management System
5 * Copyright (C) 2003 Rob Tan
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions, and the disclaimer that follows
17 * these conditions in the documentation and/or other materials
18 * provided with the distribution.
19 *
20 * 3. The name "XFlow" must not be used to endorse or promote products
21 * derived from this software without prior written permission. For
22 * written permission, please contact rcktan@yahoo.com
23 *
24 * 4. Products derived from this software may not be called "XFlow", nor
25 * may "XFlow" appear in their name, without prior written permission
26 * from the XFlow Project Management (rcktan@yahoo.com)
27 *
28 * In addition, we request (but do not require) that you include in the
29 * end-user documentation provided with the redistribution and/or in the
30 * software itself an acknowledgement equivalent to the following:
31 * "This product includes software developed by the
32 * XFlow Project (http://xflow.sourceforge.net/)."
33 * Alternatively, the acknowledgment may be graphical using the logos
34 * available at http://xflow.sourceforge.net/
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE XFLOW AUTHORS OR THE PROJECT
40 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 *
49 * ====================================================================
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the XFlow Project and was originally
52 * created by Rob Tan (rcktan@yahoo.com)
53 * For more information on the XFlow Project, please see:
54 * <http://xflow.sourceforge.net/>.
55 * ====================================================================
56 */
57
58 package xflow.server.controller;
59
60 import java.io.*;
61 import java.util.*;
62 import java.lang.*;
63 import java.sql.*;
64 import org.apache.log4j.Logger;
65 import xflow.common.*;
66 import xflow.protocol.*;
67 import xflow.util.*;
68 import xflow.server.util.*;
69
70 import org.apache.log4j.Logger;
71
72 public class WorkflowP {
73
74 private static Logger log = Logger.getLogger(WorkflowP.class);
75
76 public static int saveDB (int graphId, String workflowName, String initiator, int parentWorkflowId)
77 throws XflowException {
78
79 int wfId = 0;
80 Connection con = null;
81 Statement s = null;
82
83 String pWfId = "null";
84 if (parentWorkflowId != -1) {
85 pWfId = "" + parentWorkflowId;
86 }
87
88 try {
89 con = Persistence.getConnection();
90 s = con.createStatement();
91
92 // Create and save workflow instance
93 String timeStarted = DateUtil.getTimestamp();
94 String sql = "insert into workflow values (null, " + graphId + ", '" +
95 initiator + "', true, '" + timeStarted + "', null, 'RUNNING' ," + pWfId + ")";
96 log.info (sql);
97 s.execute (sql);
98
99 sql = "select max(workflowId), workflowId from workflow";
100 ResultSet rs = s.executeQuery(sql);
101 if (rs.next()) {
102 wfId = rs.getInt("workflowId");
103 } else {
104 throw new XflowException ("Unable to obtain workflowId");
105 }
106 } catch (Exception e) {
107 e.printStackTrace();
108 throw new XflowException ("Failed to save workflow in database");
109 } finally {
110 if (s!=null) {
111 try {
112 s.close();
113 } catch (Exception e) {
114 e.printStackTrace();
115 }
116 }
117 if (con != null) {
118 try {
119 con.close();
120 } catch (Exception e) {
121 }
122 }
123 }
124 return wfId;
125 }
126
127 public static int getGraphId (int workflowId) throws XflowException {
128
129 int gid = -1;
130 Connection con = null;
131 Statement s = null;
132 try {
133 con = Persistence.getConnection();
134 s = con.createStatement();
135
136 String sql = "select gid from workflow where workflowId = " + workflowId;
137 log.info (sql);
138 ResultSet rs = s.executeQuery (sql);
139 if (rs.next()) {
140 gid = rs.getInt("gid");
141 }
142 } catch (Exception e) {
143 e.printStackTrace();
144 throw new XflowException ("Failed to get gid from workflow in database");
145 } finally {
146 if (s!=null) {
147 try {
148 s.close();
149 } catch (Exception e) {
150 e.printStackTrace();
151 }
152 }
153 if (con != null) {
154 try {
155 con.close();
156 } catch (Exception e) {
157 }
158 }
159 }
160 return gid;
161 }
162
163 public static HashMap getWorkflows (String filter) throws XflowException {
164
165 HashMap workflows = new HashMap();
166 Connection con = null;
167 Statement s = null;
168 try {
169 con = Persistence.getConnection();
170 s = con.createStatement();
171
172 String sql = "select workflowId from workflow " + filter;
173 log.info (sql);
174 ResultSet rs = s.executeQuery (sql);
175 while (rs.next()) {
176 int wfId = rs.getInt("workflowId");
177 WorkflowId workflowId = new WorkflowId(wfId);
178 Integer key = new Integer(workflowId.getValue());
179 workflows.put (key, workflowId);
180 }
181 } catch (Exception e) {
182 e.printStackTrace();
183 throw new XflowException ("Failed to get workflows from database");
184 } finally {
185 if (s!=null) {
186 try {
187 s.close();
188 } catch (Exception e) {
189 e.printStackTrace();
190 }
191 }
192 if (con != null) {
193 try {
194 con.close();
195 } catch (Exception e) {
196 }
197 }
198 }
199 return workflows;
200 }
201
202 public static HashMap getWorkflowsByName (String name) throws XflowException {
203
204 HashMap workflows = new HashMap();
205 Connection con = null;
206 Statement s = null;
207 try {
208 con = Persistence.getConnection();
209 s = con.createStatement();
210
211 String sql = "select w.workflowId from workflow w, graph g where w.gid = g.gid and g.name = '" + name + "'";
212 log.info (sql);
213 ResultSet rs = s.executeQuery (sql);
214 while (rs.next()) {
215 int wfId = rs.getInt("workflowId");
216 WorkflowId workflowId = new WorkflowId(wfId);
217 Integer key = new Integer(workflowId.getValue());
218 workflows.put (key, workflowId);
219 }
220 } catch (Exception e) {
221 e.printStackTrace();
222 throw new XflowException ("Failed to get workflows from database");
223 } finally {
224 if (s!=null) {
225 try {
226 s.close();
227 } catch (Exception e) {
228 e.printStackTrace();
229 }
230 }
231 if (con != null) {
232 try {
233 con.close();
234 } catch (Exception e) {
235 }
236 }
237 }
238 return workflows;
239 }
240
241 public static Vector getModels () throws XflowException {
242
243 Vector models = new Vector();
244 Connection con = null;
245 Statement s = null;
246 try {
247 con = Persistence.getConnection();
248 s = con.createStatement();
249
250 String sql = "select * from graph order by name";
251 log.info (sql);
252 ResultSet rs = s.executeQuery (sql);
253 while (rs.next()) {
254 String name = rs.getString ("name");
255 String desc = rs.getString ("description");
256 int version = rs.getInt ("version");
257 WorkflowModel m = new WorkflowModel ();
258 m.name = name;
259 m.version = version;
260 m.description = desc;
261 models.addElement (m);
262 }
263 } catch (Exception e) {
264 e.printStackTrace();
265 throw new XflowException ("Failed to get workflows from database");
266 } finally {
267 if (s!=null) {
268 try {
269 s.close();
270 } catch (Exception e) {
271 e.printStackTrace();
272 }
273 }
274 if (con != null) {
275 try {
276 con.close();
277 } catch (Exception e) {
278 }
279 }
280 }
281 return models;
282 }
283
284 public static void abortWorkflow (WorkflowId workflowId) throws XflowException {
285
286 int wfId = workflowId.getValue();
287 Connection con = null;
288 Statement s = null;
289 try {
290 con = Persistence.getConnection();
291 s = con.createStatement();
292
293 String timeEnded = DateUtil.getTimestamp();
294 String sql = "update workflow set isActive = false, timeEnded = '" + timeEnded +
295 "', status = 'ABORTED' where workflowid = " + wfId;
296 log.info (sql);
297 s.execute (sql);
298 } catch (Exception e) {
299 e.printStackTrace();
300 throw new XflowException ("Failed to abort workflow in database");
301 } finally {
302 if (s!=null) {
303 try {
304 s.close();
305 } catch (Exception e) {
306 e.printStackTrace();
307 }
308 }
309 if (con != null) {
310 try {
311 con.close();
312 } catch (Exception e) {
313 }
314 }
315 }
316 }
317
318 public static void suspendWorkflow (WorkflowId workflowId) throws XflowException {
319
320 int wfId = workflowId.getValue();
321 Connection con = null;
322 Statement s = null;
323 try {
324 con = Persistence.getConnection();
325 s = con.createStatement();
326 String sql = "update workflow set status = 'SUSPENDED' where workflowid = " + wfId;
327 log.info (sql);
328 s.execute (sql);
329 } catch (Exception e) {
330 e.printStackTrace();
331 throw new XflowException ("Failed to suspend workflow in database");
332 } finally {
333 if (s!=null) {
334 try {
335 s.close();
336 } catch (Exception e) {
337 e.printStackTrace();
338 }
339 }
340 if (con != null) {
341 try {
342 con.close();
343 } catch (Exception e) {
344 }
345 }
346 }
347 }
348
349 public static void resumeWorkflow (WorkflowId workflowId) throws XflowException {
350
351 int wfId = workflowId.getValue();
352 Connection con = null;
353 Statement s = null;
354 try {
355 con = Persistence.getConnection();
356 s = con.createStatement();
357 String sql = "update workflow set status = 'RUNNING' where workflowid = " + wfId;
358 log.info (sql);
359 s.execute (sql);
360 } catch (Exception e) {
361 e.printStackTrace();
362 throw new XflowException ("Failed to resume workflow in database");
363 } finally {
364 if (s!=null) {
365 try {
366 s.close();
367 } catch (Exception e) {
368 e.printStackTrace();
369 }
370 }
371 if (con != null) {
372 try {
373 con.close();
374 } catch (Exception e) {
375 }
376 }
377 }
378 }
379
380 public static WorkflowState getWorkflowState (WorkflowId workflowId) throws XflowException {
381
382 int wfId = workflowId.getValue();
383 WorkflowState state = null;
384 Connection con = null;
385 Statement s = null;
386 try {
387 con = Persistence.getConnection();
388 s = con.createStatement();
389
390 String sql = "select * from workflow w, graph g where w.workflowId = " + wfId +
391 " and w.gid = g.gid";
392 log.info (sql);
393 ResultSet rs = s.executeQuery (sql);
394 if (rs.next()) {
395 state = new WorkflowState();
396 String wfName = rs.getString("name");
397 int version = rs.getInt("version");
398 boolean active = rs.getBoolean ("isActive");
399 String initiator = rs.getString("initiator");
400 String startTime = rs.getString("timeStarted");
401 java.util.Date stime = DateUtil.parse (startTime);
402 state.timeStarted = stime;
403 if (!active) {
404 String endTime = rs.getString("timeEnded");
405 java.util.Date etime = DateUtil.parse (endTime);
406 state.timeEnded = etime;
407 }
408 state.workflowId = new WorkflowId(wfId);
409 state.workflowName = wfName;
410 state.version = version;
411 state.isActive = active;
412 state.initiator = initiator;
413 state.state = rs.getString("status");
414 if (state.state == null || state.state.equals("")) {
415 if (state.isActive) {
416 state.state = "RUNNING";
417 } else {
418 state.state = "COMPLETED";
419 }
420 }
421
422
423 // Load the active processes
424 String sql2 = "select * from inbox where workflowid = " + wfId;
425 log.info (sql2);
426 ResultSet rs2 = s.executeQuery (sql2);
427 while (rs2.next()) {
428 ProcessState ps = new ProcessState();
429 ps.workflowId = new WorkflowId(wfId);
430 ps.processName = rs2.getString("procName");
431 startTime = rs2.getString("timeStarted");
432 stime = DateUtil.parse (startTime);
433 ps.timeStarted = stime;
434 ps.workItemId = new WorkItemId(rs2.getInt("workitemId"));
435 state.activeProcesses.addElement (ps);
436 }
437
438 // Load the workflow variables
439 String sql3 = "select name, value from workflowvars where workflowid = " + wfId;
440 log.info (sql3);
441 ResultSet rs3 = s.executeQuery (sql3);
442 while (rs3.next()) {
443 String name = rs3.getString("name");
444 String vstr = rs3.getString("value");
445 Object value = HexUtil.hexDecodeObject(vstr);
446 state.variables.put (name, value);
447 }
448 }
449 } catch (Exception e) {
450 e.printStackTrace();
451 throw new XflowException ("Failed to save workflow in database");
452 } finally {
453 if (s!=null) {
454 try {
455 s.close();
456 } catch (Exception e) {
457 e.printStackTrace();
458 }
459 }
460 if (con != null) {
461 try {
462 con.close();
463 } catch (Exception e) {
464 }
465 }
466 }
467 return state;
468 }
469
470 public static void setVariable (int workflowId, String name, Object value) throws XflowException {
471
472 Connection con = null;
473 Statement s = null;
474 try {
475 System.out.println ("Hex Encoding: " + value);
476 String valueStr = HexUtil.hexEncodeObject (value);
477 System.out.println ("String to be stored: " + valueStr);
478
479 con = Persistence.getConnection();
480 s = con.createStatement();
481 String sql = "select * from workflowvars where workflowId = " + workflowId + " and name = '" +
482 name + "'";
483 log.info (sql);
484 ResultSet rs = s.executeQuery(sql);
485 // This is an update of a var
486 if (rs.next()) {
487 sql = "update workflowvars set value = '" + valueStr + "' where workflowId = " + workflowId + " and name = '" + name + "'";
488 } else {
489 sql = "insert into workflowvars values (" + workflowId + ",'" +
490 name + "','" + valueStr + "')";
491 }
492 log.info (sql);
493 s.execute (sql);
494 } catch (Exception e) {
495 e.printStackTrace();
496 throw new XflowException ("Failed to set workflow variable in database");
497 } finally {
498 if (s!=null) {
499 try {
500 s.close();
501 } catch (Exception e) {
502 e.printStackTrace();
503 }
504 }
505 if (con != null) {
506 try {
507 con.close();
508 } catch (Exception e) {
509 }
510 }
511 }
512 }
513
514 public static Object getVariable (int workflowId, String name) throws XflowException {
515
516 Object result = null;
517 Connection con = null;
518 Statement s = null;
519 try {
520 con = Persistence.getConnection();
521 s = con.createStatement();
522
523 String sql = "select * from workflowvars where workflowId = " + workflowId +
524 " and name = '" + name + "'";
525 log.info (sql);
526 ResultSet rs = s.executeQuery (sql);
527 if (rs.next()) {
528 String vstr = rs.getString("value");
529 System.out.println ("Stored String: " + vstr);
530 result = HexUtil.hexDecodeObject(vstr);
531 }
532 } catch (Exception e) {
533 e.printStackTrace();
534 throw new XflowException ("Failed to get workflow variable from database");
535 } finally {
536 if (s!=null) {
537 try {
538 s.close();
539 } catch (Exception e) {
540 e.printStackTrace();
541 }
542 }
543 if (con != null) {
544 try {
545 con.close();
546 } catch (Exception e) {
547 }
548 }
549 }
550 return result;
551 }
552
553 public static void setCompleted (int workflowId) throws XflowException {
554
555 Connection con = null;
556 Statement s = null;
557 try {
558 con = Persistence.getConnection();
559 s = con.createStatement();
560 String timeEnded = DateUtil.getTimestamp();
561 String sql = "update workflow set isActive = 'false', timeEnded = '" + timeEnded +
562 "', status = 'COMPLETED' where workflowId = " + workflowId;
563 log.info (sql);
564 s.execute (sql);
565
566 // Do house cleaning of workflow vars, workitems? We'll keep them in the db
567 // until we develop a data warehousing solution.
568
569 } catch (Exception e) {
570 e.printStackTrace();
571 throw new XflowException ("Failed to set workflow completion time in database.");
572 } finally {
573 if (s!=null) {
574 try {
575 s.close();
576 } catch (Exception e) {
577 e.printStackTrace();
578 }
579 }
580 if (con != null) {
581 try {
582 con.close();
583 } catch (Exception e) {
584 }
585 }
586 }
587 }
588
589 public static boolean isCompleted (int workflowId) throws XflowException {
590
591 boolean result = false;
592 Connection con = null;
593 Statement s = null;
594 try {
595 con = Persistence.getConnection();
596 s = con.createStatement();
597
598 String sql = "select * from workflow where status = 'COMPLETED' and workflowId = " + workflowId;
599 log.info (sql);
600 s.execute (sql);
601 ResultSet rs = s.executeQuery(sql);
602 if (rs.next()) {
603 result = true;
604 }
605
606 } catch (Exception e) {
607 e.printStackTrace();
608 throw new XflowException ("Failed to set workflow completion time in database.");
609 } finally {
610 if (s!=null) {
611 try {
612 s.close();
613 } catch (Exception e) {
614 e.printStackTrace();
615 }
616 }
617 if (con != null) {
618 try {
619 con.close();
620 } catch (Exception e) {
621 }
622 }
623 }
624 return result;
625 }
626
627 public static Vector getProcessesWithTimeouts() throws XflowException {
628
629 Vector v = new Vector();
630 Connection con = null;
631 Statement s = null;
632 try {
633 con = Persistence.getConnection();
634 s = con.createStatement();
635 String pName = null;
636 int pId = -1;
637 int pTout = -1;
638 String pThdl = null;
639
640 String sql = "select n.nid, n.name, p.value from node n, nodeprops p where " +
641 " n.nid = p.nid and p.name = 'timeoutMinutes'";
642 //log.info (sql);
643 ResultSet rs = s.executeQuery (sql);
644 while (rs.next()) {
645 pName = rs.getString("name");
646 pId = rs.getInt("nid");
647 String vstr = rs.getString("value");
648 Object value = HexUtil.hexDecodeObject(vstr);
649 Integer iValue = (Integer)value;
650 pTout = iValue.intValue();
651
652 sql = "select p.value from node n, nodeprops p where n.nid = p.nid and n.nid = " + pId +
653 " and p.name = 'timeoutHandler'";
654 //log.info (sql);
655 ResultSet rs2 = s.executeQuery(sql);
656 if (rs2.next()) {
657 vstr = rs2.getString("value");
658 value = HexUtil.hexDecodeObject(vstr);
659 pThdl = (String)value;
660 }
661
662 sql = "select w.workflowId from workflow w, graph g, node n where w.gid = g.gid and g.gid = n.gid and n.nid = " + pId;
663 //log.info (sql);
664 ResultSet rs3 = s.executeQuery (sql);
665 while (rs3.next()) {
666 int wfId = rs3.getInt ("workflowId");
667 ProcessWithTimeout pto = new ProcessWithTimeout();
668 pto.workflowId = wfId;
669 pto.processName = pName;
670 pto.timeoutMinutes = pTout;
671 pto.timeoutHandler = pThdl;
672 v.addElement (pto);
673 }
674 }
675 } catch (Exception e) {
676 e.printStackTrace();
677 throw new XflowException ("Failed to set workflow completion time in database.");
678 } finally {
679 if (s!=null) {
680 try {
681 s.close();
682 } catch (Exception e) {
683 e.printStackTrace();
684 }
685 }
686 if (con != null) {
687 try {
688 con.close();
689 } catch (Exception e) {
690 }
691 }
692 }
693 return v;
694 }
695 }
696