package org.enhydra.shark;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.enhydra.shark.api.RootException;
import org.enhydra.shark.api.client.wfmc.wapi.WMSessionHandle;
import org.enhydra.shark.api.client.wfmodel.AlreadyRunning;
import org.enhydra.shark.api.client.wfmodel.AlreadySuspended;
import org.enhydra.shark.api.client.wfmodel.CannotAcceptSuspended;
import org.enhydra.shark.api.client.wfmodel.CannotComplete;
import org.enhydra.shark.api.client.wfmodel.CannotResume;
import org.enhydra.shark.api.client.wfmodel.CannotStart;
import org.enhydra.shark.api.client.wfmodel.CannotStop;
import org.enhydra.shark.api.client.wfmodel.CannotSuspend;
import org.enhydra.shark.api.client.wfmodel.InvalidData;
import org.enhydra.shark.api.client.wfmodel.InvalidPerformer;
import org.enhydra.shark.api.client.wfmodel.InvalidState;
import org.enhydra.shark.api.client.wfmodel.NotRunning;
import org.enhydra.shark.api.client.wfmodel.NotSuspended;
import org.enhydra.shark.api.client.wfmodel.ResultNotAvailable;
import org.enhydra.shark.api.client.wfmodel.TransitionNotAllowed;
import org.enhydra.shark.api.client.wfmodel.UpdateNotAllowed;
import org.enhydra.shark.api.client.wfmodel.WfDataEventAudit;
import org.enhydra.shark.api.client.wfmodel.WfEventAudit;
import org.enhydra.shark.api.client.wfmodel.WfRequester;
import org.enhydra.shark.api.common.DeadlineInfo;
import org.enhydra.shark.api.common.SharkConstants;
import org.enhydra.shark.api.internal.assignment.AssignmentManager;
import org.enhydra.shark.api.internal.assignment.PerformerData;
import org.enhydra.shark.api.internal.instancepersistence.ActivityPersistenceObject;
import org.enhydra.shark.api.internal.instancepersistence.ActivityVariablePersistenceObject;
import org.enhydra.shark.api.internal.instancepersistence.AssignmentPersistenceObject;
import org.enhydra.shark.api.internal.instancepersistence.DeadlinePersistenceObject;
import org.enhydra.shark.api.internal.instancepersistence.PersistentManagerInterface;
import org.enhydra.shark.api.internal.scripting.Evaluator;
import org.enhydra.shark.api.internal.security.SecurityManager;
import org.enhydra.shark.api.internal.toolagent.ToolAgentGeneralException;
import org.enhydra.shark.api.internal.working.ToolActivityHandler;
import org.enhydra.shark.api.internal.working.WfActivityInternal;
import org.enhydra.shark.api.internal.working.WfAssignmentInternal;
import org.enhydra.shark.api.internal.working.WfProcessInternal;
import org.enhydra.shark.api.internal.working.WfProcessMgrInternal;
import org.enhydra.shark.api.internal.working.WfResourceInternal;
import org.enhydra.shark.utilities.MiscUtilities;
import org.enhydra.shark.xpdl.XMLCollectionElement;
import org.enhydra.shark.xpdl.XMLUtil;
import org.enhydra.shark.xpdl.XPDLConstants;
import org.enhydra.shark.xpdl.elements.Activity;
import org.enhydra.shark.xpdl.elements.ActivitySet;
import org.enhydra.shark.xpdl.elements.ActualParameter;
import org.enhydra.shark.xpdl.elements.ActualParameters;
import org.enhydra.shark.xpdl.elements.Deadline;
import org.enhydra.shark.xpdl.elements.FormalParameter;
import org.enhydra.shark.xpdl.elements.FormalParameters;
import org.enhydra.shark.xpdl.elements.Package;
import org.enhydra.shark.xpdl.elements.Participant;
import org.enhydra.shark.xpdl.elements.Responsible;
import org.enhydra.shark.xpdl.elements.SubFlow;
import org.enhydra.shark.xpdl.elements.WorkflowProcess;
/**
* WfActivityImpl - Workflow Activity Object implementation
*
* @author Sasa Bojanic
* @author Vladimir Puskas
*/
public class WfActivityImpl extends WfExecutionObjectImpl implements WfActivityInternal {
protected String mgrName;
protected String processId;
protected Activity activityDefinition;
protected WorkflowProcess processDefinition;
protected String activitySetDefinitionId;
protected String activityDefinitionId;
protected String blockActivityId;
protected String resourceUsername;
protected Map activitiesProcessContext = new HashMap();
protected boolean contextInitialized = false;
// for implementation of requester interface
protected String performerId;
protected boolean isSubflowSynchronous = true;
// holds Ids of variables that make activity results - only those variables will be
// returned to the process context when activity finishes
protected Set resultVariableIds;
protected Evaluator evaluator;
protected WfProcessInternal process;
protected long acceptedTime = SharkConstants.UNDEFINED_TIME;
protected long activatedTime = SharkConstants.UNDEFINED_TIME;
protected List assignmentResourceIds;
protected Set variableIdsToPersist = new HashSet();
// protected ToolRunner myToolRunner;
protected Thread startSubflowThread = null;
// protected boolean deleteAssignments=false;
protected WfActivityInternal blockActivity = null;
protected Exception exc = null;
protected String exceptionName = null;
protected List deadlinesInfo;
protected boolean justCreated = false;
protected boolean justCreatedVariables = false;
protected boolean justCreatedDeadlines = false;
/**
* Create a new WfActivityImpl
*/
protected WfActivityImpl(WMSessionHandle shandle,
WfProcessInternal process,
String key,
String activityDefId,
WfActivityInternal blockActivity) throws Exception {
this.mgrName = process.manager_name(shandle);
this.processId = process.key(shandle);
this.key = key;
this.process = process;
this.activityDefinitionId = activityDefId;
// initializing activity definition
getActivityDefinition(shandle);
this.blockActivity = blockActivity;
this.justCreated = true;
this.justCreatedVariables = true;
this.justCreatedDeadlines = true;
if (this.blockActivity != null) {
this.blockActivityId = this.blockActivity.key(shandle);
this.activitySetDefinitionId = ((ActivitySet) activityDefinition.getParent()
.getParent()).getId();
}
name = activityDefinition.getName();
if (name.equals("")) {
name = activityDefinitionId;
}
description = activityDefinition.getDescription();
if (description != null && description.length() > 254) {
description = description.substring(0, 253);
}
try {
String pr = activityDefinition.getPriority();
if (pr.trim().equals("")) {
priority = process.priority(shandle);
} else {
priority = Integer.valueOf(activityDefinition.getPriority()).shortValue();
boolean allowOutOfRangePriority = Boolean.valueOf(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("SharkKernel.allowOutOfRangePriority", "false"))
.booleanValue();
if (!allowOutOfRangePriority && priority < 1)
priority = 1;
if (!allowOutOfRangePriority && priority > 5)
priority = 5;
}
} catch (Exception ex) {
priority = 3;
}
initializeActivityContext(shandle);
assignmentResourceIds = new ArrayList();
if (activitiesProcessContext.size() > 0) {
variableIdsToPersist.addAll(getContext(shandle).keySet());
}
resultVariableIds = new HashSet();
this.calculateLimit(shandle);
}
/**
* Used to create object when restoring it from database.
*/
protected WfActivityImpl(ActivityPersistenceObject po, WfProcessInternal proc) {
this.process = proc;
restore(po);
}
/**
* Activates this activity.
*/
public void activate(WMSessionHandle shandle)
throws Exception,
CannotStart,
AlreadyRunning {
checkReadOnly();
// make sure we aren't already running
if (state(shandle).equals(SharkConstants.STATE_OPEN_RUNNING)) {
throw new AlreadyRunning("Activity "
+ this + " - can't activate already running activity");
}
lastStateTime = System.currentTimeMillis();
activatedTime = lastStateTime;
// re-evaluate deadlines - the information will be stored into DB
reevaluateDeadlines(shandle);
persist(shandle);
persistActivityContext(shandle);
persistDeadlines(shandle);
lastStateEventAudit = SharkEngineManager.getInstance()
.getObjectFactory()
.createStateEventAuditWrapper(shandle,
this,
SharkConstants.EVENT_ACTIVITY_STATE_CHANGED,
null,
state);
if (activitiesProcessContext.size() > 0) { // do not use getContext() here because
// of extensions
if (SharkEngineManager.getInstance().getEventAuditManagers().size() > 0) {
SharkEngineManager.getInstance()
.getObjectFactory()
.createDataEventAuditWrapper(shandle,
this,
SharkConstants.EVENT_ACTIVITY_CONTEXT_CHANGED,
null,
new HashMap(getContext(shandle)));
}
}
try {
startActivity(shandle);
} catch (ToolAgentGeneralException tage) {
exc = tage;
finishImproperlyAndNotifyProcess(shandle,
SharkUtilities.extractExceptionName(tage));
}
startSubflowThread = null;
}
public synchronized List getAssignmentResourceIds(WMSessionHandle shandle)
throws Exception {
if (assignmentResourceIds == null) {
assignmentResourceIds = new ArrayList();
boolean createAssignments = canCreateAssignments(shandle);
if (createAssignments) {
List l = SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.getAllAssignmentsForActivity(shandle, processId, key);
for (int i = 0; i < l.size(); i++) {
AssignmentPersistenceObject po = (AssignmentPersistenceObject) l.get(i);
assignmentResourceIds.add(po.getResourceUsername());
}
}
}
return assignmentResourceIds;
}
/**
* Getter for the process of this activity.
*/
public WfProcessInternal container(WMSessionHandle shandle) throws Exception {
return process;
}
/**
* Retrieve the Result map of this activity.
*
* @return Map of results from this activity
*/
public Map result(WMSessionHandle shandle) throws Exception, ResultNotAvailable {
Map resultMap = new HashMap();
// System.out.println("Updating process with the variables
// "+getChangedContextVariableIds(t));
Iterator it = resultMap(shandle).entrySet().iterator();
while (it.hasNext()) {
Map.Entry me = (Map.Entry) it.next();
try {
resultMap.put(me.getKey(), MiscUtilities.cloneWRD(me.getValue()));
} catch (Throwable thr) {
throw new RootException(thr);
}
}
return resultMap;
}
protected Map resultMap(WMSessionHandle shandle) throws Exception {
Map resultMap = new HashMap();
// System.out.println("Updating process with the variables
// "+getChangedContextVariableIds(t));
Iterator it = getResultVariableIds(shandle).iterator();
while (it.hasNext()) {
java.lang.Object vId = it.next();
resultMap.put(vId, getContext(shandle).get(vId));
}
return resultMap;
}
/**
* Assign Result for this activity.
*/
public void set_result(WMSessionHandle shandle, Map results)
throws Exception,
InvalidData {
checkReadOnly();
try {
setProcessContext(shandle, results, SharkConstants.EVENT_ACTIVITY_RESULT_CHANGED);
} catch (InvalidData id) {
SharkEngineManager.getInstance()
.getCallbackUtilities()
.error(shandle,
"Activity" + toString() + " - failed to set the activity result");
throw id;
} catch (Exception be) {
SharkEngineManager.getInstance()
.getCallbackUtilities()
.error(shandle,
"Activity" + toString() + " - failed to set the activity result");
throw be;
}
}
public void complete(WMSessionHandle shandle) throws Exception, CannotComplete {
checkReadOnly();
// get the type of this activity
int type = getActivityDefinition(shandle).getActivityType();
switch (type) {
case XPDLConstants.ACTIVITY_TYPE_ROUTE: // Route
throw new Exception("Activity "
+ this
+ " - route activity can be finished only automatically");
// this.finish(t); // ROUTE goes directly to complete status
case XPDLConstants.ACTIVITY_TYPE_NO: // NoImplementation
this.finish(shandle); // NO impl goes directly to complete status
break;
case XPDLConstants.ACTIVITY_TYPE_TOOL: // Tools
boolean shouldFinishImmediatelly = getActivityDefinition(shandle).getActivityFinishMode() == XPDLConstants.ACTIVITY_MODE_AUTOMATIC;
if (getActivityDefinition(shandle).getActivityStartMode() == XPDLConstants.ACTIVITY_MODE_MANUAL) {
try {
if (shouldFinishImmediatelly
|| getAssignmentResourceIds(shandle).size() > 0) {
this.runTool(shandle);
}
} catch (Exception ex) {
if (ex instanceof ToolAgentGeneralException) {
exc = ex;
finishImproperlyAndNotifyProcess(shandle,
SharkUtilities.extractExceptionName(exc));
return;
}
throw ex;
}
if (shouldFinishImmediatelly
|| getAssignmentResourceIds(shandle).size() == 0) {
finish(shandle);
} else {
// delete assignments
removeAssignments(shandle, true, true);
}
} else {
if (!shouldFinishImmediatelly) {
this.finish(shandle);
}
}
break;
case XPDLConstants.ACTIVITY_TYPE_SUBFLOW: // SubFlow
throw new Exception("Activity "
+ this
+ " - subflow activity can be finished only automatically");
// this.finish(t); // Subflow act. goes directly to complete status
// break;
case XPDLConstants.ACTIVITY_TYPE_BLOCK: // BlockActivity
throw new Exception("Activity "
+ this
+ " - block activity can be finished only automatically");
// this.finish(t); // Block act. goes directly to complete status
// break;
}
}
/**
* Complete this activity.
*/
public void finish(WMSessionHandle shandle) throws Exception, CannotComplete {
checkReadOnly();
try {
boolean cont = true;
if (handleAllAssignments(shandle)) {
checkReadOnly();
int[] es = execution_status(shandle);
removeAssignment(shandle, SharkEngineManager.getInstance()
.getCallbackUtilities()
.getUserId(shandle), false, true);
if ((es[1] + es[2]) > 1) {
cont = false;
}
}
if (cont) {
// remove assignments first, because method for getting assignments
// from database depends on activity's state
removeAssignments(shandle, true, true);
change_state(shandle, SharkConstants.STATE_CLOSED_COMPLETED);
process.set_process_context(shandle, resultMap(shandle));
process.activity_complete(shandle, this);
}
} catch (InvalidData e) {
throw new CannotComplete("Activity "
+ this
+ " -> can't complete activity. Invalid result data was passed.");
} catch (ResultNotAvailable rne) {
throw new CannotComplete("Activity "
+ this
+ " -> can't complete activity. Result of activity is not available.");
} catch (UpdateNotAllowed una) {
throw new CannotComplete("Activity "
+ this
+ " -> can't complete activity. Process context update is not allowed.");
}
}
protected void change_state(WMSessionHandle shandle, String new_state)
throws Exception,
InvalidState,
TransitionNotAllowed {
// System.out.println("Act "+this+" Curr st is "+state(t)+", new state is
// "+new_state+", valid states are
// "+SharkUtilities.valid_activity_states(state(t)));
if (!SharkUtilities.valid_activity_states(state(shandle)).contains(new_state)) {
throw new TransitionNotAllowed("Activity "
+ this + " - current state is " + state
+ ", can't change to state " + new_state + "!");
}
// persist changes to activity state
String oldState = state;
state = new_state;
lastStateTime = System.currentTimeMillis();
persist(shandle);
lastStateEventAudit = SharkEngineManager.getInstance()
.getObjectFactory()
.createStateEventAuditWrapper(shandle,
this,
SharkConstants.EVENT_ACTIVITY_STATE_CHANGED,
oldState,
new_state);
}
public void set_process_context(WMSessionHandle shandle, Map new_value)
throws Exception,
InvalidData,
UpdateNotAllowed {
checkReadOnly();
setProcessContext(shandle, new_value, SharkConstants.EVENT_ACTIVITY_CONTEXT_CHANGED);
}
protected void setProcessContext(WMSessionHandle shandle,
Map newValue,
String eventType)
throws Exception,
InvalidData,
UpdateNotAllowed,
Exception {
if (newValue == null) {
throw new Exception("Activity "
+ this + " - can't set context map which is null");
}
Map oldValues = new HashMap();
Map newChanged = new HashMap();
Iterator it = newValue.entrySet().iterator();
while (it.hasNext()) {
Map.Entry me = (Map.Entry) it.next();
String id = (String) me.getKey();
if (getContext(shandle).containsKey(id)) {
Object oldVal = getContext(shandle).get(id);
// type checking - throws an exception if type is invalid or can't be
// converted to a valid one
Object val = SharkUtilities.checkDataType(getProcessDefinition(shandle),
id,
oldVal,
me.getValue());
// System.out.println("var "+id+"["+oldVal+","+val+"]");
if ((oldVal != null && !oldVal.equals(val))
|| (oldVal == null && val != null)) {
oldValues.put(id, oldVal);
newChanged.put(id, val);
}
} else {
// System.err.println("The variable "+id+" is not in the context");
throw new UpdateNotAllowed("Activity "
+ this
+ " - context attribute "
+ id
+ " does not exist in the activity context - adding new attributes to activity context is not allowed");
}
}
if (newChanged.size() > 0
|| eventType.equals(SharkConstants.EVENT_ACTIVITY_RESULT_CHANGED)) {
getContext(shandle).putAll(newChanged);
Map toPersist = new HashMap(newChanged);
Map newSRVars = null;
if (eventType.equals(SharkConstants.EVENT_ACTIVITY_RESULT_CHANGED)) {
newSRVars = new HashMap();
Set oldRVIds = new HashSet(getResultVariableIds(shandle));
getResultVariableIds(shandle).addAll(newValue.keySet());
Set newRVIds = new HashSet(getResultVariableIds(shandle));
newRVIds.removeAll(oldRVIds);
Iterator itRV = newRVIds.iterator();
while (itRV.hasNext()) {
String id = (String) itRV.next();
Object val = getContext(shandle).get(id);
toPersist.put(id, val);
newSRVars.put(id, val);
}
}
variableIdsToPersist.addAll(toPersist.keySet());
persistActivityContext(shandle);
if (newChanged.size() > 0) {
if (SharkEngineManager.getInstance().getEventAuditManagers().size() > 0) {
boolean persistOldEventAuditData = new Boolean(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("PERSIST_OLD_EVENT_AUDIT_DATA", "true")).booleanValue();
if (!persistOldEventAuditData) {
oldValues = null;
}
SharkEngineManager.getInstance()
.getObjectFactory()
.createDataEventAuditWrapper(shandle,
this,
SharkConstants.EVENT_ACTIVITY_CONTEXT_CHANGED,
oldValues,
newChanged);
}
}
if (newSRVars != null && newSRVars.size() > 0) {
if (SharkEngineManager.getInstance().getEventAuditManagers().size() > 0) {
boolean persistOldEventAuditData = new Boolean(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("PERSIST_OLD_EVENT_AUDIT_DATA", "true")).booleanValue();
if (!persistOldEventAuditData) {
oldValues = null;
}
SharkEngineManager.getInstance()
.getObjectFactory()
.createDataEventAuditWrapper(shandle, this, eventType, null, newSRVars);
}
}
}
}
/**
* Resume this process or activity.
*/
public void resume(WMSessionHandle shandle)
throws Exception,
CannotResume,
NotSuspended {
checkReadOnly();
int type = getActivityDefinition(shandle).getActivityType();
// try {
if (!state(shandle).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
throw new NotSuspended("Activity "
+ this + " - can't resume activity that is not suspended");
}
if (process.state(shandle).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
throw new CannotResume("Activity "
+ this
+ " - can't resume activity which process is suspended");
}
if (blockActivityId != null
&& block_activity(shandle).state(shandle)
.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
throw new CannotResume("Activity "
+ this
+ " - can't resume activity which block is suspended");
}
try {
int[] es = execution_status(shandle);
if ((es[0] + es[1]) > 0
|| type == XPDLConstants.ACTIVITY_TYPE_BLOCK
|| type == XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
} else {
change_state(shandle, SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED);
}
} catch (Exception ex) {
throw new CannotResume(ex);
}
if (type == XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
// if this is a subflow activity, resume it's process
// if it is SYNCHRONOUS
if (isSubflowSynchronous) {
WfProcessInternal performer = getPerformer(shandle);
if (performer == null) {
SubFlow subflow = getActivityDefinition(shandle).getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
String refSbflw = subflow.getId();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle,
subflow,
refSbflw);
if (wp != null || performerId == null || performerId.equals("")) {
throw new Exception("Activity "
+ this
+ " - null performer of sync. subflow activity");
}
SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.resume(shandle,
performerId,
processId,
MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle)));
} else {
if (performer.state(shandle)
.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
performer.resume(shandle);
}
}
}
} else if (type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
List actActs = process.getAllActiveActivitiesForBlockActivity(shandle, key);
Iterator it = actActs.iterator();
while (it.hasNext()) {
WfActivityInternal act = (WfActivityInternal) it.next();
if (act.state(shandle)
.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
act.resume(shandle);
}
}
}
}
/**
* Suspend this process or activity.
*/
public void suspend(WMSessionHandle shandle)
throws Exception,
CannotSuspend,
NotRunning,
AlreadySuspended {
checkReadOnly();
if (state(shandle).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
throw new AlreadySuspended("Activity " + this + " is already suspended!");
}
if (state(shandle).startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
throw new CannotSuspend("Activity " + this + " is closed - can't suspend!");
}
try {
change_state(shandle, SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED);
} catch (Exception ex) {
throw new CannotSuspend(ex);
}
int type = getActivityDefinition(shandle).getActivityType();
if (type == XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
// if this is a subflow activity, suspend it's process
// if it is SYNCHRONOUS
if (isSubflowSynchronous) {
WfProcessInternal performer = getPerformer(shandle);
if (performer == null) {
SubFlow subflow = getActivityDefinition(shandle).getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
String refSbflw = subflow.getId();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle,
subflow,
refSbflw);
if (wp != null || performerId == null || performerId.equals("")) {
throw new Exception("Activity "
+ this
+ " - null performer of sync. subflow activity");
}
SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.suspend(shandle,
performerId,
processId,
MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle)));
} else {
String perfState = performer.state(shandle);
if (perfState.startsWith(SharkConstants.STATEPREFIX_OPEN)
&& !perfState.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
performer.suspend(shandle);
}
}
}
} else if (type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
List actActs = process.getAllActiveActivitiesForBlockActivity(shandle, key);
Iterator it = actActs.iterator();
while (it.hasNext()) {
WfActivityInternal act = (WfActivityInternal) it.next();
String actState = act.state(shandle);
if (actState.startsWith(SharkConstants.STATEPREFIX_OPEN)
&& !actState.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
act.suspend(shandle);
}
}
}
}
/**
* Terminate this process or activity.
*/
public void terminateFromProcess(WMSessionHandle shandle)
throws Exception,
CannotStop,
NotRunning {
checkReadOnly();
terminateActivity(shandle, true);
}
/**
* Terminate this process or activity.
*/
public void terminate(WMSessionHandle shandle)
throws Exception,
CannotStop,
NotRunning {
checkReadOnly();
terminateActivity(shandle, false);
}
protected void terminateActivity(WMSessionHandle shandle, boolean fromProcess)
throws Exception,
CannotStop,
NotRunning {
checkReadOnly();
String stateStr = SharkConstants.STATE_CLOSED_TERMINATED;
if (!state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
throw new CannotStop("Activity "
+ this
+ " - the activity is already in the closed state - can't terminate it!");
}
// remove assignments first, because method for getting assignments
// from database depends on activity's state
removeAssignments(shandle, true, true);
try {
change_state(shandle, stateStr);
} catch (Exception ex) {
throw new CannotStop(ex);
}
int type = getActivityDefinition(shandle).getActivityType();
if (type == XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
// if this is a subflow activity, terminate it's process
// if it is SYNCHRONOUS
if (isSubflowSynchronous) {
WfProcessInternal performer = getPerformer(shandle);
if (performer == null) {
SubFlow subflow = getActivityDefinition(shandle).getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
String refSbflw = subflow.getId();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle,
subflow,
refSbflw);
if (wp != null || performerId == null || performerId.equals("")) {
throw new Exception("Activity "
+ this
+ " - null performer of sync. subflow activity");
}
SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.terminate(shandle,
performerId,
processId,
MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle)));
} else {
if (performer.state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
performer.terminateFromActivity(shandle);
}
}
}
} else if (type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
List actActs = process.getAllActiveActivitiesForBlockActivity(shandle, key);
Iterator it = actActs.iterator();
while (it.hasNext()) {
WfActivityInternal act = (WfActivityInternal) it.next();
if (act.state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
act.terminateFromProcess(shandle);
}
}
}
if (!fromProcess) {
process.activity_terminate(shandle, this);
}
}
public void abortFromProcess(WMSessionHandle shandle)
throws Exception,
CannotStop,
NotRunning {
checkReadOnly();
abortActivity(shandle, true);
}
/**
* Abort the execution of this process or activity.
*/
public void abort(WMSessionHandle shandle) throws Exception, CannotStop, NotRunning {
checkReadOnly();
abortActivity(shandle, false);
}
protected void abortActivity(WMSessionHandle shandle, boolean fromProcess)
throws Exception,
CannotStop,
NotRunning {
checkReadOnly();
String stateStr = SharkConstants.STATE_CLOSED_ABORTED;
if (!state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
throw new CannotStop("Activity "
+ this
+ " - the activity is already in the closed state - can't abort it!");
}
// remove assignments first, because method for getting assignments
// from database depends on activity's state
removeAssignments(shandle, true, true);
try {
change_state(shandle, stateStr);
} catch (Exception ex) {
throw new CannotStop(ex);
}
int type = getActivityDefinition(shandle).getActivityType();
if (type == XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
// if this is a subflow activity, abort it's process
// if it is SYNCHRONOUS
if (isSubflowSynchronous) {
WfProcessInternal performer = getPerformer(shandle);
if (performer == null) {
SubFlow subflow = getActivityDefinition(shandle).getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
String refSbflw = subflow.getId();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle,
subflow,
refSbflw);
if (wp != null || performerId == null || performerId.equals("")) {
throw new Exception("Activity "
+ this
+ " - null performer of sync. subflow activity");
}
SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.abort(shandle,
performerId,
processId,
MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle)));
} else {
if (performer.state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
performer.abortFromActivity(shandle);
}
}
}
} else if (type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
List actActs = process.getAllActiveActivitiesForBlockActivity(shandle, key);
Iterator it = actActs.iterator();
while (it.hasNext()) {
WfActivityInternal act = (WfActivityInternal) it.next();
if (act.state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
act.abortFromProcess(shandle);
}
}
}
if (!fromProcess) {
process.activity_abort(shandle, this);
}
}
/**
* Receives notice of event status changes. This is called when some subflow process
* has finished its execution.
*/
public void receive_event(WMSessionHandle shandle,
WfEventAudit event,
WfProcessInternal performer)
throws Exception,
InvalidPerformer {
checkReadOnly();
// System.out.println("Act "+this+" receives event from process "+performer+",
// ms="+state);
Activity aDef = getActivityDefinition(shandle);
SubFlow subflow = aDef.getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
if (!isSubflowSynchronous)
return;
try {
if (performer != null) {
if (state(shandle).startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
return;
}
String perfState = performer.state(shandle);
if (perfState.startsWith(SharkConstants.STATEPREFIX_OPEN)) {
return;
}
if (perfState.equals(SharkConstants.STATE_CLOSED_COMPLETED)) {
// if
// (event.event_type().equals(SharkConstants.EVENT_PROCESS_STATE_CHANGED)
// &&
// The Ids of variables of result from the subflow process must be
// corrected to correspond to the actual param variables
// In the following map are only OUT and INOUT formal params of
// subflow process
Map rm = performer.result(shandle);
// This is a subflow activity, so it's context consists
// of actual parameters to be passed to the referenced
// process in exact order. The Ids of the passed values
// are not the same as the Ids used internally by the subprocess
// formal parameters, so we get appropriate ids by getting the
// process context param at the appropriate place which must be
// determined from matching activities actual parameter order
// with the subflow process formal parameter order
// Get actual parameters definition of the subflow activity
Iterator actualParameters = subflow.getActualParameters()
.toElements()
.iterator();
// make a list of actual parameter Ids
List originalIds = new ArrayList();
while (actualParameters.hasNext()) {
ActualParameter ap = (ActualParameter) actualParameters.next();
String apId = ap.toValue();
originalIds.add(apId);
}
Map updatedContext = new HashMap();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle,
performer.package_id(shandle),
performer.manager_version(shandle),
performer.process_definition_id(shandle));
Iterator it = rm.entrySet().iterator();
while (it.hasNext()) {
Map.Entry me = (Map.Entry) it.next();
String fpId = (String) me.getKey();
int index = 0;
int foundIndex = -1;
// find the index of formal parameter by searching for it's Id
Iterator fps = wp.getFormalParameters().toElements().iterator();
while (fps.hasNext()) {
FormalParameter fp = (FormalParameter) fps.next();
if (fpId.equals(fp.getId())) {
foundIndex = index;
break;
}
index++;
}
// if formal parameter is found, put the appropriate actual param
// name and formal param value into new context
if (foundIndex != -1) {
java.lang.Object apId = originalIds.get(foundIndex);
updatedContext.put(apId, me.getValue());
}
}
set_result(shandle, updatedContext);
finish(shandle);
} else {
change_state(shandle, perfState);
if (perfState.equals(SharkConstants.STATE_CLOSED_TERMINATED)) {
process.activity_terminate(shandle, this);
} else {
process.activity_abort(shandle, this);
}
}
} else {
if (performerId == null) {
throw new Exception("Activity "
+ this + " - this is not remote subflow activity!");
}
if (event instanceof WfDataEventAudit) {
WfDataEventAudit dea = (WfDataEventAudit) event;
Map res = dea.new_data();
// TODO: in the future, we'll need another call to wfxml API, to get
// info about variables to update
res = SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.parseOutParams(shandle,
processId,
MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle)),
res,
container(shandle).manager(shandle)
.context_signature(shandle));
set_result(shandle, res);
} else if (event instanceof org.enhydra.shark.api.client.wfmodel.WfStateEventAudit
&& ((org.enhydra.shark.api.client.wfmodel.WfStateEventAudit) event).new_state()
.startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
finish(shandle);
}
}
} catch (Exception ex) {
SharkEngineManager.getInstance()
.getCallbackUtilities()
.error(shandle,
"Activity"
+ toString()
+ " - problems when receiving finishing event of subprocess");
// System.err.println(ex.getMessage());
// ex.printStackTrace();
throw ex;
}
}
public String activity_set_definition_id(WMSessionHandle shandle) throws Exception {
return activitySetDefinitionId;
}
public String activity_definition_id(WMSessionHandle shandle) throws Exception {
return activityDefinitionId;
}
public String activity_definition_name(WMSessionHandle shandle) throws Exception {
return getActivityDefinition(shandle).getName();
}
public String block_activity_id(WMSessionHandle shandle) throws Exception {
return blockActivityId;
}
public WfActivityInternal block_activity(WMSessionHandle shandle) throws Exception {
if (blockActivity == null && blockActivityId != null) {
blockActivity = process.getActivity(shandle, blockActivityId);
}
return blockActivity;
}
public String manager_name(WMSessionHandle shandle) throws Exception {
return mgrName;
}
public String process_id(WMSessionHandle shandle) throws Exception {
return processId;
}
public int getDefinitionType(WMSessionHandle shandle) throws Exception {
int type = getActivityDefinition(shandle).getActivityType();
if (type == XPDLConstants.ACTIVITY_TYPE_TOOL) {
Participant p = findParticipant(shandle,
getActivityDefinition(shandle).getPerformer());
boolean isSystemParticipant = p != null
&& p.getParticipantType()
.equals((XPDLConstants.PARTICIPANT_TYPE_SYSTEM));
if (!isSystemParticipant) {
boolean isManualStart = getActivityDefinition(shandle).getActivityStartMode() == XPDLConstants.ACTIVITY_MODE_MANUAL;
if (isManualStart) {
type = 2 * type + 1;
} else {
boolean isManualFinish = getActivityDefinition(shandle).getActivityFinishMode() == XPDLConstants.ACTIVITY_MODE_MANUAL;
if (isManualFinish) {
type = 2 * type + 2;
}
}
}
}
return type;
}
/**
* Initializes the context of the given activity. Currently, it returns the whole
* process context for the activities which type is not Route or Block.
*/
protected void initializeActivityContext(WMSessionHandle shandle) throws Exception {
// must be linked map to preserve the exact order of parameters,
// which is important for subflow, and tool activities
int type = getActivityDefinition(shandle).getActivityType();
// set the needed process context to activity context
if (type != XPDLConstants.ACTIVITY_TYPE_ROUTE
&& type != XPDLConstants.ACTIVITY_TYPE_BLOCK) {
activitiesProcessContext = process.process_context(shandle);
}
contextInitialized = true;
}
// TODO: what to do with assignments that are already accepted???
public int reevaluateAssignments(WMSessionHandle shandle) throws Exception {
checkReadOnly();
if (!(state(shandle).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED) || state(shandle).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)))
return -1;
List arids = getAssignmentResourceIds(shandle);
PerformerData xpdlParticipant = findPerformerData(shandle);
if (xpdlParticipant == null)
return -1;
List users = findUsers(shandle, xpdlParticipant);
List toAdd = new ArrayList(users);
toAdd.removeAll(arids);
List toRemove = new ArrayList(arids);
toRemove.removeAll(users);
// removing old assignments
for (int i = 0; i < toRemove.size(); i++) {
String resUsername = (String) toRemove.get(i);
removeAssignment(shandle, resUsername, true, false);
}
createAssignments(shandle, toAdd);
if (toAdd.size() != 0 || toRemove.size() != 0) {
return 1;
}
return 0;
}
protected PerformerData findPerformerData(WMSessionHandle shandle) throws Exception {
boolean createAssignments = canCreateAssignments(shandle);
if (!createAssignments)
return null;
int type = getActivityDefinition(shandle).getActivityType();
if (!(type == XPDLConstants.ACTIVITY_TYPE_NO || type == XPDLConstants.ACTIVITY_TYPE_TOOL)) {
return null;
}
Participant p = findParticipant(shandle,
getActivityDefinition(shandle).getPerformer());
PerformerData xpdlParticipant = null;
xpdlParticipant = checkParticipant(shandle, p, type);
return xpdlParticipant;
}
protected List findUsers(WMSessionHandle shandle, PerformerData xpdlParticipant)
throws Exception {
if (xpdlParticipant == null)
return null;
List users = null;
AssignmentManager am = getAssignmentManager(shandle);
if (am != null) {
List xpdlResponsibleParticipants = new ArrayList();
List resps = XMLUtil.getResponsibles(getProcessDefinition(shandle));
Iterator it = resps.iterator();
int type = getActivityDefinition(shandle).getActivityType();
while (it.hasNext()) {
Responsible resp = (Responsible) it.next();
// if responsible is not unresolved expression, this will return Participant
// object
Participant p = findParticipant(shandle, resp.toValue());
PerformerData pd = checkParticipant(shandle, p, type);
if (pd != null) {
xpdlResponsibleParticipants.add(pd);
}
}
users = am.getAssignments(shandle,
processId,
key,
getResourceRequesterUsername(shandle),
xpdlParticipant,
xpdlResponsibleParticipants);
}
if (users == null) {
users = new ArrayList();
}
if (users.size() == 0) {
boolean createDefaultAssignment = createDefaultAssignment(shandle);
if (createDefaultAssignment) {
users.add(getResourceRequesterUsername(shandle));
}
}
SecurityManager sm = SharkEngineManager.getInstance().getSecurityManager();
if (sm != null) {
users = sm.getAssignments(shandle, processId, key, users);
if (users == null) {
users = new ArrayList();
}
}
return users;
}
protected void createAssignments(WMSessionHandle shandle, List users) throws Exception {
if (users == null || users.size() == 0)
return;
// optimization in the case of DODS persistence layer
int lrLimit = 5;
try {
lrLimit = Integer.parseInt(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("SharkKernel.LimitForRetrievingAllResourcesWhenCreatingAssignments",
"5"));
} catch (Exception ex) {
}
if (users.size() > lrLimit) {
SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.getAllResources(shandle);
}
Iterator resourcesIt = users.iterator();
while (resourcesIt.hasNext()) {
String username = (String) resourcesIt.next();
WfResourceInternal wr = SharkUtilities.getResource(shandle, username);
if (wr == null) {
wr = SharkEngineManager.getInstance()
.getObjectFactory()
.createResource(shandle, username);
}
WfAssignmentInternal ass = SharkEngineManager.getInstance()
.getObjectFactory()
.createAssignment(shandle, this, wr);
wr.addAssignment(shandle, ass);
getAssignmentResourceIds(shandle).add(username);
}
}
protected void createAssignments(WMSessionHandle shandle) throws Exception {
PerformerData xpdlParticipant = findPerformerData(shandle);
List users = findUsers(shandle, xpdlParticipant);
createAssignments(shandle, users);
}
protected PerformerData checkParticipant(WMSessionHandle shandle,
Participant p,
int activityType) throws Exception {
if (p != null) {
// check if participant is SYSTEM, and if it is, do not create PerformerData,
// which will indicate not to create any assignments
String participantType = p.getParticipantType().getType();
if (participantType.equals(XPDLConstants.PARTICIPANT_TYPE_SYSTEM)) {
return null;
}
String pDefId = null;
if (p.getParent().getParent() instanceof WorkflowProcess) {
pDefId = ((WorkflowProcess) p.getParent().getParent()).getId();
}
Package pkg = XMLUtil.getPackage(p);
return new PerformerData(pkg.getId(),
pkg.getInternalVersion(),
pDefId,
p.getId(),
false,
participantType);
}
String performerExpr = getActivityDefinition(shandle).getPerformer();
// check if this is a tool activity with an empty performer, and if it
// is, do not create PerformerData, which will indicate not to create any
// assignments
// if (performerExpr.trim().length()==0 &&
// activityType==XPDLConstants.ACTIVITY_TYPE_TOOL) {
// return null;
// }
try {
// if participant is an expression, calculate an expression
performerExpr = evaluateParticipantExpression(shandle, performerExpr);
} catch (Exception ex) {
}
Package pkg = XMLUtil.getPackage(getActivityDefinition(shandle));
return new PerformerData(pkg.getId(),
pkg.getInternalVersion(),
XMLUtil.getWorkflowProcess(getActivityDefinition(shandle))
.getId(),
performerExpr.trim(),
true,
null);
}
protected Participant findParticipant(WMSessionHandle shandle, String performerExpr)
throws Exception {
Participant p = SharkUtilities.getParticipant(shandle,
getActivityDefinition(shandle),
performerExpr);
if (p == null) {
try {
// if participant is an expression, calculate an expression, and
// try to retrieve the participant
if (performerExpr.trim().length() > 0) {
String participantId = evaluateParticipantExpression(shandle,
performerExpr);
p = SharkUtilities.getParticipant(shandle,
getActivityDefinition(shandle),
participantId);
return p;
}
} catch (Exception ex) {
}
}
return p;
}
// Starts or activates this automatic activity
protected void startActivity(WMSessionHandle shandle)
throws Exception,
CannotStart,
ToolAgentGeneralException {
// get the type of this activity
int type = getActivityDefinition(shandle).getActivityType();
// log.info("Executing activity " + activity.getId());
if (type != XPDLConstants.ACTIVITY_TYPE_NO
&& type != XPDLConstants.ACTIVITY_TYPE_TOOL) {
try {
change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
} catch (InvalidState is) {
throw new CannotStart("Activity "
+ this + " -> can't start: errMsg=" + is.getMessage());
} catch (TransitionNotAllowed tna) {
throw new CannotStart("Activity "
+ this + " -> can't start: errMsg=" + tna.getMessage());
} catch (Exception be) {
throw new CannotStart("Activity "
+ this + " -> can't start: errMsg=" + be.getMessage());
}
}
// configure the limit agent - this is handled in change_state
// this is not a point for all activities
// set the new previousActivity
// set the estimatedStartDate
switch (type) {
case XPDLConstants.ACTIVITY_TYPE_ROUTE: // Route
try {
this.finish(shandle); // ROUTE goes directly to complete status
} catch (CannotComplete cc) {
// System.err.println(cc.getMessage());
throw new CannotStart("Activity " + this + " -> can't start", cc);
}
break;
case XPDLConstants.ACTIVITY_TYPE_NO: // NoImplementation
this.runNo(shandle);
break;
case XPDLConstants.ACTIVITY_TYPE_TOOL: // Tools
if (getActivityDefinition(shandle).getActivityStartMode() == XPDLConstants.ACTIVITY_MODE_AUTOMATIC) {
boolean shouldFinishImmediatelly = getActivityDefinition(shandle).getActivityFinishMode() == XPDLConstants.ACTIVITY_MODE_AUTOMATIC;
this.runTool(shandle);
if (shouldFinishImmediatelly) {
finish(shandle);
} else {
String perf = getActivityDefinition(shandle).getPerformer();
Participant p = null;
boolean isSystemParPerfOrNoPerf = false;
if (!perf.equals("")) {
findParticipant(shandle, perf);
} else {
isSystemParPerfOrNoPerf = true;
}
if (p != null) {
String participantType = p.getParticipantType().getType();
if (participantType.equals(XPDLConstants.PARTICIPANT_TYPE_SYSTEM)) {
isSystemParPerfOrNoPerf = true;
}
}
if (isSystemParPerfOrNoPerf) {
removeAssignments(shandle, true, true);
} else {
change_state(shandle,
SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED);
this.runNo(shandle);
}
}
} else {
this.runNo(shandle);
}
break;
case XPDLConstants.ACTIVITY_TYPE_SUBFLOW: // SubFlow
startSubflowThread = Thread.currentThread();
this.runSubFlow(shandle); // Begin a sub workflow
startSubflowThread = null;
break;
case XPDLConstants.ACTIVITY_TYPE_BLOCK: // BlockActivity
this.runBlock(shandle); // Block activity
break;
}
}
protected void runNo(WMSessionHandle shandle) throws Exception, CannotStart {
createAssignments(shandle);
}
// Runs a TOOL activity - there can be 0..n
protected void runTool(WMSessionHandle shandle)
throws Exception,
CannotStart,
ToolAgentGeneralException {
if (!state(shandle).equals(SharkConstants.STATE_OPEN_RUNNING)) {
try {
change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
} catch (InvalidState is) {
throw new CannotStart("Activity "
+ this + " -> can't start: errMsg=" + is.getMessage());
} catch (TransitionNotAllowed tna) {
throw new CannotStart("Activity "
+ this + " -> can't start: errMsg=" + tna.getMessage());
} catch (Exception be) {
throw new CannotStart("Activity "
+ this + " -> can't start: errMsg=" + be.getMessage());
}
}
ToolActivityHandler tam = SharkEngineManager.getInstance().getToolActivityHandler();
tam.executeActivity(shandle, this);
}
// Runs a SUBFLOW activity
protected void runSubFlow(WMSessionHandle shandle)
throws Exception,
ToolAgentGeneralException {
SubFlow subflow = getActivityDefinition(shandle).getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
if (subflow == null) {
return;
}
// Get actual parameters definition of the subflow activity
ActualParameters aps = subflow.getActualParameters();
isSubflowSynchronous = getActivityDefinition(shandle).isSubflowSynchronous();
String refSbflw = subflow.getId();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle, subflow, refSbflw);
String packageId = process.package_id(shandle);
String packageVersion = process.manager_version(shandle);
if (wp != null) {
// start the process
WfProcessMgrInternal mgr;
WfProcessInternal subProc;
String sbflwPkgId;
String sbflwPkgVersion;
String sbflwProcId;
sbflwPkgId = XMLUtil.getPackage(wp).getId();
sbflwPkgVersion = XMLUtil.getPackage(wp).getInternalVersion();
sbflwProcId = refSbflw;
String pmgrName = MiscUtilities.createProcessMgrKey(sbflwPkgId,
sbflwPkgVersion,
sbflwProcId);
// System.out.println("SPIDWV="+sbflwPkgIdWithVersion+", PMGRN="+pmgrName);
mgr = SharkUtilities.getProcessMgr(shandle, pmgrName);
if (mgr == null) {
throw new Exception("Activity " + this + " - subflow process is not found");
}
try {
subProc = mgr.create_process(shandle, this);
subProc.set_name(shandle, process.name(shandle) + "-" + this.name(shandle));
} catch (Exception ex) {
SharkEngineManager.getInstance()
.getCallbackUtilities()
.error(shandle,
"Activity" + toString() + " - Error instantiating sub-process");
throw ex;
}
FormalParameters fps = SharkUtilities.getWorkflowProcess(shandle,
sbflwPkgId,
sbflwPkgVersion,
sbflwProcId)
.getFormalParameters();
Map m = null;
m = SharkUtilities.createContextMap(shandle,
processId,
key,
this.getContext(shandle),
aps,
fps,
packageId,
packageVersion);
subProc.set_process_context(shandle, m);
performerId = subProc.key(shandle);
persist(shandle);
subProc.start(shandle);
// this is a remote subflow
} else {
Map m = SharkUtilities.createContextMap(shandle,
processId,
key,
this.getContext(shandle),
aps,
packageId,
packageVersion);
String assId = MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle));
// check if some variable is used to define a reference to remote subflow
if (this.getContext(shandle).containsKey(refSbflw)) {
Object rsv = this.getContext(shandle).get(refSbflw);
if (rsv instanceof String) {
refSbflw = (String) rsv;
}
}
performerId = SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.start(shandle, refSbflw, processId, assId, isSubflowSynchronous, m);
persist(shandle);
}
// if this is asynchronous execution, complete activity, otherwise
// wait until the process calls the receive_event() method
if (!isSubflowSynchronous) {
this.finish(shandle);
}
}
// Runs a BLOCK activity
protected void runBlock(WMSessionHandle shandle) throws Exception {
}
/**
* Complete this activity.
*/
protected void finishImproperlyAndNotifyProcess(WMSessionHandle shandle, String excName)
throws Exception {
// remove assignments first, because method for getting assignments
// from database depends on activity's state
removeAssignments(shandle, true, true);
// The activity can already be terminated it is a sub-flow activity
if (!state.equals(SharkConstants.STATE_CLOSED_TERMINATED)) {
change_state(shandle, SharkConstants.STATE_CLOSED_TERMINATED);
}
this.exceptionName = excName;
if (exc == null && excName != null) {
int type = getActivityDefinition(shandle).getActivityType();
if (type == XPDLConstants.ACTIVITY_TYPE_SUBFLOW) {
// if this is a subflow activity, terminate it's process
// if it is SYNCHRONOUS
if (isSubflowSynchronous) {
WfProcessInternal performer = getPerformer(shandle);
if (performer == null) {
SubFlow subflow = getActivityDefinition(shandle).getActivityTypes()
.getImplementation()
.getImplementationTypes()
.getSubFlow();
String refSbflw = subflow.getId();
WorkflowProcess wp = SharkUtilities.getWorkflowProcess(shandle,
subflow,
refSbflw);
if (wp != null || performerId == null || performerId.equals("")) {
throw new Exception("Activity "
+ this
+ " - null performer of sync. subflow activity");
}
SharkEngineManager.getInstance()
.getWfEngineInteroperabilityMgr()
.abort(shandle,
performerId,
processId,
MiscUtilities.createAssignmentKey(key,
getResourceRequesterUsername(shandle)));
} else {
if (performer.state(shandle)
.startsWith(SharkConstants.STATEPREFIX_OPEN)) {
performer.terminateFromActivity(shandle);
}
}
}
} else if (type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
List actActs = process.getAllActiveActivitiesForBlockActivity(shandle, key);
Iterator it = actActs.iterator();
while (it.hasNext()) {
WfActivityInternal act = (WfActivityInternal) it.next();
act.terminateFromProcess(shandle);
}
}
}
process.activity_terminate(shandle, this);
}
public void set_accepted_status(WMSessionHandle shandle,
boolean accept,
String resourceUname)
throws Exception,
CannotAcceptSuspended {
checkReadOnly();
if (state(shandle).startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
throw new Exception("Activity "
+ this
+ " - can't change accepted status - activity state is closed"); // activity
// is
// closed
}
if (state(shandle).equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
throw new CannotAcceptSuspended("Activity "
+ this
+ " - can't accept or reject suspended activity"); // activity
// is
// suspended
}
boolean handleAAS = handleAllAssignments(shandle);
boolean accepted = state(shandle).equals(SharkConstants.STATE_OPEN_RUNNING);
if (accepted && accept && !handleAAS) {
throw new Exception("Activity "
+ this + " - someone else already accepted assignment!"); // activity
// is
// already
// accepted
}
if (SharkEngineManager.getInstance().getEventAuditManagers().size() > 0) {
WfResourceInternal res = SharkUtilities.getResource(shandle, resourceUname);
SharkEngineManager.getInstance()
.getObjectFactory()
.createAssignmentEventAuditWrapper(shandle, this, res, res, accept);
}
// accept
boolean deleteOtherAssignments = deleteOtherAssignments(shandle);
boolean createAssignments = canCreateAssignments(shandle);
if (accept) {
// the following must come before change_state where peristing happens
if (!accepted) {
acceptedTime = System.currentTimeMillis();
this.resourceUsername = resourceUname;
}
if (createAssignments) {
if (!handleAAS) {
removeAssignments(shandle, false, deleteOtherAssignments);
}
if (getAssignmentResourceIds(shandle).contains(resourceUname)) {
setAssignmentStatus(shandle, resourceUname, true, true);
WfResourceInternal res = SharkUtilities.getResourceFromCache(resourceUname);
if (res != null) {
res.restoreAssignment(shandle, mgrName, processId, key, true);
}
}
}
if (!accepted) {
change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
} else {
persist(shandle);
}
// reject
} else {
if (accepted) {
int es[] = execution_status(shandle);
if (createAssignments) {
setAssignmentStatus(shandle, resourceUname, true, false);
WfResourceInternal res = SharkUtilities.getResourceFromCache(resourceUname);
if (res != null) {
res.restoreAssignment(shandle, mgrName, processId, key, false);
}
}
if (!handleAAS || (es[0] + es[1]) <= 1) {
// put activity into not_started status
change_state(shandle, SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED);
this.acceptedTime = SharkConstants.UNDEFINED_TIME;
this.resourceUsername = null;
accepted = false;
}
if (!handleAAS) {
if (createAssignments && !deleteOtherAssignments) {
Iterator it = getAssignmentResourceIds(shandle).iterator();
while (it.hasNext()) {
String resUsername = (String) it.next();
if (resUsername.equals(resourceUname))
continue;
setAssignmentStatus(shandle, resUsername, true, false);
WfResourceInternal res = SharkUtilities.getResourceFromCache(resUsername);
if (res != null) {
res.restoreAssignment(shandle, mgrName, processId, key, false);
}
}
}
}
persist(shandle);
if (!handleAAS && createAssignments && deleteOtherAssignments) {
reevaluateAssignments(shandle);
}
}
}
}
public String getResourceUsername(WMSessionHandle shandle) throws Exception {
return resourceUsername;
}
protected Activity getActivityDefinition(WMSessionHandle shandle) throws Exception {
if (activityDefinition == null) {
activityDefinition = SharkUtilities.getActivityDefinition(shandle,
this,
getProcessDefinition(shandle));
}
return activityDefinition;
}
protected WorkflowProcess getProcessDefinition(WMSessionHandle shandle)
throws Exception {
if (processDefinition == null) {
String packageId = process.package_id(shandle);
String packageVer = process.manager_version(shandle);
String pDefId = process.process_definition_id(shandle);
processDefinition = SharkUtilities.getWorkflowProcess(shandle,
packageId,
packageVer,
pDefId);
}
return processDefinition;
}
public String toString() {
return "[Process Id="
+ processId + ", Id=" + key + ", ba=" + blockActivityId + ", ActDefId="
+ activityDefinitionId + "]";
}
protected synchronized void setActivityVariables(WMSessionHandle shandle)
throws Exception {
if (contextInitialized) {
return;
}
// System.out.println("SPVCVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");
// initialize context, just to keep the order of variables
// initializeActivityContext(t);
resultVariableIds = new HashSet();
int type = getActivityDefinition(shandle).getActivityType();
// ROUTE AND BLOCK Activities do not have a context
if (type == XPDLConstants.ACTIVITY_TYPE_ROUTE
|| type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
return;
}
WorkflowProcess wp = getProcessDefinition(shandle);
List l = new ArrayList(wp.getAllVariables().values());
if (l.size() == 0)
return;
PersistentManagerInterface ipm = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
// System.err.println("INIT PC="+processContext);
Iterator it = l.iterator();
List variableIds = new ArrayList();
while (it.hasNext()) {
XMLCollectionElement dfOrFp = (XMLCollectionElement) it.next();
String vdId = dfOrFp.getId();
variableIds.add(vdId);
}
l = ipm.getActivityVariables(shandle, processId, key, variableIds);
it = l.iterator();
while (it.hasNext()) {
ActivityVariablePersistenceObject var = (ActivityVariablePersistenceObject) it.next();
String vdId = var.getDefinitionId();
Object val = var.getValue();
// System.out.println("Restoring act var "+vdId+", val="+val);
// if (anyVal!=null) {
activitiesProcessContext.put(vdId, val);
if (var.isResultVariable()) {
resultVariableIds.add(vdId);
}
//
}
contextInitialized = true;
// System.err.println("REFILLED AC="+activitiesProcessContext);
}
/**
* It is assumed that there can't be two or more activities having the same key.
*/
public boolean equals(java.lang.Object obj) {
if (!(obj instanceof WfActivityImpl))
return false;
return ((WfActivityImpl) obj).key.equals(key);
}
public int hashCode() {
return key.hashCode();
}
protected String evaluateParticipantExpression(WMSessionHandle shandle, String expr)
throws Exception {
if (expr == null || expr.trim().length() == 0)
throw new Exception("Activity " + this + " - improper participant expression!");
// use process_context - these are cloned variables
return evaluator(shandle).evaluateExpression(shandle,
processId,
key,
expr.trim(),
process_context(shandle),
java.lang.String.class).toString();
}
protected Evaluator evaluator(WMSessionHandle shandle) throws Exception {
if (evaluator == null) {
evaluator = SharkEngineManager.getInstance()
.getScriptingManager()
.getEvaluator(shandle,
SharkUtilities.getScriptType(shandle,
process.package_id(shandle),
process.manager_version(shandle)));
}
return evaluator;
}
protected WfProcessInternal getPerformer(WMSessionHandle shandle) throws Exception {
if (performerId != null) {
return SharkUtilities.getProcess(shandle, performerId, SharkUtilities.WRITE_MODE);
}
return null;
}
public String getResourceRequesterUsername(WMSessionHandle shandle) throws Exception {
return process.requester(shandle).getResourceRequesterUsername(shandle);
}
public WfRequester getExternalRequester(WMSessionHandle shandle) throws Exception {
return null;
}
public void setExternalRequester(WMSessionHandle shandle, WfRequester extReq)
throws Exception {
return;
}
protected int[] execution_status(WMSessionHandle shandle) throws Exception {
List l = SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.getAllAssignmentsForActivity(shandle, processId, key);
int[] hm = {
0, 0, 0
};
for (int i = 0; i < l.size(); i++) {
AssignmentPersistenceObject po = (AssignmentPersistenceObject) l.get(i);
if (!po.isValid()) {
hm[0]++;
} else if (po.isAccepted()) {
hm[1]++;
} else {
hm[2]++;
}
}
return hm;
}
public void persist(WMSessionHandle shandle) throws Exception {
// System.err.println("The act "+this+" is being persisted with thread
// "+Thread.currentThread());
// System.err.println(" The act "+key+" is being persisted:");
PersistentManagerInterface pmi = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
pmi.persist(shandle, createAndFillPersistentObject(), this.justCreated);
// persistActivityContext(t);
this.justCreated = false;
// delete assignments if needed
/*
* if (deleteAssignments) { Iterator aRes=getAssignmentResourceIds(t).iterator();
* while (aRes.hasNext()) { String resKey=(String)aRes.next();
* //System.err.println(" The act "+key+" is deleting its assignment for resource
* "+resKey); pmi.deleteAssignment(key,resKey,t.getSharkTransaction()); }
* deleteAssignments=false; }
*/
/*
* if (deadlinesInfo!=null && deadlinesInfo.size()>0) { persistDeadlines(t); }
*/
}
/**
* Method persistActivityContext stores content of the workflow relevant data of this
* activity, either all of them, or modified only.
*
* @exception Exception
*/
protected void persistActivityContext(WMSessionHandle shandle) throws Exception {
if (variableIdsToPersist.size() == 0)
return;
PersistentManagerInterface pmgr = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
// System.out.println("Persisting act var map="+getContext(t));
Iterator it = getContext(shandle).entrySet().iterator();
while (it.hasNext()) {
Map.Entry me = (Map.Entry) it.next();
String defId = (String) me.getKey();
// boolean modifiedOnly = (null != modified);
// if (!modifiedOnly||(modifiedOnly && modified.contains(defId))) {
if (variableIdsToPersist.contains(defId)) {
Object val = me.getValue();
ActivityVariablePersistenceObject var = new ActivityVariablePersistenceObject();
var.setProcessId(processId);
var.setActivityId(key);
var.setDefinitionId(defId);
var.setValue(val);
var.setResultVariable(getResultVariableIds(shandle).contains(defId));
pmgr.persist(shandle, var, this.justCreatedVariables);
// System.out.println("Persisting activity variable "+defId+", val="+val+"
// for activity "+key+" of process "+processId);
}
}
variableIdsToPersist.clear();
this.justCreatedVariables = false;
}
protected void persistDeadlines(WMSessionHandle shandle) throws Exception {
if (deadlinesInfo == null || deadlinesInfo.size() == 0)
return;
PersistentManagerInterface pmgr = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
Iterator it = deadlinesInfo.iterator();
while (it.hasNext()) {
DeadlineInfo dinfo = (DeadlineInfo) it.next();
DeadlinePersistenceObject dpi = new DeadlinePersistenceObject();
dpi.setProcessId(processId);
dpi.setActivityId(key);
dpi.setExceptionName(dinfo.exceptionName);
dpi.setSynchronous(dinfo.isSynchronous);
dpi.setTimeLimit(dinfo.timeLimit);
pmgr.persist(shandle, dpi, justCreatedDeadlines);
}
deadlinesInfo.clear();
this.justCreatedDeadlines = false;
}
protected void persistExecutedDeadline(WMSessionHandle shandle, String uniqueId)
throws Exception {
PersistentManagerInterface pmgr = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
DeadlinePersistenceObject dpi = new DeadlinePersistenceObject();
dpi.setProcessId(processId);
dpi.setActivityId(key);
dpi.setUniqueId(uniqueId);
dpi.setExecuted(true);
pmgr.persist(shandle, dpi, false);
}
public void delete(WMSessionHandle shandle) throws Exception {
// try {System.err.println("Deleting activity "+key());}catch (Exception ex){};
SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.deleteActivity(shandle, processId, key);
}
protected XMLCollectionElement getXPDLObject(WMSessionHandle shandle) throws Exception {
return getActivityDefinition(shandle);
}
public Map getContext(WMSessionHandle shandle) throws Exception {
if (!contextInitialized) {
setActivityVariables(shandle);
}
return activitiesProcessContext;
}
protected Set getResultVariableIds(WMSessionHandle shandle) throws Exception {
if (resultVariableIds == null) {
setActivityVariables(shandle);
}
return resultVariableIds;
}
protected ActivityPersistenceObject createAndFillPersistentObject() {
ActivityPersistenceObject po = new ActivityPersistenceObject();
fillPersistentObject(po);
return po;
}
protected void fillPersistentObject(ActivityPersistenceObject po) {
po.setId(this.key);
po.setActivitySetDefinitionId(this.activitySetDefinitionId);
po.setActivityDefinitionId(this.activityDefinitionId);
po.setProcessMgrName(this.mgrName);
po.setProcessId(this.processId);
po.setResourceUsername(this.resourceUsername);
po.setSubflowProcessId(this.performerId);
po.setSubflowAsynchronous(!this.isSubflowSynchronous);
po.setState(this.state);
po.setBlockActivityId(this.blockActivityId);
po.setName(this.name);
po.setDescription(this.description);
po.setPriority(this.priority);
po.setAcceptedTime(this.acceptedTime);
po.setActivatedTime(this.activatedTime);
po.setLastStateTime(this.lastStateTime);
po.setLimitTime(limitTime);
}
protected void restore(ActivityPersistenceObject po) {
this.key = po.getId();
this.activitySetDefinitionId = po.getActivitySetDefinitionId();
this.activityDefinitionId = po.getActivityDefinitionId();
this.mgrName = po.getProcessMgrName();
this.processId = po.getProcessId();
this.resourceUsername = po.getResourceUsername();
this.performerId = po.getSubflowProcessId();
this.isSubflowSynchronous = !po.isSubflowAsynchronous();
this.state = po.getState();
this.blockActivityId = po.getBlockActivityId();
this.name = po.getName();
this.description = po.getDescription();
this.priority = po.getPriority();
this.acceptedTime = po.getAcceptedTime();
this.activatedTime = po.getActivatedTime();
this.lastStateTime = po.getLastStateTime();
this.limitTime = po.getLimitTime();
}
public String getPerformerId(WMSessionHandle shandle) {
return performerId;
}
public boolean isPerformerSynchronous(WMSessionHandle shandle) {
return isSubflowSynchronous;
}
public long getCreationTime(WMSessionHandle shandle) throws Exception {
return activatedTime;
}
public long getStartTime(WMSessionHandle shandle) throws Exception {
return acceptedTime;
}
public synchronized void updateAssignmentResourceIds(WMSessionHandle shandle,
String oldResUname,
String newResUname)
throws Exception {
checkReadOnly();
if (assignmentResourceIds != null) {
assignmentResourceIds.remove(oldResUname);
if (!assignmentResourceIds.contains(newResUname)) {
assignmentResourceIds.add(newResUname);
}
}
if (this.resourceUsername != null && this.resourceUsername.equals(oldResUname)) {
this.resourceUsername = newResUname;
persist(shandle);
}
}
protected synchronized void removeAssignments(WMSessionHandle shandle,
boolean removeActiveOne,
boolean deleteOtherAssignments)
throws Exception {
int actType = getActivityDefinition(shandle).getActivityType();
if (actType == XPDLConstants.ACTIVITY_TYPE_BLOCK
|| actType == XPDLConstants.ACTIVITY_TYPE_ROUTE
|| actType == XPDLConstants.ACTIVITY_TYPE_SUBFLOW)
return;
boolean createAssignments = canCreateAssignments(shandle);
if (!createAssignments)
return;
Iterator itAss = new ArrayList(getAssignmentResourceIds(shandle)).iterator();
while (itAss.hasNext()) {
String resUsername = (String) itAss.next();
if (!removeActiveOne && resUsername.equals(resourceUsername))
continue;
removeAssignment(shandle, resUsername, deleteOtherAssignments, false);
}
}
protected void removeAssignment(WMSessionHandle shandle,
String resUsername,
boolean delete,
boolean assStat) throws Exception {
PersistentManagerInterface pmi = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
WfResourceInternal res = SharkUtilities.getResourceFromCache(resUsername);
if (delete) {
pmi.deleteAssignment(shandle, processId, key, resUsername);
getAssignmentResourceIds(shandle).remove(resUsername);
} else {
setAssignmentStatus(shandle, resUsername, false, assStat);
}
if (res != null) {
res.removeAssignment(shandle, processId, key);
}
}
protected void setAssignmentStatus(WMSessionHandle shandle,
String resUsername,
boolean isValid,
boolean isAccepted) throws Exception {
PersistentManagerInterface pmi = SharkEngineManager.getInstance()
.getInstancePersistenceManager();
AssignmentPersistenceObject asspo = new AssignmentPersistenceObject();
asspo.setProcessMgrName(mgrName);
asspo.setProcessId(processId);
asspo.setActivityId(key);
asspo.setResourceUsername(resUsername);
asspo.setValid(isValid);
asspo.setAccepted(isAccepted);
pmi.persist(shandle, asspo, false);
// System.out.println("PA "+asspo.getActivityId()+",
// "+asspo.getResourceUsername()+", a="+asspo.isAccepted()+",
// v="+asspo.isValid());
}
public List getDeadlineInfo(WMSessionHandle shandle) throws Exception {
List ret = null;
List pDeadlines = null;
pDeadlines = SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.getAllDeadlinesForActivity(shandle, this.processId, this.key);
Collections.sort(pDeadlines, new DeadlineComparator());
if (pDeadlines == null || pDeadlines.size() == 0)
return new ArrayList();
if (!performDeadlineReevaluation()) {
ret = new ArrayList();
for (Iterator iter = pDeadlines.iterator(); iter.hasNext();) {
DeadlinePersistenceObject dpo = (DeadlinePersistenceObject) iter.next();
DeadlineInfo info = new DeadlineInfo(processId,
key,
dpo.isExecuted(),
dpo.getTimeLimit(),
dpo.getExceptionName(),
dpo.isSynchronous());
ret.add(info);
}
} else {
ret = new ArrayList(reevaluateDeadlines(shandle));
for (int i = 0; i < ret.size(); i++) {
DeadlineInfo di = (DeadlineInfo) ret.get(i);
DeadlinePersistenceObject dpo = (DeadlinePersistenceObject) pDeadlines.get(i);
di.isExecuted = dpo.isExecuted();
}
}
return ret;
}
public boolean checkDeadlines(WMSessionHandle shandle,
long timeLimitBoundary,
Map actsToAsyncExcNames) throws Exception {
checkReadOnly();
String syncDeadlineExcName = null;
List brokenDeadlines = null;
List excNames = new ArrayList();
if (performDeadlineReevaluation()) {
List pDeadlines = null;
pDeadlines = SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.getAllDeadlinesForActivity(shandle, this.processId, this.key);
Collections.sort(pDeadlines, new DeadlineComparator());
reevaluateDeadlines(shandle);
brokenDeadlines = new ArrayList();
for (int i = 0; i < pDeadlines.size(); i++) {
DeadlineInfo di = (DeadlineInfo) deadlinesInfo.get(i);
DeadlinePersistenceObject dpo = (DeadlinePersistenceObject) pDeadlines.get(i);
if (di.timeLimit < timeLimitBoundary) {
dpo.setTimeLimit(di.timeLimit);
brokenDeadlines.add(dpo);
}
}
deadlinesInfo.clear();
} else {
brokenDeadlines = SharkEngineManager.getInstance()
.getInstancePersistenceManager()
.getAllDeadlinesForActivity(shandle,
this.processId,
this.key,
timeLimitBoundary);
}
if (brokenDeadlines != null && brokenDeadlines.size() > 0) {
boolean raiseAsyncDeadlineOnce = new Boolean(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("Deadlines.raiseAsyncDeadlineOnlyOnce", "true")).booleanValue();
for (int i = 0; i < brokenDeadlines.size(); i++) {
DeadlinePersistenceObject dpi = (DeadlinePersistenceObject) brokenDeadlines.get(i);
if (dpi.isExecuted() && raiseAsyncDeadlineOnce) {
continue;
}
persistExecutedDeadline(shandle, dpi.getUniqueId());
String excName = dpi.getExceptionName();
if (dpi.isSynchronous()) {
syncDeadlineExcName = excName;
break;
}
if (!excNames.contains(excName)) {
excNames.add(excName);
}
}
}
if (syncDeadlineExcName != null) {
finishImproperlyAndNotifyProcess(shandle, syncDeadlineExcName);
} else {
if (excNames.size() > 0) {
actsToAsyncExcNames.put(this, excNames);
}
int type = getActivityDefinition(shandle).getActivityType();
// if this is block activity, handle its content deadlines
if (type == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
List actActs = process.getAllActiveActivitiesForBlockActivity(shandle, key);
Iterator it = actActs.iterator();
while (it.hasNext()) {
Map ataens = new HashMap();
WfActivityInternal act = (WfActivityInternal) it.next();
boolean syncDeadlineHappened = act.checkDeadlines(shandle,
timeLimitBoundary,
ataens);
if (syncDeadlineHappened) {
continue;
}
if (ataens.size() > 0) {
actsToAsyncExcNames.putAll(ataens);
}
}
}
}
return (syncDeadlineExcName != null);
}
protected List reevaluateDeadlines(WMSessionHandle shandle) throws Exception {
Iterator dls = getActivityDefinition(shandle).getDeadlines()
.toElements()
.iterator();
deadlinesInfo = new ArrayList();
while (dls.hasNext()) {
Deadline dl = (Deadline) dls.next();
String dc = dl.getDeadlineCondition();
String en = dl.getExceptionName();
boolean isSynchronous = dl.getExecution().equals(XPDLConstants.EXECUTION_SYNCHR);
Map context = null;
String useProcessContextStr = SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("Deadlines.useProcessContext", "false");
if (Boolean.valueOf(useProcessContextStr).booleanValue()) {
context = this.process.process_context(shandle);
} else {
context = this.process_context(shandle);
}
context.put(SharkConstants.PROCESS_STARTED_TIME,
new java.util.Date(process.getStartTime(shandle)));
context.put(SharkConstants.ACTIVITY_ACCEPTED_TIME,
new java.util.Date(this.acceptedTime));
context.put(SharkConstants.ACTIVITY_ACTIVATED_TIME,
new java.util.Date(this.activatedTime));
long timeLimit = ((java.util.Date) evaluator(shandle).evaluateExpression(shandle,
processId,
key,
dc,
context,
java.util.Date.class)).getTime();
DeadlineInfo dinfo = new DeadlineInfo(processId,
key,
false,
timeLimit,
en,
isSynchronous);
deadlinesInfo.add(dinfo);
// System.out.println("Act "+this+" re-evaluated deadline "+dinfo);
}
return deadlinesInfo;
}
public Exception getException(WMSessionHandle shandle) {
return exc;
}
public void setException(WMSessionHandle shandle, Exception tage) {
this.exc = tage;
}
public String getExceptionName(WMSessionHandle shandle) {
return exceptionName;
}
public void setExceptionName(WMSessionHandle shandle, String excName) {
this.exceptionName = excName;
}
protected boolean performDeadlineReevaluation() {
String reevalStr = SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("Deadlines.reevaluateDeadlines", "true");
return Boolean.valueOf(reevalStr).booleanValue();
}
static class DeadlineComparator implements Comparator {
public int compare(Object o1, Object o2) {
DeadlinePersistenceObject dd1 = (DeadlinePersistenceObject) o1;
DeadlinePersistenceObject dd2 = (DeadlinePersistenceObject) o2;
String ui1 = dd1.getUniqueId();
String ui2 = dd2.getUniqueId();
return ui1.compareTo(ui2);
}
}
public WfActivityInternal duplicate(WfProcessInternal proc) throws Exception {
WfActivityImpl actImpl = (WfActivityImpl) SharkEngineManager.getInstance()
.getObjectFactory()
.createActivity(createAndFillPersistentObject(), proc);
actImpl.lastStateEventAudit = this.lastStateEventAudit;
actImpl.evaluator = this.evaluator;
actImpl.activityDefinition = this.activityDefinition;
actImpl.processDefinition = this.processDefinition;
actImpl.startSubflowThread = this.startSubflowThread;
if (this.contextInitialized) {
try {
actImpl.activitiesProcessContext = this.duplicateContext(activitiesProcessContext);
actImpl.resultVariableIds = new HashSet(this.resultVariableIds);
actImpl.contextInitialized = true;
} catch (Exception ex) {
}
}
return actImpl;
}
protected void checkReadOnly() throws Exception {
if (process.isReadOnly()) {
throw new Exception("Activity " + this + " is read-only!");
}
}
protected boolean canCreateAssignments(WMSessionHandle shandle) throws Exception {
boolean createAssignments = Boolean.valueOf(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("SharkKernel.createAssignments", "true")).booleanValue();
return createAssignments;
}
protected boolean createDefaultAssignment(WMSessionHandle shandle) throws Exception {
boolean createDefaultAssignment = Boolean.valueOf(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("SharkKernel.createDefaultAssignment", "true")).booleanValue();
return createDefaultAssignment;
}
protected boolean deleteOtherAssignments(WMSessionHandle shandle) throws Exception {
return Boolean.valueOf(SharkEngineManager.getInstance()
.getCallbackUtilities()
.getProperty("SharkKernel.deleteOtherAssignments", "true")).booleanValue();
}
protected AssignmentManager getAssignmentManager(WMSessionHandle shandle)
throws Exception {
return SharkEngineManager.getInstance().getAssignmentManager();
}
protected boolean handleAllAssignments(WMSessionHandle shandle) throws Exception {
return false;
}
}
|