KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > shark > WfActivityImpl


1 package org.enhydra.shark;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Collections JavaDoc;
5 import java.util.Comparator JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.HashSet JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Map JavaDoc;
11 import java.util.Set JavaDoc;
12
13 import org.enhydra.shark.api.ParticipantMappingTransaction;
14 import org.enhydra.shark.api.RootException;
15 import org.enhydra.shark.api.SharkTransaction;
16 import org.enhydra.shark.api.TransactionException;
17 import org.enhydra.shark.api.UserTransaction;
18 import org.enhydra.shark.api.client.wfbase.BaseException;
19 import org.enhydra.shark.api.client.wfmodel.AlreadyRunning;
20 import org.enhydra.shark.api.client.wfmodel.AlreadySuspended;
21 import org.enhydra.shark.api.client.wfmodel.CannotAcceptSuspended;
22 import org.enhydra.shark.api.client.wfmodel.CannotComplete;
23 import org.enhydra.shark.api.client.wfmodel.CannotResume;
24 import org.enhydra.shark.api.client.wfmodel.CannotStart;
25 import org.enhydra.shark.api.client.wfmodel.CannotStop;
26 import org.enhydra.shark.api.client.wfmodel.CannotSuspend;
27 import org.enhydra.shark.api.client.wfmodel.InvalidData;
28 import org.enhydra.shark.api.client.wfmodel.InvalidPerformer;
29 import org.enhydra.shark.api.client.wfmodel.InvalidState;
30 import org.enhydra.shark.api.client.wfmodel.NotRunning;
31 import org.enhydra.shark.api.client.wfmodel.NotSuspended;
32 import org.enhydra.shark.api.client.wfmodel.ResultNotAvailable;
33 import org.enhydra.shark.api.client.wfmodel.TransitionNotAllowed;
34 import org.enhydra.shark.api.client.wfmodel.UpdateNotAllowed;
35 import org.enhydra.shark.api.client.wfmodel.WfDataEventAudit;
36 import org.enhydra.shark.api.client.wfmodel.WfEventAudit;
37 import org.enhydra.shark.api.client.wfmodel.WfRequester;
38 import org.enhydra.shark.api.common.DeadlineInfo;
39 import org.enhydra.shark.api.common.SharkConstants;
40 import org.enhydra.shark.api.internal.assignment.PerformerData;
41 import org.enhydra.shark.api.internal.instancepersistence.ActivityPersistenceInterface;
42 import org.enhydra.shark.api.internal.instancepersistence.ActivityVariablePersistenceInterface;
43 import org.enhydra.shark.api.internal.instancepersistence.AssignmentPersistenceInterface;
44 import org.enhydra.shark.api.internal.instancepersistence.DeadlinePersistenceInterface;
45 import org.enhydra.shark.api.internal.instancepersistence.PersistenceException;
46 import org.enhydra.shark.api.internal.instancepersistence.PersistentManagerInterface;
47 import org.enhydra.shark.api.internal.limitagent.LimitAgentException;
48 import org.enhydra.shark.api.internal.limitagent.LimitAgentManager;
49 import org.enhydra.shark.api.internal.partmappersistence.ParticipantMap;
50 import org.enhydra.shark.api.internal.partmappersistence.ParticipantMappingManager;
51 import org.enhydra.shark.api.internal.scripting.Evaluator;
52 import org.enhydra.shark.api.internal.toolagent.ToolAgentGeneralException;
53 import org.enhydra.shark.api.internal.usergroup.UserGroupManager;
54 import org.enhydra.shark.api.internal.working.ToolAgentManager;
55 import org.enhydra.shark.api.internal.working.WfActivityInternal;
56 import org.enhydra.shark.api.internal.working.WfAssignmentInternal;
57 import org.enhydra.shark.api.internal.working.WfProcessInternal;
58 import org.enhydra.shark.api.internal.working.WfProcessMgrInternal;
59 import org.enhydra.shark.api.internal.working.WfResourceInternal;
60 import org.enhydra.shark.utilities.MiscUtilities;
61 import org.enhydra.shark.xpdl.XMLCollectionElement;
62 import org.enhydra.shark.xpdl.XMLComplexElement;
63 import org.enhydra.shark.xpdl.XMLUtil;
64 import org.enhydra.shark.xpdl.XPDLConstants;
65 import org.enhydra.shark.xpdl.elements.Activity;
66 import org.enhydra.shark.xpdl.elements.ActualParameter;
67 import org.enhydra.shark.xpdl.elements.ActualParameters;
68 import org.enhydra.shark.xpdl.elements.Deadline;
69 import org.enhydra.shark.xpdl.elements.FormalParameter;
70 import org.enhydra.shark.xpdl.elements.FormalParameters;
71 import org.enhydra.shark.xpdl.elements.Participant;
72 import org.enhydra.shark.xpdl.elements.Responsible;
73 import org.enhydra.shark.xpdl.elements.SubFlow;
74 import org.enhydra.shark.xpdl.elements.WorkflowProcess;
75
76 /**
77  * WfActivityImpl - Workflow Activity Object implementation
78  * @author Sasa Bojanic
79  * @author Vladimir Puskas
80  */

81 public class WfActivityImpl extends WfExecutionObjectImpl implements WfActivityInternal {
82
83    private String JavaDoc mgrName;
84    private String JavaDoc processId;
85
86    private Activity activityDefinition;
87    private WorkflowProcess processDefinition;
88    private String JavaDoc activitySetDefinitionId;
89    private String JavaDoc activityDefinitionId;
90
91    private String JavaDoc blockActivityId;
92
93    private boolean accepted=false;
94    private String JavaDoc resourceUsername;
95
96    private Map JavaDoc activitiesProcessContext;
97
98    // for implementation of requester interface
99
private String JavaDoc performerId;
100    private boolean isSubflowSynchronous=true;
101
102    // holds Ids of variables that make activity results - only those variables will be
103
// returned to the process context when activity finishes
104
private Set JavaDoc resultVariableIds;
105
106    private Evaluator evaluator;
107
108    private WfProcessInternal process;
109
110    private long acceptedTime=Long.MAX_VALUE/2;
111
112    private long activatedTime=Long.MAX_VALUE/2;
113
114    protected List JavaDoc assignmentResourceIds;
115
116    protected Set JavaDoc variableIdsToPersist=new HashSet JavaDoc();
117
118    //private ToolRunner myToolRunner;
119

120    protected Thread JavaDoc startSubflowThread=null;
121
122    //protected boolean deleteAssignments=false;
123

124    protected WfActivityInternal blockActivity=null;
125
126    protected ToolAgentGeneralException toolAgentException=null;
127    protected String JavaDoc exceptionName=null;
128    protected List JavaDoc deadlinesInfo;
129
130    private boolean justCreated=false;
131    private boolean justCreatedVariables=false;
132    private boolean justCreatedDeadlines=false;
133
134    /**
135     * Create a new WfActivityImpl
136     */

137    protected WfActivityImpl(SharkTransaction t,
138                             WfProcessInternal process,
139                             String JavaDoc key,
140                             String JavaDoc activitySetDefId,
141                             String JavaDoc activityDefId,
142                             WfActivityInternal blockActivity) throws BaseException {
143       this.mgrName=process.manager_name(t);
144       this.processId=process.key(t);
145       this.key=key;
146       this.process=process;
147       this.activityDefinitionId=activityDefId;
148       this.blockActivity=blockActivity;
149       this.justCreated=true;
150       this.justCreatedVariables=true;
151       this.justCreatedDeadlines=true;
152       // initialize process definition
153
WorkflowProcess wp=getProcessDefinition(t);
154       if (this.blockActivity!=null) {
155          this.blockActivityId=this.blockActivity.key(t);
156          this.activitySetDefinitionId=activitySetDefId;
157       }
158       // initializing activity definition
159
getActivityDefinition(t);
160       name=activityDefinition.getName();
161       if (name.equals("")) {
162          name=getActivityDefinition(t).getId();
163       }
164       description=activityDefinition.getDescription();
165       if (description!=null && description.length()>254) {
166          description=description.substring(0,253);
167       }
168       try {
169          priority=Integer.valueOf(activityDefinition.getPriority()).shortValue();
170       } catch (Exception JavaDoc ex) {
171          priority=3;
172       }
173       lastStateTime = System.currentTimeMillis();
174
175       lastStateEventAudit=SharkEngineManager.
176          getInstance().
177          getObjectFactory().
178          createStateEventAuditWrapper(t,
179                                       this,
180                                       SharkConstants.EVENT_ACTIVITY_STATE_CHANGED,
181                                       null,
182                                       state);
183
184       activitiesProcessContext=getActivityContext(t);
185       resultVariableIds=new HashSet JavaDoc();
186       if (activitiesProcessContext.size()>0) {
187          variableIdsToPersist.addAll(getContext(t).keySet());
188          if (SharkEngineManager.getInstance().getEventAuditManager()!=null) {
189             SharkEngineManager.
190                getInstance().
191                getObjectFactory().
192                createDataEventAuditWrapper(t,
193                                            this,
194                                            SharkConstants.EVENT_ACTIVITY_CONTEXT_CHANGED,
195                                            null,
196                                            new HashMap JavaDoc(activitiesProcessContext));
197          }
198       }
199
200       assignmentResourceIds=new ArrayList JavaDoc();
201
202    }
203
204    /**
205     * Used to create object when restoring it from database.
206     */

207    protected WfActivityImpl (ActivityPersistenceInterface po,WfProcessInternal proc) {
208       this.process=proc;
209       restore(po);
210    }
211
212    public List JavaDoc getAssignmentResourceIds (SharkTransaction t) throws BaseException {
213       if (assignmentResourceIds==null) {
214          try {
215             assignmentResourceIds=new ArrayList JavaDoc();
216             boolean createAssignments=Boolean.valueOf(
217                   SharkEngineManager.
218                   getInstance().
219                   getCallbackUtilities().
220                   getProperty("SharkKernel.createAssignments","true")).booleanValue();
221             if (createAssignments) {
222                List JavaDoc l=SharkEngineManager
223                   .getInstance()
224                   .getInstancePersistenceManager().getAllAssignmentsForActivity(key,t);
225                for (int i=0; i<l.size(); i++) {
226                   AssignmentPersistenceInterface po=(AssignmentPersistenceInterface)l.get(i);
227                   assignmentResourceIds.add(po.getResourceUsername());
228                }
229             }
230          } catch (Exception JavaDoc ex) {
231             throw new BaseException(ex);
232          }
233       }
234       return assignmentResourceIds;
235    }
236
237    /**
238     * Getter for the process of this activity.
239     */

240    public WfProcessInternal container (SharkTransaction t) throws BaseException {
241       return process;
242    }
243
244    /**
245     * Retrieve the Result map of this activity.
246     * @return Map of results from this activity
247     */

248    public Map JavaDoc result (SharkTransaction t) throws BaseException, ResultNotAvailable {
249       Map JavaDoc resultMap=new HashMap JavaDoc();
250       //System.out.println("Updating process with the variables "+getChangedContextVariableIds(t));
251
Iterator JavaDoc it=resultMap(t).entrySet().iterator();
252       while (it.hasNext()) {
253          Map.Entry JavaDoc me=(Map.Entry JavaDoc)it.next();
254          try {
255             resultMap.put(me.getKey(),MiscUtilities.cloneWRD(me.getValue()));
256          } catch (Throwable JavaDoc thr) {
257             throw new BaseException(thr);
258          }
259       }
260       return resultMap;
261    }
262
263    private Map JavaDoc resultMap (SharkTransaction t) throws BaseException {
264       Map JavaDoc resultMap=new HashMap JavaDoc();
265       //System.out.println("Updating process with the variables "+getChangedContextVariableIds(t));
266
Iterator JavaDoc it=getResultVariableIds(t).iterator();
267       while (it.hasNext()) {
268          java.lang.Object JavaDoc vId=it.next();
269          resultMap.put(vId,getContext(t).get(vId));
270       }
271       return resultMap;
272    }
273
274    /**
275     * Assign Result for this activity.
276     */

277    public void set_result (SharkTransaction t,Map JavaDoc results) throws BaseException, InvalidData {
278       try {
279          setProcessContext(t,results,SharkConstants.EVENT_ACTIVITY_RESULT_CHANGED);
280       } catch (InvalidData id) {
281          SharkEngineManager.getInstance().getCallbackUtilities().error("Activity"+toString()+" - failed to set the activity result");
282          throw id;
283       } catch (BaseException be) {
284          SharkEngineManager.getInstance().getCallbackUtilities().error("Activity"+toString()+" - failed to set the activity result");
285          throw be;
286       } catch (Exception JavaDoc ex) {
287          throw new BaseException(ex);
288       }
289    }
290
291    public void complete (SharkTransaction t) throws BaseException, CannotComplete {
292       // get the type of this activity
293
int type=getActivityDefinition(t).getActivityType();
294       switch (type) {
295          case XPDLConstants.ACTIVITY_TYPE_ROUTE: // Route
296
throw new BaseException("Subflow activity can be finished only automatically");
297             //this.finish(t); // ROUTE goes directly to complete status
298
case XPDLConstants.ACTIVITY_TYPE_NO: // NoImplementation
299
// NOTE: when using JaWE's code for XPDL handling, we never
300
// have this activity type. NO type is representet by
301
// TOOL type with zero tools
302
this.finish(t); // NO impl goes directly to complete status
303
break;
304          case XPDLConstants.ACTIVITY_TYPE_TOOL: // Tools
305
int hmt=getActivityDefinition(t).getActivityTypes().getImplementation().getImplementationTypes().getTools().size();
306             // if there is no tool -> the same as No implementation
307
if (hmt>0) {
308                if (getActivityDefinition(t).getActivityStartMode()==XPDLConstants.ACTIVITY_MODE_MANUAL) {
309                   boolean shouldFinishImmediatelly=getActivityDefinition(t).getActivityFinishMode()==XPDLConstants.ACTIVITY_MODE_AUTOMATIC;
310                   try {
311                      if (shouldFinishImmediatelly || getAssignmentResourceIds(t).size()>0) {
312                         this.runTool(t);
313                      }
314                   } catch (Exception JavaDoc ex) {
315                      if (ex instanceof ToolAgentGeneralException) {
316                         toolAgentException=(ToolAgentGeneralException)ex;
317                         finishImproperlyAndNotifyProcess(t,
318                                                          SharkUtilities.extractExceptionName(toolAgentException));
319
320                         return;
321                      } else {
322                         throw new BaseException(ex);
323                      }
324                   }
325                   if (shouldFinishImmediatelly || getAssignmentResourceIds(t).size()==0) {
326                      finish(t);
327                   } else {
328                      // delete assignments
329
removeAssignments(t, true, true);
330                   }
331                   return;
332                   // the case when start mode is AUTOMATIC, but finish mode is MANUAL
333
} else {
334                   finish(t);
335                }
336                //throw new BaseException("When the start mode is automatic, Tool activity can be finished automatically");
337
/*if (getStartMode()==WfActivityImpl.AUTOMATIC_MODE &&
338                 getFinishMode()==WfActivityImpl.MANUAL_MODE) {
339                 return;
340                 }*/

341                // check the finish mode
342
//this.finish(t); // this should never happen->tool agents should directly call finish()
343

344                //}
345
} else {
346                this.finish(t); // NO impl goes directly to complete status
347
}
348             break;
349          case XPDLConstants.ACTIVITY_TYPE_SUBFLOW: // SubFlow
350
throw new BaseException("Subflow activity can be finished only automatically");
351             //this.finish(t); // Subflow act. goes directly to complete status
352
//break;
353
case XPDLConstants.ACTIVITY_TYPE_BLOCK: // BlockActivity
354
throw new BaseException("Block activity can be finished only automatically");
355             //this.finish(t); // Block act. goes directly to complete status
356
//break;
357
}
358    }
359
360    /**
361     * Complete this activity.
362     */

363    public void finish (SharkTransaction t) throws BaseException, CannotComplete {
364       try {
365
366          // remove assignments first, because method for getting assignments
367
// from database depends on activity's state
368
removeAssignments(t, true, true);
369
370          change_state(t,SharkConstants.STATE_CLOSED_COMPLETED);
371          process.set_process_context(t,resultMap(t));
372
373          process.activity_complete(t,this);
374
375       } catch (InvalidState is) {
376          throw new CannotComplete(is);
377       } catch (TransitionNotAllowed tna) {
378          throw new CannotComplete(tna);
379       } catch (InvalidData e) {
380          throw new CannotComplete("Invalid result data was passed");
381       } catch (ResultNotAvailable rne) {
382          throw new CannotComplete("Result of activity is not available");
383       } catch (UpdateNotAllowed una) {
384          throw new CannotComplete("Process context update is not allowed");
385       } catch (Exception JavaDoc ex) {
386          if (ex instanceof BaseException) {
387             throw (BaseException)ex;
388          } else {
389             throw new BaseException(ex);
390          }
391       }
392    }
393
394    protected void change_state (SharkTransaction t,String JavaDoc new_state) throws BaseException, InvalidState, TransitionNotAllowed {
395       //System.out.println("Act "+this+" Curr st is "+state(t)+", new state is "+new_state+", valid states are "+SharkUtilities.valid_activity_states(state(t)));
396
if (!SharkUtilities.valid_activity_states(state(t)).contains(new_state)) {
397          throw new TransitionNotAllowed("Current state is "+state+", can't change to state "+new_state+"!");
398       }
399
400       // persist changes to activity state
401
String JavaDoc oldState=state;
402       state=new_state;
403
404       lastStateTime = System.currentTimeMillis();
405       try {
406          persist(t);
407       } catch (TransactionException te) {
408          throw new BaseException(te);
409       }
410       lastStateEventAudit=SharkEngineManager.
411          getInstance().
412          getObjectFactory().
413          createStateEventAuditWrapper(t,
414                                       this,
415                                       SharkConstants.EVENT_ACTIVITY_STATE_CHANGED,
416                                       oldState,
417                                       new_state);
418       // cancel the limit agent when we enter closed state
419
if (state.startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
420          LimitAgentManager mgr = SharkEngineManager.getInstance().getLimitAgentManager();
421          if (mgr != null) {
422             try {
423                mgr.notifyStop(processId,key);
424             } catch (LimitAgentException e) {
425                throw new BaseException(e);
426             }
427          }
428       }
429
430    }
431
432    public void set_process_context (SharkTransaction t,Map JavaDoc new_value) throws BaseException, InvalidData, UpdateNotAllowed {
433       try {
434          setProcessContext(t,new_value,SharkConstants.EVENT_ACTIVITY_CONTEXT_CHANGED);
435       } catch (InvalidData id) {
436          throw id;
437       } catch (UpdateNotAllowed una) {
438          throw una;
439       } catch (BaseException be) {
440          throw be;
441       } catch (Exception JavaDoc ex) {
442          throw new BaseException(ex);
443       }
444    }
445
446    private void setProcessContext (SharkTransaction t,Map JavaDoc newValue,String JavaDoc eventType)
447       throws BaseException, InvalidData, UpdateNotAllowed, Exception JavaDoc {
448       if (newValue==null) {
449          throw new BaseException("new value is null");
450       }
451       Map JavaDoc oldValues=new HashMap JavaDoc();
452       Map JavaDoc newChanged=new HashMap JavaDoc();
453       Iterator JavaDoc it=newValue.entrySet().iterator();
454       while (it.hasNext()) {
455          Map.Entry JavaDoc me=(Map.Entry JavaDoc)it.next();
456          String JavaDoc id=(String JavaDoc)me.getKey();
457          Object JavaDoc val= me.getValue();
458
459          //if (val==null) continue;
460
if (getContext(t).containsKey(id)) {
461             Object JavaDoc oldVal=getContext(t).get(id);
462             //type checking
463
if (SharkUtilities.checkDataType(t,getProcessDefinition(t),id,oldVal,val)) {
464                //System.out.println("var "+id+"["+oldVal+","+val+"]");
465
if ((oldVal!=null && !oldVal.equals(val)) || (oldVal==null && val!=null)) {
466                   oldValues.put(id,oldVal);
467                   newChanged.put(id,val);
468                }
469             } else {
470                throw new InvalidData("Invalid data type for activity variable "+id);
471             }
472          } else {
473             //System.err.println("The variable "+id+" is not in the context");
474
throw new UpdateNotAllowed("Context attribute "+id+" does not exist in the activity context - adding new attributes to activity context is not allowed");
475          }
476       }
477       if (newChanged.size()>0 || eventType.equals(SharkConstants.EVENT_ACTIVITY_RESULT_CHANGED)) {
478          getContext(t).putAll(newChanged);
479          Map JavaDoc toPersist=new HashMap JavaDoc(newChanged);
480          Map JavaDoc newSRVars=null;
481          if (eventType.equals(SharkConstants.EVENT_ACTIVITY_RESULT_CHANGED)) {
482             newSRVars=new HashMap JavaDoc();
483             Set JavaDoc oldRVIds=new HashSet JavaDoc(getResultVariableIds(t));
484             getResultVariableIds(t).addAll(newValue.keySet());
485             Set JavaDoc newRVIds=new HashSet JavaDoc(getResultVariableIds(t));
486             newRVIds.removeAll(oldRVIds);
487             Iterator JavaDoc itRV=newRVIds.iterator();
488             while (itRV.hasNext()) {
489                String JavaDoc id=(String JavaDoc)itRV.next();
490                Object JavaDoc val=getContext(t).get(id);
491                toPersist.put(id,val);
492                newSRVars.put(id,val);
493             }
494          }
495
496          variableIdsToPersist.addAll(toPersist.keySet());
497          persistActivityContext(t);
498          if (newChanged.size()>0) {
499             if (SharkEngineManager.getInstance().getEventAuditManager()!=null) {
500                boolean persistOldEventAuditData=new Boolean JavaDoc(
501                      SharkEngineManager
502                         .getInstance()
503                         .getCallbackUtilities()
504                         .getProperty("PERSIST_OLD_EVENT_AUDIT_DATA","true")).booleanValue();
505                if (!persistOldEventAuditData) {
506                   oldValues=null;
507                }
508                SharkEngineManager.getInstance().getObjectFactory().
509                   createDataEventAuditWrapper(t,this,SharkConstants.EVENT_ACTIVITY_CONTEXT_CHANGED,oldValues,newChanged);
510             }
511          }
512          if (newSRVars!=null && newSRVars.size()>0) {
513             if (SharkEngineManager.getInstance().getEventAuditManager()!=null) {
514                boolean persistOldEventAuditData=new Boolean JavaDoc(
515                      SharkEngineManager
516                         .getInstance()
517                         .getCallbackUtilities()
518                         .getProperty("PERSIST_OLD_EVENT_AUDIT_DATA","true")).booleanValue();
519                if (!persistOldEventAuditData) {
520                   oldValues=null;
521                }
522                SharkEngineManager.getInstance().getObjectFactory().
523                   createDataEventAuditWrapper(t,this,eventType,null,newSRVars);
524             }
525          }
526       }
527    }
528
529    /**
530     * Resume this process or activity.
531     */

532    public void resume (SharkTransaction t) throws BaseException, CannotResume, NotSuspended {
533       int type=getActivityDefinition(t).getActivityType();
534
535       // try {
536
if (!state(t).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
537          throw new NotSuspended("Can't resume activity that is not suspended");
538       }
539       if (process.state(t).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
540          throw new CannotResume("Can't resume activity which process is suspended");
541       }
542       if (blockActivityId!=null && block_activity(t).state(t).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
543          throw new CannotResume("Can't resume activity which block is suspended");
544       }
545
546       try {
547          if (accepted || type==XPDLConstants.ACTIVITY_TYPE_BLOCK || type==XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
548             change_state(t,SharkConstants.STATE_OPEN_RUNNING);
549          } else {
550             change_state(t,SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED);
551          }
552       } catch (Exception JavaDoc ex) {
553          throw new CannotResume(ex);
554       }
555
556       if (type==XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
557          // if this is a subflow activity, resume it's process
558
// if it is SYNCHRONOUS
559
if (isSubflowSynchronous) {
560             WfProcessInternal performer=getPerformer(t);
561             if (performer==null) {
562                SubFlow subflow=getActivityDefinition(t).getActivityTypes().getImplementation().getImplementationTypes().getSubFlow();
563                String JavaDoc refSbflw=subflow.getId();
564                WorkflowProcess wp=SharkUtilities.getWorkflowProcess(subflow,refSbflw);
565                if (wp!=null || performerId!=null) {
566                   throw new BaseException("Null performer of sync. subflow activity");
567                }
568
569                try {
570                   SharkEngineManager.getInstance().getWfEngineInteroperabilityMgr().resume(t,performerId,processId,SharkUtilities.createAssignmentKey(key,getResourceRequesterUsername(t)));
571                } catch (Exception JavaDoc ex) {
572                   throw new BaseException(ex);
573                }
574
575             } else {
576                if (performer.state(t).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
577                   performer.resume(t);
578                }
579             }
580          }
581       } else if (type==XPDLConstants.ACTIVITY_TYPE_BLOCK) {
582          List JavaDoc actActs=process.getAllActiveActivitiesForBlockActivity(t,key);
583          Iterator JavaDoc it=actActs.iterator();
584          while (it.hasNext()) {
585             WfActivityInternal act=(WfActivityInternal)it.next();
586             if (act.state(t).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
587                act.resume(t);
588             }
589          }
590       }
591
592    }
593
594    /**
595     * Suspend this process or activity.
596     */

597    public void suspend(SharkTransaction t) throws BaseException, CannotSuspend, NotRunning, AlreadySuspended {
598       if (state(t).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
599          throw new AlreadySuspended("The activity is already suspended - can't suspend it twice!");
600       }
601
602       try {
603          change_state(t,SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED);
604       } catch (Exception JavaDoc ex) {
605          throw new CannotSuspend(ex);
606       }
607
608
609       int type=getActivityDefinition(t).getActivityType();
610       if (type==XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
611          // if this is a subflow activity, suspend it's process
612
// if it is SYNCHRONOUS
613
if (isSubflowSynchronous) {
614             WfProcessInternal performer=getPerformer(t);
615             if (performer==null) {
616                SubFlow subflow=getActivityDefinition(t).getActivityTypes().getImplementation().getImplementationTypes().getSubFlow();
617                String JavaDoc refSbflw=subflow.getId();
618                WorkflowProcess wp=SharkUtilities.getWorkflowProcess(subflow,refSbflw);
619                if (wp!=null || performerId!=null) {
620                   throw new BaseException("Null performer of sync. subflow activity");
621                }
622
623                try {
624                   SharkEngineManager.getInstance().getWfEngineInteroperabilityMgr().suspend(t,performerId,processId,SharkUtilities.createAssignmentKey(key,getResourceRequesterUsername(t)));
625                } catch (Exception JavaDoc ex) {
626                   throw new BaseException(ex);
627                }
628
629
630             } else {
631                String JavaDoc perfState=performer.state(t);
632                if (perfState.startsWith(SharkConstants.STATEPREFIX_OPEN) &&
633                    !perfState.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
634                   performer.suspend(t);
635                }
636             }
637          }
638       } else if (type==XPDLConstants.ACTIVITY_TYPE_BLOCK) {
639          List JavaDoc actActs=process.getAllActiveActivitiesForBlockActivity(t,key);
640          Iterator JavaDoc it=actActs.iterator();
641          while (it.hasNext()) {
642             WfActivityInternal act=(WfActivityInternal)it.next();
643             String JavaDoc actState=act.state(t);
644             if (actState.startsWith(SharkConstants.STATEPREFIX_OPEN) &&
645                 !actState.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
646                act.suspend(t);
647             }
648          }
649       }
650
651    }
652
653    /**
654     * Terminate this process or activity.
655     */

656    public void terminateFromProcess (SharkTransaction t) throws BaseException, CannotStop, NotRunning {
657       terminateActivity(t,true);
658    }
659    /**
660     * Terminate this process or activity.
661     */

662    public void terminate(SharkTransaction t) throws BaseException, CannotStop, NotRunning {
663       terminateActivity(t,false);
664    }
665
666    protected void terminateActivity (SharkTransaction t,boolean fromProcess) throws BaseException, CannotStop, NotRunning {
667       String