0001: package org.enhydra.shark;
0002:
0003: import java.util.ArrayList;
0004: import java.util.Collection;
0005: import java.util.HashMap;
0006: import java.util.HashSet;
0007: import java.util.Iterator;
0008: import java.util.List;
0009: import java.util.Map;
0010: import java.util.Set;
0011:
0012: import org.enhydra.shark.api.RootException;
0013: import org.enhydra.shark.api.client.wfmc.wapi.WMSessionHandle;
0014: import org.enhydra.shark.api.client.wfmodel.AlreadyRunning;
0015: import org.enhydra.shark.api.client.wfmodel.AlreadySuspended;
0016: import org.enhydra.shark.api.client.wfmodel.CannotResume;
0017: import org.enhydra.shark.api.client.wfmodel.CannotStart;
0018: import org.enhydra.shark.api.client.wfmodel.CannotStop;
0019: import org.enhydra.shark.api.client.wfmodel.CannotSuspend;
0020: import org.enhydra.shark.api.client.wfmodel.InvalidData;
0021: import org.enhydra.shark.api.client.wfmodel.InvalidState;
0022: import org.enhydra.shark.api.client.wfmodel.NotRunning;
0023: import org.enhydra.shark.api.client.wfmodel.NotSuspended;
0024: import org.enhydra.shark.api.client.wfmodel.ResultNotAvailable;
0025: import org.enhydra.shark.api.client.wfmodel.TransitionNotAllowed;
0026: import org.enhydra.shark.api.client.wfmodel.UpdateNotAllowed;
0027: import org.enhydra.shark.api.client.wfmodel.WfCreateProcessEventAudit;
0028: import org.enhydra.shark.api.client.wfmodel.WfDataEventAudit;
0029: import org.enhydra.shark.api.client.wfmodel.WfEventAudit;
0030: import org.enhydra.shark.api.client.wfmodel.WfRequester;
0031: import org.enhydra.shark.api.client.wfmodel.WfStateEventAudit;
0032: import org.enhydra.shark.api.common.SharkConstants;
0033: import org.enhydra.shark.api.internal.instancepersistence.AndJoinEntryPersitenceObject;
0034: import org.enhydra.shark.api.internal.instancepersistence.PersistentManagerInterface;
0035: import org.enhydra.shark.api.internal.instancepersistence.ProcessPersistenceObject;
0036: import org.enhydra.shark.api.internal.instancepersistence.ProcessVariablePersistenceObject;
0037: import org.enhydra.shark.api.internal.scripting.Evaluator;
0038: import org.enhydra.shark.api.internal.toolagent.ToolAgentGeneralException;
0039: import org.enhydra.shark.api.internal.working.TxSynchronization;
0040: import org.enhydra.shark.api.internal.working.WfActivityInternal;
0041: import org.enhydra.shark.api.internal.working.WfProcessInternal;
0042: import org.enhydra.shark.api.internal.working.WfProcessMgrInternal;
0043: import org.enhydra.shark.api.internal.working.WfRequesterInternal;
0044: import org.enhydra.shark.utilities.MiscUtilities;
0045: import org.enhydra.shark.xpdl.XMLCollectionElement;
0046: import org.enhydra.shark.xpdl.XMLUtil;
0047: import org.enhydra.shark.xpdl.XPDLConstants;
0048: import org.enhydra.shark.xpdl.elements.Activity;
0049: import org.enhydra.shark.xpdl.elements.ActivitySet;
0050: import org.enhydra.shark.xpdl.elements.BlockActivity;
0051: import org.enhydra.shark.xpdl.elements.Condition;
0052: import org.enhydra.shark.xpdl.elements.ProcessHeader;
0053: import org.enhydra.shark.xpdl.elements.Transition;
0054: import org.enhydra.shark.xpdl.elements.WorkflowProcess;
0055:
0056: /**
0057: * WfProcessImpl - Workflow Process Object implementation
0058: *
0059: * @author Sasa Bojanic, Vladimir Puskas
0060: * @version 1.0.1
0061: */
0062: public class WfProcessImpl extends WfExecutionObjectImpl implements
0063: WfProcessInternal {
0064:
0065: protected String actRequesterId;
0066:
0067: protected String actRequestersProcessId;
0068:
0069: protected String resRequesterId;
0070:
0071: protected String managerName;
0072:
0073: protected String pkgId;
0074:
0075: protected String pDefId;
0076:
0077: protected String mgrVer;
0078:
0079: protected Map processContext = new HashMap();
0080:
0081: protected boolean contextInitialized = false;
0082:
0083: // condition evaluation
0084: protected Evaluator evaluator;
0085:
0086: protected List lastFinishedActivities = new ArrayList();
0087:
0088: protected WfProcessMgrInternal manager;
0089:
0090: protected ActivityCache activityCache;
0091:
0092: protected boolean isRunning = false;
0093:
0094: protected long creationTime = SharkConstants.UNDEFINED_TIME;
0095:
0096: protected long startTime = SharkConstants.UNDEFINED_TIME;
0097:
0098: protected WorkflowProcess xpdlProcess;
0099:
0100: protected Set variableIdsToPersist = new HashSet();
0101:
0102: protected Map activityToFollowedTransitions = new HashMap();
0103:
0104: protected Map newActivityToFollowedTransitions = new HashMap();
0105:
0106: protected TxSynchronization initialTransaction;
0107:
0108: protected Thread startingThread = null;
0109:
0110: protected WfActivityInternal actRequester;
0111:
0112: protected boolean terminateOrAbortFromActivity = false;
0113:
0114: protected String externalRequesterClassName = null;
0115:
0116: protected boolean justCreated = false;
0117:
0118: protected boolean justCreatedVariables = false;
0119:
0120: protected boolean isReadOnly = true;
0121:
0122: /**
0123: * Creates new WfProcessImpl
0124: *
0125: * @param manager a WfProcessMgrInternal
0126: * @param requester a WfRequester
0127: * @param key a String
0128: * @exception Exception
0129: */
0130: protected WfProcessImpl(WMSessionHandle shandle,
0131: WfProcessMgrInternal manager,
0132: WfRequesterInternal requester, String key) throws Exception {
0133: this .key = key;
0134: this .manager = manager;
0135: this .managerName = manager.name(shandle);
0136: this .justCreated = true;
0137: this .justCreatedVariables = true;
0138: this .isReadOnly = false;
0139: this .activityCache = new ActivityCache(this , true);
0140:
0141: setXPDLAttribs();
0142: if (requester != null
0143: && requester.getExternalRequester(shandle) != null) {
0144: this .externalRequesterClassName = requester
0145: .getExternalRequester(shandle).getClass().getName();
0146: }
0147: if (requester != null
0148: && requester instanceof WfActivityInternal) {
0149: this .actRequesterId = ((WfActivityInternal) requester)
0150: .key(shandle);
0151: this .actRequestersProcessId = ((WfActivityInternal) requester)
0152: .process_id(shandle);
0153: this .actRequester = (WfActivityInternal) requester;
0154: this .resRequesterId = this .actRequester
0155: .getResourceRequesterUsername(shandle);
0156:
0157: this .initialTransaction = SharkUtilities
0158: .getTxSynchronization();
0159: } else if (requester != null
0160: && requester instanceof WfDefaultRequester) {
0161: this .resRequesterId = ((WfDefaultRequester) requester)
0162: .getResourceRequesterUsername(shandle);
0163: }
0164:
0165: name = getProcessDefinition(shandle).getName();
0166: if (name.equals("")) {
0167: name = pDefId;
0168: }
0169: ProcessHeader ph = ((WorkflowProcess) getXPDLObject(shandle))
0170: .getProcessHeader();
0171: description = ph.getDescription();
0172:
0173: if (description != null && description.length() > 254) {
0174: description = description.substring(0, 253);
0175: }
0176:
0177: try {
0178: priority = Integer.valueOf(ph.getPriority()).shortValue();
0179: boolean allowOutOfRangePriority = Boolean
0180: .valueOf(
0181: SharkEngineManager
0182: .getInstance()
0183: .getCallbackUtilities()
0184: .getProperty(
0185: "SharkKernel.allowOutOfRangePriority",
0186: "false")).booleanValue();
0187: if (!allowOutOfRangePriority && priority < 1)
0188: priority = 1;
0189: if (!allowOutOfRangePriority && priority > 5)
0190: priority = 5;
0191: } catch (Exception ex) {
0192: priority = 3;
0193: }
0194:
0195: lastStateTime = System.currentTimeMillis();
0196: creationTime = lastStateTime;
0197:
0198: initializeProcessContext(shandle);
0199:
0200: if (getContext(shandle).size() > 0) {
0201: variableIdsToPersist.addAll(getContext(shandle).keySet());
0202: }
0203:
0204: activityToFollowedTransitions = new HashMap();
0205:
0206: SharkUtilities.addProcessToCache(shandle, this ,
0207: SharkUtilities.WRITE_MODE);
0208:
0209: persist(shandle);
0210: persistProcessContext(shandle);
0211:
0212: if (SharkEngineManager.getInstance().getEventAuditManagers()
0213: .size() > 0
0214: || externalRequesterClassName != null) {
0215: WfCreateProcessEventAudit cpea = SharkEngineManager
0216: .getInstance().getObjectFactory()
0217: .createCreateProcessEventAuditWrapper(shandle,
0218: this , requester);
0219: if (externalRequesterClassName != null) {
0220: notifyRequester(shandle, cpea);
0221: }
0222:
0223: }
0224:
0225: lastStateEventAudit = SharkEngineManager.getInstance()
0226: .getObjectFactory().createStateEventAuditWrapper(
0227: shandle, this ,
0228: SharkConstants.EVENT_PROCESS_STATE_CHANGED,
0229: null, state);
0230:
0231: if (externalRequesterClassName != null) {
0232: notifyRequester(shandle, lastStateEventAudit);
0233: }
0234:
0235: if (getContext(shandle).size() > 0) {
0236: if (SharkEngineManager.getInstance()
0237: .getEventAuditManagers().size() > 0
0238: || externalRequesterClassName != null) {
0239: WfDataEventAudit dea = SharkEngineManager
0240: .getInstance()
0241: .getObjectFactory()
0242: .createDataEventAuditWrapper(
0243: shandle,
0244: this ,
0245: SharkConstants.EVENT_PROCESS_CONTEXT_CHANGED,
0246: null, new HashMap(getContext(shandle)));
0247: if (externalRequesterClassName != null) {
0248: notifyRequester(shandle, dea);
0249: }
0250: }
0251: }
0252:
0253: SharkEngineManager.getInstance().getCallbackUtilities().info(
0254: shandle, "Process " + this + " is created");
0255:
0256: }
0257:
0258: /**
0259: * Used to create object when restoring it from database.
0260: */
0261: protected WfProcessImpl(ProcessPersistenceObject po) {
0262: restore(po);
0263: activityCache = new ActivityCache(this , false);
0264: }
0265:
0266: /**
0267: * Retrieve the requestor of this process.
0268: *
0269: * @return a WfRequester
0270: * @exception Exception
0271: */
0272: public WfRequesterInternal requester(WMSessionHandle shandle)
0273: throws Exception {
0274: return requester(shandle, SharkUtilities.READ_ONLY_MODE);
0275: }
0276:
0277: protected WfRequesterInternal requester(WMSessionHandle shandle,
0278: int mode) throws Exception {
0279: WfRequesterInternal requester = null;
0280: if (this .actRequesterId != null) {
0281: if (actRequester != null
0282: && ((initialTransaction != null && initialTransaction
0283: .equals(SharkUtilities
0284: .getTxSynchronization())) || (startingThread != null && startingThread
0285: .equals(Thread.currentThread())))) {
0286: requester = actRequester;
0287: } else {
0288: WfProcessInternal pReq = SharkUtilities.getProcess(
0289: shandle, this .actRequestersProcessId, mode);
0290: if (pReq != null) {
0291: requester = pReq.getActivity(shandle,
0292: this .actRequesterId);
0293: }
0294: }
0295: }
0296:
0297: WfRequester extReq = null;
0298: if (requester == null) {
0299: if (externalRequesterClassName != null) {
0300: try {
0301: extReq = (WfRequester) Class.forName(
0302: externalRequesterClassName).newInstance();
0303: } catch (Exception ex) {
0304: SharkEngineManager
0305: .getInstance()
0306: .getCallbackUtilities()
0307: .warn(
0308: shandle,
0309: "Process "
0310: + this
0311: + " - can't create external requester - "
0312: + externalRequesterClassName
0313: + " is not in the classpath, or it doesn't have default constructor.");
0314: }
0315: }
0316: if (this .resRequesterId != null) {
0317: requester = SharkEngineManager.getInstance()
0318: .getObjectFactory().createDefaultRequester(
0319: shandle, this .resRequesterId, extReq);
0320: } else {
0321: // throw new Exception("Process must have some requester");
0322: SharkEngineManager
0323: .getInstance()
0324: .getCallbackUtilities()
0325: .warn(
0326: shandle,
0327: "Process "
0328: + this
0329: + " - process Requester is missing. Maybe the parent process is deleted. Empty requester will be returned !");
0330: requester = SharkEngineManager.getInstance()
0331: .getObjectFactory().createDefaultRequester(
0332: shandle, "", extReq);
0333:
0334: }
0335: }
0336:
0337: return requester;
0338: }
0339:
0340: public void setExternalRequesterClassName(WMSessionHandle shandle,
0341: String extReqClassName) throws Exception {
0342: checkReadOnly();
0343: this .externalRequesterClassName = extReqClassName;
0344:
0345: persist(shandle);
0346: }
0347:
0348: /**
0349: * Retrieve the no of activities in this process.
0350: *
0351: * @return an int
0352: * @exception Exception
0353: */
0354: public int how_many_step(WMSessionHandle shandle) throws Exception {
0355: // TODO: see OMG/WfMC docu which acitivities to consider:
0356: // all or active ones only
0357: return activityCache.getOpen(shandle).size();
0358: }
0359:
0360: /**
0361: * Retrieve the WfProcessMgr of this process.
0362: *
0363: * @return a WfProcessMgr
0364: * @exception Exception
0365: */
0366: public WfProcessMgrInternal manager(WMSessionHandle shandle)
0367: throws Exception {
0368: if (manager == null) {
0369: manager = SharkUtilities
0370: .getProcessMgr(shandle, managerName);
0371: if (manager == null) {
0372: throw new Exception("Process " + this
0373: + " - can't find manager " + managerName);
0374: }
0375: }
0376: return manager;
0377: }
0378:
0379: /**
0380: * Retrieve the result for this process.
0381: *
0382: * @return a Map
0383: * @exception Exception
0384: * @exception ResultNotAvailable
0385: */
0386: public Map result(WMSessionHandle shandle) throws Exception,
0387: ResultNotAvailable {
0388: Map resultSigLHM = manager(shandle).result_signature(shandle);
0389: Map results = new HashMap();
0390:
0391: if (resultSigLHM != null) {
0392: Set resultKeys = resultSigLHM.keySet();
0393: Iterator i = resultKeys.iterator();
0394: while (i.hasNext()) {
0395: String fpId = (String) i.next();
0396: try {
0397: results.put(fpId, MiscUtilities
0398: .cloneWRD(getContext(shandle).get(fpId)));
0399: } catch (Throwable thr) {
0400: throw new RootException(thr);
0401: }
0402: }
0403: }
0404:
0405: return results;
0406: }
0407:
0408: /**
0409: * Starts the process.
0410: *
0411: * @exception Exception
0412: * @exception CannotStart
0413: * @exception AlreadyRunning
0414: */
0415: public void start(WMSessionHandle shandle) throws Exception,
0416: CannotStart, AlreadyRunning, ToolAgentGeneralException {
0417: checkReadOnly();
0418: if (state(shandle).equals(SharkConstants.STATE_OPEN_RUNNING)) {
0419: throw new AlreadyRunning(
0420: "Process "
0421: + toString()
0422: + " - the process is already running - can't start again!");
0423: }
0424: if (state(shandle)
0425: .startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
0426: throw new CannotStart("Process " + toString()
0427: + " - the process is closed - can't start it!");
0428: }
0429:
0430: if (getProcessDefinition(shandle).getStartingActivities()
0431: .size() == 0) {
0432: throw new CannotStart(
0433: "Process "
0434: + toString()
0435: + " - there are no starting activities in the process - can't start it!");
0436: }
0437: if (startTime < SharkConstants.UNDEFINED_TIME) {
0438: throw new CannotStart("Process " + toString()
0439: + " have been started already!");
0440: }
0441: try {
0442: startingThread = Thread.currentThread();
0443: initialTransaction = null;
0444: change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
0445: SharkEngineManager.getInstance().getCallbackUtilities()
0446: .info(shandle,
0447: "Process " + this + " is starting...");
0448: run(shandle, null);
0449: } catch (ToolAgentGeneralException tage) {
0450:
0451: change_state(shandle,
0452: SharkConstants.STATE_CLOSED_TERMINATED);
0453:
0454: throw tage;
0455: } finally {
0456: actRequester = null;
0457: startingThread = null;
0458: }
0459:
0460: }
0461:
0462: /**
0463: * Method change_state
0464: *
0465: * @param new_state a String
0466: * @exception Exception
0467: * @exception InvalidState
0468: * @exception TransitionNotAllowed
0469: */
0470: protected void change_state(WMSessionHandle shandle,
0471: String new_state) throws Exception, InvalidState,
0472: TransitionNotAllowed {
0473: // System.out.println(this+" - changing state from "+state+" to "+new_state);
0474: if (!SharkUtilities.valid_process_states(state(shandle))
0475: .contains(new_state)) {
0476: throw new TransitionNotAllowed("Process " + toString()
0477: + " - can't change to state " + new_state
0478: + ", from state " + state + " !");
0479: }
0480:
0481: if (new_state.equals(SharkConstants.STATE_OPEN_RUNNING)) {
0482: startTime = System.currentTimeMillis();
0483: this .calculateLimit(shandle);
0484: }
0485:
0486: // persisting the state change
0487: String oldState = state;
0488: state = new_state;
0489:
0490: lastStateTime = System.currentTimeMillis();
0491:
0492: persist(shandle);
0493:
0494: String eventType = SharkConstants.EVENT_PROCESS_STATE_CHANGED;
0495: lastStateEventAudit = SharkEngineManager.getInstance()
0496: .getObjectFactory().createStateEventAuditWrapper(
0497: shandle, this , eventType, oldState, new_state);
0498: if (state.startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
0499: if (!terminateOrAbortFromActivity
0500: && (externalRequesterClassName != null || actRequesterId != null)) {
0501: notifyRequester(shandle, lastStateEventAudit);
0502: }
0503: if (state.equals(SharkConstants.STATE_CLOSED_COMPLETED)) {
0504: delete(shandle);
0505: }
0506:
0507: } else {
0508: if (externalRequesterClassName != null) {
0509: notifyRequester(shandle, lastStateEventAudit);
0510: }
0511: }
0512:
0513: }
0514:
0515: /**
0516: * Asignes the new values to some process context variables. The variable can be given
0517: * by it's name or it's id.
0518: *
0519: * @param newValue a Map
0520: * @exception Exception
0521: * @exception InvalidData
0522: * @exception UpdateNotAllowed
0523: */
0524: public void set_process_context(WMSessionHandle shandle,
0525: Map newValue) throws Exception, InvalidData,
0526: UpdateNotAllowed {
0527: checkReadOnly();
0528: if (newValue == null) {
0529: throw new Exception("Process " + this
0530: + " - can't set context map which is null");
0531: }
0532: Map oldValues = new HashMap();
0533: Map newChanged = new HashMap();
0534: Iterator it = newValue.entrySet().iterator();
0535: while (it.hasNext()) {
0536: Map.Entry me = (Map.Entry) it.next();
0537: String id = (String) me.getKey();
0538: if (getContext(shandle).containsKey(id)) {
0539: Object oldVal = getContext(shandle).get(id);
0540: // type checking - throws an exception if type is invalid or can't be
0541: // converted to a valid one
0542: Object val = SharkUtilities.checkDataType(
0543: getProcessDefinition(shandle), id, oldVal, me
0544: .getValue());
0545: if ((oldVal != null && !oldVal.equals(val))
0546: || (oldVal == null && val != null)) {
0547: oldValues.put(id, oldVal);
0548: newChanged.put(id, val);
0549: }
0550: } else {
0551: throw new UpdateNotAllowed(
0552: "Process "
0553: + toString()
0554: + " - context attribute "
0555: + id
0556: + " does not exist in process context - adding new attributes to the process context is not allowed");
0557: }
0558: }
0559:
0560: if (newChanged.size() > 0) {
0561: getContext(shandle).putAll(newChanged);
0562: variableIdsToPersist.addAll(newChanged.keySet());
0563: persistProcessContext(shandle);
0564: if (SharkEngineManager.getInstance()
0565: .getEventAuditManagers().size() > 0
0566: || externalRequesterClassName != null) {
0567: boolean persistOldEventAuditData = new Boolean(
0568: SharkEngineManager.getInstance()
0569: .getCallbackUtilities().getProperty(
0570: "PERSIST_OLD_EVENT_AUDIT_DATA",
0571: "true")).booleanValue();
0572: if (!persistOldEventAuditData) {
0573: oldValues = null;
0574: }
0575: WfDataEventAudit dea = SharkEngineManager
0576: .getInstance()
0577: .getObjectFactory()
0578: .createDataEventAuditWrapper(
0579: shandle,
0580: this ,
0581: SharkConstants.EVENT_PROCESS_CONTEXT_CHANGED,
0582: oldValues, newChanged);
0583: if (externalRequesterClassName != null) {
0584: notifyRequester(shandle, dea);
0585: }
0586: }
0587: }
0588: }
0589:
0590: /**
0591: * Resume this process.
0592: */
0593: public void resume(WMSessionHandle shandle) throws Exception,
0594: CannotResume, NotSuspended {
0595: checkReadOnly();
0596: if (!state(shandle).equals(
0597: SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
0598: throw new NotSuspended(
0599: "Process "
0600: + toString()
0601: + " - the process is not suspended - can't resume it!");
0602: }
0603: // if this is a subflow process of suspended activity, and it is
0604: // executed as SYNCHRONOUS, do not allow process to resume
0605: WfRequesterInternal requester = requester(shandle);
0606: if (requester != null
0607: && (requester instanceof WfActivityInternal)) {
0608: WfActivityInternal waImpl = (WfActivityInternal) requester;
0609: if (waImpl.state(shandle).equals(
0610: SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
0611: // Determine subflow type
0612: if (waImpl.isPerformerSynchronous(shandle)) {
0613: SharkEngineManager
0614: .getInstance()
0615: .getCallbackUtilities()
0616: .error(
0617: shandle,
0618: "Process"
0619: + this
0620: + " - cannot resume because the requester activity is suspended");
0621: throw new CannotResume(
0622: "Process "
0623: + toString()
0624: + " - cannot resume. The requester activity is suspended");
0625: }
0626: }
0627: }
0628: SharkEngineManager.getInstance().getCallbackUtilities().info(
0629: shandle, "Process " + this + " -> resuming ...");
0630: change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
0631:
0632: Iterator it = getActiveActivities(shandle).iterator();
0633: while (it.hasNext()) {
0634: WfActivityInternal act = (WfActivityInternal) it.next();
0635: if (act.state(shandle).equals(
0636: SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
0637: if (act.block_activity_id(shandle) == null) {
0638: act.resume(shandle);
0639: }
0640: }
0641: }
0642: }
0643:
0644: /**
0645: * Suspend this process.
0646: */
0647: public void suspend(WMSessionHandle shandle) throws Exception,
0648: CannotSuspend, NotRunning, AlreadySuspended {
0649: checkReadOnly();
0650: if (state(shandle).equals(
0651: SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
0652: throw new AlreadySuspended(
0653: "Process "
0654: + toString()
0655: + " - the process is already suspended - can't suspend it twice!");
0656: }
0657: if (state(shandle).startsWith(
0658: SharkConstants.STATEPREFIX_OPEN_NOT_RUNNING)) {
0659: throw new NotRunning("Process " + toString()
0660: + " - the process is not in the running state");
0661: }
0662: SharkEngineManager.getInstance().getCallbackUtilities().info(
0663: shandle, "Process " + this + " - suspending...");
0664: change_state(shandle,
0665: SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED);
0666:
0667: Iterator it = getActiveActivities(shandle).iterator();
0668: while (it.hasNext()) {
0669: WfActivityInternal act = (WfActivityInternal) it.next();
0670: String actState = act.state(shandle);
0671: if (!actState
0672: .equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
0673: if (act.block_activity_id(shandle) == null) {
0674: act.suspend(shandle);
0675: }
0676: }
0677: }
0678: }
0679:
0680: public void terminateFromActivity(WMSessionHandle shandle)
0681: throws Exception, CannotStop, NotRunning {
0682: checkReadOnly();
0683: terminateOrAbortFromActivity = true;
0684: terminate(shandle);
0685: }
0686:
0687: /**
0688: * Terminate this process.
0689: */
0690: public void terminate(WMSessionHandle shandle) throws Exception,
0691: CannotStop, NotRunning {
0692: checkReadOnly();
0693: String stateStr = SharkConstants.STATE_CLOSED_TERMINATED;
0694:
0695: if (!state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
0696: throw new CannotStop(
0697: "Process "
0698: + toString()
0699: + " - the process is already closed - can't terminate it!");
0700: }
0701:
0702: SharkEngineManager.getInstance().getCallbackUtilities().info(
0703: shandle, "Process " + this + " -> terminating ...");
0704:
0705: change_state(shandle, stateStr);
0706:
0707: Iterator it = getActiveActivities(shandle).iterator();
0708: while (it.hasNext()) {
0709: WfActivityInternal act = (WfActivityInternal) it.next();
0710: if (act.block_activity_id(shandle) == null) {
0711: act.terminateFromProcess(shandle);
0712: }
0713: }
0714: lastFinishedActivities.clear();
0715:
0716: // delete(t);
0717: }
0718:
0719: public void abortFromActivity(WMSessionHandle shandle)
0720: throws Exception, CannotStop, NotRunning {
0721: checkReadOnly();
0722: terminateOrAbortFromActivity = true;
0723: abort(shandle);
0724: }
0725:
0726: /**
0727: * Abort the execution of this process.
0728: *
0729: * @exception Exception
0730: * @exception CannotStop
0731: * @exception NotRunning
0732: */
0733: public void abort(WMSessionHandle shandle) throws Exception,
0734: CannotStop, NotRunning {
0735: checkReadOnly();
0736: String stateStr = SharkConstants.STATE_CLOSED_ABORTED;
0737:
0738: if (!state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN)) {
0739: throw new CannotStop(
0740: "Process "
0741: + toString()
0742: + " - the process is already closed - can't abort it!");
0743: }
0744:
0745: SharkEngineManager.getInstance().getCallbackUtilities().info(
0746: shandle, "Process " + this + " -> aborting ...");
0747: change_state(shandle, stateStr);
0748:
0749: Iterator it = getActiveActivities(shandle).iterator();
0750:
0751: while (it.hasNext()) {
0752: WfActivityInternal act = (WfActivityInternal) it.next();
0753: if (act.block_activity_id(shandle) == null) {
0754: act.abortFromProcess(shandle);
0755: }
0756: }
0757:
0758: lastFinishedActivities.clear();
0759:
0760: // delete(t);
0761: }
0762:
0763: protected void run(WMSessionHandle shandle,
0764: WfActivityInternal lastFinishedActivity) throws Exception,
0765: ToolAgentGeneralException {
0766: isRunning = true;
0767: try {
0768: if (lastFinishedActivity == null) {
0769: List starts = getProcessDefinition(shandle)
0770: .getStartingActivities();
0771:
0772: for (Iterator it = starts.iterator(); it.hasNext();) {
0773: Activity actDef = (Activity) it.next();
0774: startActivity(shandle, actDef, null);
0775: }
0776: // return;
0777: }
0778: while (lastFinishedActivities.size() > 0) {
0779: if (!state
0780: .equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDED)) {
0781: // System.out.println("QN for lfa "+lastFinishedActivities.get(0));
0782: if (!state
0783: .startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
0784: queueNext(
0785: shandle,
0786: (WfActivityInternal) lastFinishedActivities
0787: .get(0));
0788: // System.out.println("QN for lfa "+lastFinishedActivities.get(0)+"
0789: // finished");
0790: }
0791: lastFinishedActivities.remove(0);
0792: } else {
0793: // System.out.println("ELSE");
0794: return;
0795: }
0796: }
0797: if (state.startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
0798: /*
0799: * try { delete(t); } catch (TransactionException tme) { throw new
0800: * Exception(tme); }
0801: */
0802: return;
0803: }
0804: } finally {
0805: isRunning = false;
0806: }
0807:
0808: }
0809:
0810: /**
0811: * Activates an activity object
0812: *
0813: * @param actDefId a String
0814: * @param blockActId a String
0815: * @exception Exception
0816: */
0817: public WfActivityInternal start_activity(WMSessionHandle shandle,
0818: String actDefId, String blockActId) throws Exception,
0819: ToolAgentGeneralException {
0820: checkReadOnly();
0821:
0822: if (state(shandle)
0823: .startsWith(SharkConstants.STATEPREFIX_CLOSED)) {
0824: throw new Exception("Process " + toString()
0825: + " - can't start activity of closed process!");
0826: }
0827:
0828: WorkflowProcess wp = getProcessDefinition(shandle);
0829:
0830: Activity activity = wp.getActivity(actDefId);
0831: if (activity == null) {
0832: throw new Exception("Process " + toString()
0833: + " - there's no activity for definition id="
0834: + actDefId + "!");
0835: }
0836: boolean needBlock = (activity.getParent().getParent() instanceof ActivitySet);
0837: if (blockActId == null && needBlock) {
0838: throw new Exception(
0839: "Process "
0840: + toString()
0841: + " - can't start activity for definition id="
0842: + actDefId
0843: + " - you must provide corresponding block activity instance Id!");
0844: }
0845:
0846: WfActivityInternal ba = null;
0847: if (needBlock) {
0848: ba = getActiveActivity(shandle, blockActId);
0849: if (ba == null) {
0850: throw new Exception(
0851: "Process "
0852: + toString()
0853: + " - can't start activity for definition id="
0854: + actDefId
0855: + " - the block activity Id "
0856: + blockActId
0857: + " is invalid, or block activity instance is closed!");
0858: }
0859: Activity bact = wp.getActivity(ba
0860: .activity_definition_id(shandle));
0861: if (bact.getActivityType() != XPDLConstants.ACTIVITY_TYPE_BLOCK) {
0862: throw new Exception("Process " + toString()
0863: + " - the activity instance with Id="
0864: + blockActId + " is not block activity!");
0865: }
0866: }
0867:
0868: if (state(shandle).equals(
0869: SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED)) {
0870: change_state(shandle, SharkConstants.STATE_OPEN_RUNNING);
0871: this .calculateLimit(shandle);
0872: }
0873:
0874: return startActivity(shandle, activity, ba);
0875: }
0876:
0877: public WfActivityInternal activateBlockActivity(
0878: WMSessionHandle shandle, String blockActDefId)
0879: throws Exception {
0880: checkReadOnly();
0881: WorkflowProcess wp = getProcessDefinition(shandle);
0882: Activity bact = wp.getActivity(blockActDefId);
0883: if (bact.getActivityType() != XPDLConstants.ACTIVITY_TYPE_BLOCK) {
0884: throw new Exception("Process " + toString()
0885: + " - the activity for definition id="
0886: + blockActDefId + " is not block activity!");
0887: }
0888: WfActivityInternal ba = null;
0889: if (bact.getParent().getParent() instanceof ActivitySet) {
0890: throw new Exception(
0891: "Process "
0892: + toString()
0893: + " - can't activate block that's inside another block!");
0894: }
0895: WfActivityInternal act = SharkEngineManager.getInstance()
0896: .getObjectFactory().createActivity(shandle, this ,
0897: getNextWorkItemId(shandle, blockActDefId),
0898: blockActDefId, ba);
0899: SharkEngineManager.getInstance().getCallbackUtilities().info(
0900: shandle,
0901: "Process" + toString() + " - Activity" + act.toString()
0902: + " is created");
0903: activityCache.add(act.key(shandle), act);
0904: act.activate(shandle);
0905: return act;
0906: }
0907:
0908: public String process_definition_id(WMSessionHandle shandle)
0909: throws Exception {
0910: return pDefId;
0911: }
0912:
0913: public String process_definition_name(WMSessionHandle shandle)
0914: throws Exception {
0915: return getProcessDefinition(shandle).getName();
0916: }
0917:
0918: public String manager_name(WMSessionHandle shandle)
0919: throws Exception {
0920: return managerName;
0921: }
0922:
0923: public String manager_version(WMSessionHandle shandle)
0924: throws Exception {
0925: return mgrVer;
0926: }
0927:
0928: // Activates an activity object
0929: protected WfActivityInternal startActivity(WMSessionHandle shandle,
0930: Activity activity, WfActivityInternal ba) throws Exception,
0931: ToolAgentGeneralException {
0932: // if activity is already activated (the case when XOR Join is reached twice or
0933: // more times, before activity is executed), do nothing
0934: if (isActivityDefinitionActive(shandle, activity, ba)) {
0935: SharkEngineManager
0936: .getInstance()
0937: .getCallbackUtilities()
0938: .warn(
0939: shandle,
0940: "Process "
0941: + this
0942: + "-> Activity "
0943: + activity
0944: + " is already started - can't start it twice");
0945:
0946: return null;
0947: }
0948:
0949: WfActivityInternal act = SharkEngineManager.getInstance()
0950: .getObjectFactory().createActivity(shandle, this ,
0951: getNextWorkItemId(shandle, activity.getId()),
0952: activity.getId(), ba);
0953: SharkEngineManager.getInstance().getCallbackUtilities().info(
0954: shandle,
0955: "Process" + toString() + " - Activity" + act.toString()
0956: + " is created");
0957: activityCache.add(act.key(shandle), act);
0958:
0959: // System.out.println("Activating act "+act);
0960: act.activate(shandle);
0961: // System.out.println("Finished activation of act "+act);
0962: String causeClassName = null;
0963: // handling block activity start and exc. handling
0964: if (activity.getActivityType() == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
0965: try {
0966: // System.out.println("Running block ....");
0967: runBlock(shandle, activity, act);
0968: // System.out.println("Finished running block");
0969: } catch (ToolAgentGeneralException ex) {
0970: causeClassName = SharkUtilities
0971: .extractExceptionName(ex);
0972: act.setExceptionName(shandle, causeClassName);
0973: act.setException(shandle, ex);
0974: }
0975: } else {
0976: causeClassName = act.getExceptionName(shandle);
0977: }
0978:
0979: if (causeClassName != null) {
0980: if (getExceptionTransFrom(shandle, act, activity,
0981: causeClassName).size() == 0) {
0982: Exception tage = act.getException(shandle);
0983: if (tage != null) {
0984: throw tage;
0985: }
0986: throw new Exception(
0987: "Process "
0988: + toString()
0989: + " - unexpected exception from WfProcessImpl.startActivity()");
0990: }
0991: }
0992:
0993: return act;
0994: }
0995:
0996: /**
0997: * Receives notification when an activity has completed.
0998: */
0999: public void activity_complete(WMSessionHandle shandle,
1000: WfActivityInternal activity) throws Exception {
1001: checkReadOnly();
1002: SharkEngineManager.getInstance().getCallbackUtilities().info(
1003: shandle,
1004: "Process" + toString() + " - Activity"
1005: + activity.toString() + " is completed.");
1006:
1007: // System.out.println("Activity "+activity+" signals its completion");
1008: lastFinishedActivities.add(activity);
1009:
1010: if (!isRunning) {
1011: // System.out.println("Calling run after completion of Activity "+activity);
1012: run(shandle, activity);
1013: // System.out.println("Run after completion of Activity "+activity+"finished");
1014: }
1015: // System.out.println("Returning to the caller after completion of Activity
1016: // "+activity+"finished");
1017: // SharkServer.getLogger().error("Process"+toString()+" - Exception while completing
1018: // activity");
1019: }
1020:
1021: /**
1022: * Receives notification when an activity has terminated.
1023: */
1024: public void activity_terminate(WMSessionHandle shandle,
1025: WfActivityInternal activity) throws Exception {
1026: checkReadOnly();
1027: SharkEngineManager.getInstance().getCallbackUtilities().info(
1028: shandle,
1029: "Process" + toString() + " - Activity"
1030: + activity.toString() + " is terminated.");
1031:
1032: lastFinishedActivities.add(activity);
1033:
1034: // FIXING BUG WHEN DEADLINE HAPPENS ON BLOCK ACTIVITY
1035: // Activity activityDefinition = SharkUtilities.getActivityDefinition(activity,
1036: // getProcessDefinition());
1037: // if (activityDefinition.getActivityType() == XPDLConstants.ACTIVITY_TYPE_BLOCK) {
1038: // List bas = getAllActiveActivitiesForBlockActivity(activity.key());
1039: // Iterator it = bas.iterator();
1040: // while (it.hasNext()) {
1041: // WfActivityInternal baMember = (WfActivityInternal) it.next();
1042: // removeFromActiveActivities(baMember.key());
1043: // }
1044: // }
1045:
1046: if (!isRunning) {
1047: run(shandle, activity);
1048: }
1049: }
1050:
1051: /**
1052: * Receives notification when an activity has aborted.
1053: */
1054: public void activity_abort(WMSessionHandle shandle,
1055: WfActivityInternal activity) throws Exception {
1056: checkReadOnly();
1057: if (!activity.state(shandle).equals(
1058: SharkConstants.STATE_CLOSED_ABORTED)) {
1059: throw new Exception("Process " + toString()
1060: + " - activity state is not aborted");
1061: }
1062:
1063: SharkEngineManager.getInstance().getCallbackUtilities().info(
1064: shandle,
1065: "Process" + toString() + " - Aborting activity"
1066: + activity.toString());
1067:
1068: }
1069:
1070: // Queues the next activities for processing
1071: protected void queueNext(WMSessionHandle shandle,
1072: WfActivityInternal fromActivity) throws Exception,
1073: ToolAgentGeneralException {
1074: // System.err.println("QUEINGNEXT FOR "+fromActivity);
1075: // try {
1076: WorkflowProcess wp = getProcessDefinition(shandle);
1077: Activity aDef = SharkUtilities.getActivityDefinition(shandle,
1078: fromActivity, wp);
1079: // Activities activityDefs;
1080: // Transitions transitions;
1081: // the next transitions from 'fromActivity'
1082: List nextTrans;
1083: WfActivityInternal blockActivity = fromActivity
1084: .block_activity(shandle);
1085: ActivitySet aSet = null;
1086: if (blockActivity != null) {
1087: aSet = (ActivitySet) aDef.getParent().getParent();
1088: // activityDefs=aSet.getActivities();
1089: // transitions=aSet.getTransitions();
1090: // // all transitions from activity
1091: // } else {
1092: // activityDefs=wp.getActivities();
1093: // transitions=wp.getTransitions();
1094: }
1095:
1096: String causeClassName = fromActivity.getExceptionName(shandle);
1097: boolean checkIfSomethingWrong = true;
1098: if (causeClassName == null) {
1099: nextTrans = getTransFrom(shandle, fromActivity, aDef);
1100: // System.out.println("NEXTTRANS="+nextTrans);
1101: } else {
1102: nextTrans = getExceptionTransFrom(shandle, fromActivity,
1103: aDef, causeClassName);
1104: // System.out.println("ETs="+nextTrans);
1105: if (nextTrans.size() == 0) {
1106: if (blockActivity != null
1107: && blockActivity.getException(shandle) != null) {
1108: nextTrans = new ArrayList();
1109: checkIfSomethingWrong = false;
1110: } else {
1111: Exception tage = null;
1112: if (blockActivity != null) {
1113: tage = blockActivity.getException(shandle);
1114: } else {
1115: tage = fromActivity.getException(shandle);
1116: }
1117: if (tage != null) {
1118: throw tage;
1119: }
1120: throw new Exception("Process " + toString()
1121: + " - tool agent exception '"
1122: + causeClassName
1123: + "' is not handled in XPDL");
1124: }
1125: }
1126: }
1127:
1128: // if something went wrong
1129: if (checkIfSomethingWrong && nextTrans.size() == 0) {
1130: // System.out.println("CSW ts0");
1131: XMLCollectionElement wpOrASet = wp;
1132: if (aSet != null) {
1133: wpOrASet = aSet;
1134: }
1135: List endingActDefs = null;
1136: if (wpOrASet instanceof WorkflowProcess) {
1137: endingActDefs = ((WorkflowProcess) wpOrASet)
1138: .getEndingActivities();
1139: // System.out.println("ead1="+endingActDefs);
1140: } else {
1141: endingActDefs = ((ActivitySet) wpOrASet)
1142: .getEndingActivities();
1143: // System.out.println("ead2="+endingActDefs);
1144: }
1145: if (!endingActDefs.contains(aDef)) {
1146: String unsatSplitHandling = getUnsatisfiedSplitConditionHandlingMode(shandle);
1147: if (unsatSplitHandling
1148: .equals(SharkConstants.UNSATISFIED_SPLIT_CONDITIONS_HANDLING_IGNORE)) {
1149: SharkEngineManager
1150: .getInstance()
1151: .getCallbackUtilities()
1152: .warn(
1153: shandle,
1154: "Process "
1155: + this
1156: + " could hang forever in "
1157: + fromActivity
1158: + " branch, after this activity is finished");
1159: return;
1160: } else if (unsatSplitHandling
1161: .equals(SharkConstants.UNSATISFIED_SPLIT_CONDITIONS_HANDLING_ROLLBACK)) {
1162: throw new Exception(
1163: "Process "
1164: + toString()
1165: + " - shark kernel is configured not to allow hanging processes!");
1166: } else {
1167: synchronizeProcess(shandle);
1168: // Do nothing - process/block will finish if it can
1169: SharkEngineManager
1170: .getInstance()
1171: .getCallbackUtilities()
1172: .error(
1173: shandle,
1174: "Process "
1175: + this
1176: + " will try to finish after "
1177: + fromActivity
1178: + " is executed because kernel is configured not to allow hanging and not to rollback");
1179: }
1180: }
1181: }
1182:
1183: if (nextTrans.size() > 0) {
1184: // System.out.println("NTS="+nextTrans.size());
1185: Iterator it = nextTrans.iterator();
1186: while (it.hasNext()) {
1187: Transition trans = (Transition) it.next();
1188: // Get the activity definition
1189: Activity toActivityDef = trans.getToActivity();
1190: if (!toActivityDef.isAndTypeJoin()
1191: || toActivityDef.getIncomingTransitions()
1192: .size() == 1) {
1193: // System.out.println("SA");
1194: startActivity(shandle, toActivityDef, blockActivity);
1195: } else {
1196: // System.out.println("JT");
1197: joinTransition(shandle, fromActivity, toActivityDef);
1198: }
1199: }
1200: } else {
1201: // find if there are active activities in some other branches
1202:
1203: // if there are other active activities, do nothing, and if this
1204: // is the last activity within activity set, finish block activity
1205: List actActs = getActiveActivities(shandle);
1206: // System.out.println("Act acts are "+actActs);
1207: if (actActs.size() > 0) {
1208: if (blockActivity != null) {
1209: for (int i = 0; i < actActs.size(); i++) {
1210: // try {
1211: Object ba = getActiveActivity(shandle,
1212: ((WfActivityInternal) actActs.get(i))
1213: .block_activity_id(shandle));
1214: if (ba != null && ba.equals(blockActivity)) {
1215: // System.out.println("AA is BA");
1216: return;
1217: }
1218: }
1219: // the activity set has no more transitions, finish the block activity
1220: // System.out.println("FBA");
1221: blockActivity.finish(shandle);
1222: return;
1223: }
1224: } else {
1225: // if this is end of Activity Set, finish the block activity
1226: if (aSet != null) {
1227: if (blockActivity.state(shandle).startsWith(
1228: SharkConstants.STATEPREFIX_CLOSED)) {
1229: // this can happen if we have implicit AND split within
1230: // the fully automatic block
1231: // System.out.println("BASCL");
1232: return;
1233: }
1234: // System.out.println("FBA2");
1235: blockActivity.finish(shandle);
1236: return;
1237: // otherwise, finish the process
1238: }
1239: // System.out.println("LFAS="+lastFinishedActivities);
1240: if (lastFinishedActivities.size() <= 1) {
1241: SharkEngineManager
1242: .getInstance()
1243: .getCallbackUtilities()
1244: .info(
1245: shandle,
1246: "Process"
1247: + toString()
1248: + " - No transitions left to follow");
1249:
1250: change_state(shandle,
1251: SharkConstants.STATE_CLOSED_COMPLETED);
1252: }
1253: }
1254: }
1255: /*
1256: * } catch (Throwable tr) {
1257: * SharkEngineManager.getInstance().getCallbackUtilities().error("Process"+toString()+" -
1258: * error while querying"); throw new Exception("Problems while querying",tr); }
1259: */
1260: }
1261:
1262: // Follows the and-join transition
1263: protected void joinTransition(WMSessionHandle shandle,
1264: WfActivityInternal fromActivity, Activity toActivityDef)
1265: throws Exception, ToolAgentGeneralException {
1266:
1267: synchronizeProcess(shandle);
1268:
1269: // get all incoming transitions to this activity
1270: List toTrans = toActivityDef.getIncomingTransitions();
1271:
1272: AndJoinHelperStruct ajhs = new AndJoinHelperStruct(fromActivity
1273: .block_activity_id(shandle), toActivityDef);
1274: int followed = restoreActivityToFollowedTransitionsMap(shandle,
1275: ajhs);
1276:
1277: SharkEngineManager
1278: .getInstance()
1279: .getCallbackUtilities()
1280: .info(
1281: shandle,
1282: "Process"
1283: + toString()
1284: + " - "
1285: + (followed + 1)
1286: + " of "
1287: + toTrans.size()
1288: + " transitions followed to activity with definition "
1289: + toActivityDef.getId()
1290: + ((fromActivity
1291: .block_activity_id(shandle) == null) ? ""
1292: : " inside block instance "
1293: + fromActivity
1294: .block_activity_id(shandle)));
1295: // System.err.println(Thread.currentThread()+ " - Process"
1296: // + toString()
1297: // + " - "
1298: // + (followed + 1)
1299: // + " of "
1300: // + toTrans.size()
1301: // + " transitions followed to activity with definition "
1302: // + toActivityDef.getId()
1303: // + ((fromActivity.block_activity_id(shandle) == null) ? ""
1304: // : " inside block instance "
1305: // + fromActivity.block_activity_id(shandle)));
1306:
1307: // check to see if all transition requirements are met
1308: if (toTrans.size() == followed + 1) {
1309: SharkEngineManager
1310: .getInstance()
1311: .getCallbackUtilities()
1312: .info(
1313: shandle,
1314: "Process"
1315: + toString()
1316: + " - All transition have been followed to activity with definition "
1317: + toActivityDef.getId()
1318: + ((fromActivity
1319: .block_activity_id(shandle) == null) ? ""
1320: : " inside block instance "
1321: + fromActivity
1322: .block_activity_id(shandle)));
1323: // System.err.println(Thread.currentThread()+ " - Process"
1324: // + toString()
1325: // + " - All transition have been followed to activity with definition "
1326: // + toActivityDef.getId()
1327: // + ((fromActivity.block_activity_id(shandle) == null) ? ""
1328: // : " inside block instance "
1329: // + fromActivity.block_activity_id(shandle)));
1330:
1331: Set currentTrans = (Set) newActivityToFollowedTransitions
1332: .get(ajhs);
1333: if (currentTrans != null && currentTrans.size() == followed) { // just remove
1334: // from map - this
1335: // is all
1336: // performed in
1337: // one transaction
1338: newActivityToFollowedTransitions.remove(ajhs);
1339: } else { // mark for delete
1340: if (currentTrans != null) {
1341: currentTrans.clear();
1342: } else {
1343: newActivityToFollowedTransitions.put(ajhs,
1344: currentTrans);
1345: }
1346: }
1347: // lastFinishedActivities.removeAll(followedActs);
1348: activityToFollowedTransitions.put(ajhs, new Integer(0));
1349:
1350: persistActivityToFollowedTransitions(shandle);
1351:
1352: startActivity(shandle, toActivityDef, getActiveActivity(
1353: shandle, fromActivity.block_activity_id(shandle)));
1354: } else {
1355: activityToFollowedTransitions.put(ajhs, new Integer(
1356: followed + 1));
1357: Set currentTrans = (Set) newActivityToFollowedTransitions
1358: .get(ajhs);
1359: if (currentTrans == null) {
1360: currentTrans = new HashSet();
1361: newActivityToFollowedTransitions
1362: .put(ajhs, currentTrans);
1363: }
1364: currentTrans.add(fromActivity.key(shandle));
1365:
1366: persistActivityToFollowedTransitions(shandle);
1367:
1368: // System.err.println("[WfProcess.joinTransition] : Waiting for transitions to
1369: // finish.");
1370: }
1371: }
1372:
1373: // Returns transitions to the next activity or activities to execute, based
1374: // on transition conditions, and split type of fromActivity
1375: // EXCEPTION and DEFAULTEXCEPTION transitions are not returned
1376: protected List getTransFrom(WMSessionHandle shandle,
1377: WfActivityInternal fromActivity, Activity fromActDef)
1378: throws Exception {
1379:
1380: List orderedOutTransitions = fromActDef
1381: .getNonExceptionalOutgoingTransitions();
1382: List transList = new ArrayList();
1383:
1384: boolean isAndSplit = fromActDef.isAndTypeSplit();
1385: Transition otherwiseTransition = null;
1386:
1387: Iterator transitions = orderedOutTransitions.iterator();
1388:
1389: while (transitions.hasNext()) {
1390: Transition trans = (Transition) transitions.next();
1391: Condition condition = trans.getCondition();
1392: String condType = condition.getType();
1393: if (condType.equals(XPDLConstants.CONDITION_TYPE_OTHERWISE)) {
1394: otherwiseTransition = trans;
1395: boolean handleOtherwiseTransitionLast = new Boolean(
1396: SharkEngineManager
1397: .getInstance()
1398: .getCallbackUtilities()
1399: .getProperty(
1400: "SharkKernel.handleOtherwiseTransitionLast",
1401: "false")).booleanValue();
1402: if (!isAndSplit && !handleOtherwiseTransitionLast) {
1403: break;
1404: }
1405: continue;
1406: }
1407: boolean evalRes = false;
1408: // user process_context() - we must pass cloned variables
1409: String cond = condition.toValue();
1410: if (cond.trim().length() == 0) {
1411: evalRes = true;
1412: } else {
1413: evalRes = evaluator(shandle).evaluateCondition(shandle,
1414: key, null, cond, process_context(shandle));
1415: }
1416: if (evalRes) {
1417: transList.add(trans);
1418: if (!isAndSplit) {
1419: break;
1420: }
1421: }
1422: }
1423:
1424: // use otherwise transitions if that is the only one transition
1425: // or if no other transition condition is evaluated to true
1426: // NOTE: this depends on configuration how to handle OTHERWISE transition
1427: if (transList.size() == 0 && otherwiseTransition != null) {
1428: transList.add(otherwiseTransition);
1429: SharkEngineManager
1430: .getInstance()
1431: .getCallbackUtilities()
1432: .info(
1433: shandle,
1434: "Process"
1435: + toString()
1436: + " - process is proceeding with otherwise transition of Activity"
1437: + fromActivity);
1438: }
1439: // System.err.println("[WfProcess.getTransFrom] : Transitions: " +
1440: // transList.size());
1441:
1442: return transList;
1443: }
1444:
1445: // Returns exception transition where the process has to go based on
1446: // exception thrown from tool agent
1447: protected List getExceptionTransFrom(WMSessionHandle shandle,
1448: WfActivityInternal fromActivity, Activity fromActDef,
1449: String exceptionName) throws Exception {
1450:
1451: List outTransitions = fromActDef
1452: .getExceptionalOutgoingTransitions();
1453: List transList = new ArrayList();
1454:
1455: if (outTransitions.size() == 0)
1456: return transList;
1457:
1458: Transition excTransition = null;
1459: Transition defaultExceptionTransition = null;
1460: Iterator transitions = outTransitions.iterator();
1461:
1462: while (transitions.hasNext()) {
1463: Transition trans = (Transition) transitions.next();
1464: Condition condition = trans.getCondition();
1465: String condType = condition.getType();
1466: if (condType
1467: .equals(XPDLConstants.CONDITION_TYPE_DEFAULTEXCEPTION)) {
1468: defaultExceptionTransition = trans;
1469: continue;
1470: }
1471:
1472: boolean evalRes = false;
1473: String cond = condition.toValue();
1474: if (cond.length() == 0) {
1475: evalRes = true;
1476: } else {
1477: evalRes = cond.equals(exceptionName);
1478: }
1479: if (evalRes) {
1480: excTransition = trans;
1481: break;
1482: }
1483: }
1484:
1485: // if there is no exception transition found, and there is no
1486: // default exception transition, try to evaluate conditions
1487: if (excTransition == null && defaultExceptionTransition == null) {
1488: transitions = outTransitions.iterator();
1489: while (transitions.hasNext()) {
1490: Transition trans = (Transition) transitions.next();
1491: Condition condition = trans.getCondition();
1492: boolean evalRes = false;
1493: String cond = condition.toValue();
1494: try {
1495: evalRes = evaluator(shandle).evaluateCondition(
1496: shandle, key, null, cond,
1497: process_context(shandle));
1498: } catch (Exception ex) {
1499: // System.out.println("Condition is not satisfied");
1500: }
1501: if (evalRes) {
1502: excTransition = trans;
1503: break;
1504: }
1505: }
1506: }
1507:
1508: // use default exception transitions if that is the only one transition
1509: if (excTransition == null && defaultExceptionTransition != null) {
1510: excTransition = defaultExceptionTransition;
1511: SharkEngineManager
1512: .getInstance()
1513: .getCallbackUtilities()
1514: .info(
1515: shandle,
1516: "Process"
1517: + toString()
1518: + " - process is proceeding with default exception transition of Activity"
1519: + fromActivity);
1520: }
1521: // System.err.println("[WfProcess.getTransFrom] : Transitions: " +
1522: // transList.size());
1523: if (excTransition != null) {
1524: transList.add(excTransition);
1525: }
1526:
1527: return transList;
1528: }
1529:
1530: protected void notifyRequester(WMSessionHandle shandle,
1531: WfEventAudit event) throws Exception {
1532: SharkEngineManager.getInstance().getCallbackUtilities().info(
1533: shandle,
1534: "Process" + toString()
1535: + " - notifying requester of the event");
1536: WfRequesterInternal req = requester(shandle,
1537: SharkUtilities.WRITE_MODE);
1538: // SharkEngineManager.getInstance().getCallbackUtilities().info("Process"+toString()+"
1539: // - requester found");
1540:
1541: if (req != null) {
1542: WfActivityInternal aReq = null;
1543: if (req instanceof WfActivityInternal) {
1544: aReq = (WfActivityInternal) req;
1545: }
1546: if (aReq == null) {
1547: req.receive_event(shandle, event, this );
1548: // SharkEngineManager.getInstance().getCallbackUtilities().info("Process"+toString()+"
1549: // - ext requester notified");
1550: } else {
1551: // if the requester activity is closed - do not notify it
1552: if ((event instanceof WfStateEventAudit)
1553: && aReq.state(shandle).startsWith(
1554: SharkConstants.STATEPREFIX_OPEN)) {
1555: aReq.receive_event(shandle, event, this );
1556: // SharkEngineManager.getInstance().getCallbackUtilities().info("Process"+toString()+"
1557: // - act requester notified");
1558: }
1559: }
1560: }
1561: }
1562:
1563: /**
1564: * Puts the workflow relevant data and formal parameters into process context. All data
1565: * is put into context by id-value pairs. The initial value of WRD is set if exist, or
1566: * default value otherwise. The formal parameters are also initialized to the default
1567: * values.
1568: */
1569: protected void initializeProcessContext(WMSessionHandle shandle)
1570: throws Exception {
1571: // get all data fields (from package, and from process)
1572: WorkflowProcess wp = getProcessDefinition(shandle);
1573: Collection dfsAndFPs = wp.getAllVariables().values();
1574: Iterator itDfs = dfsAndFPs.iterator();
1575:
1576: while (itDfs.hasNext()) {
1577: XMLCollectionElement dfOrFp = (XMLCollectionElement) itDfs
1578: .next();
1579: Object initVal = SharkUtilities.getInitialValue(shandle,
1580: dfOrFp, false);
1581: String id = dfOrFp.getId();
1582: // out.println("putting "+dfOrFp.getClass().getName()+" "+id+"into context");
1583: processContext.put(id, initVal);
1584: }
1585:
1586: contextInitialized = true;
1587: }
1588:
1589: /**
1590: * Get the next work item ID. Each work item will have a unique ID.
1591: *
1592: * @return The work item ID string
1593: */
1594: protected String getNextWorkItemId(WMSessionHandle shandle,
1595: String aDefId) throws Exception {
1596: String id = SharkUtilities
1597: .getNextId(SharkConstants.ACTIVITY_ID_NAME);
1598: id = id + "_" + key + "_" + aDefId;
1599: if (id.length() > 100)
1600: id = id.substring(0, 100);
1601:
1602: return id;
1603: }
1604:
1605: public String toString() {
1606: return "[key=" + key + ",mgrname=" + managerName + "]";
1607: }
1608:
1609: /**
1610: * It is assumed that there can't be two or more processes having the same key.
1611: */
1612: public boolean equals(java.lang.Object obj) {
1613: if (!(obj instanceof WfProcessImpl))
1614: return false;
1615:
1616: return ((WfProcessImpl) obj).key.equals(key);
1617: }
1618:
1619: public int hashCode() {
1620: return key.hashCode();
1621: }
1622:
1623: /**
1624: * Returns if there is an active activity for given definition.
1625: */
1626: protected boolean isActivityDefinitionActive(
1627: WMSessionHandle shandle, Activity aDef,
1628: WfActivityInternal ba) throws Exception {
1629: String aDefId = aDef.getId();
1630: Iterator it = getActiveActivities(shandle).iterator();
1631: while (it.hasNext()) {
1632: WfActivityInternal act = (WfActivityInternal) it.next();
1633: WfActivityInternal actba = act.block_activity(shandle);
1634: boolean bae;
1635: if (actba != null) {
1636: bae = actba.equals(ba);
1637: } else {
1638: if (ba == null) {
1639: bae = true;
1640: } else {
1641: bae = false;
1642: }
1643: }
1644: if (bae
1645: && act.activity_definition_id(shandle).equals(
1646: aDefId)
1647: && (act.state(shandle).equals(
1648: SharkConstants.STATE_OPEN_RUNNING) || act
1649: .state(shandle)
1650: .equals(
1651: SharkConstants.STATE_OPEN_NOT_RUNNING_NOT_STARTED))) {
1652: return true;
1653: }
1654: }
1655:
1656: return false;
1657: }
1658:
1659: protected synchronized void setProcessVariables(
1660: WMSessionHandle shandle) throws Exception {
1661: if (contextInitialized) {
1662: return;
1663: }
1664: // System.out.println("SPVCVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");
1665: // initialize context, just to keep the order of variables
1666: PersistentManagerInterface ipm = SharkEngineManager
1667: .getInstance().getInstancePersistenceManager();
1668:
1669: WorkflowProcess wp = getProcessDefinition(shandle);
1670: List l = new ArrayList(wp.getAllVariables().values());
1671: if (l.size() == 0)
1672: return;
1673: // System.err.println("INIT PC="+processContext);
1674: Iterator it = l.iterator();
1675: List variableIds = new ArrayList();
1676: while (it.hasNext()) {
1677: XMLCollectionElement dfOrFp = (XMLCollectionElement) it
1678: .next();
1679: String vdId = dfOrFp.getId();
1680: variableIds.add(vdId);
1681: }
1682: l = ipm.getProcessVariables(shandle, key, variableIds);
1683: it = l.iterator();
1684: while (it.hasNext()) {
1685: ProcessVariablePersistenceObject var = (ProcessVariablePersistenceObject) it
1686: .next();
1687: // System.out.println("Restoring proc var "+var.getDefinitionId()+",
1688: // val="+var.getValue());
1689: // if (anyVal!=null) {
1690: processContext.put(var.getDefinitionId(), var.getValue());
1691: // }
1692: }
1693: contextInitialized = true;
1694: }
1695:
1696: protected WorkflowProcess getProcessDefinition(
1697: WMSessionHandle shandle) throws Exception {
1698: if (xpdlProcess == null) {
1699: xpdlProcess = SharkUtilities.getWorkflowProcess(shandle,
1700: pkgId, mgrVer, pDefId);
1701: }
1702: return xpdlProcess;
1703: }
1704:
1705: public void persist(WMSessionHandle shandle) throws Exception {
1706: checkReadOnly();
1707: // System.err.println("The proc "+this+" is being persisted with thread
1708: // "+Thread.currentThread());
1709: // System.err.println("The proc "+key+" is being persisted:");
1710: SharkEngineManager.getInstance()
1711: .getInstancePersistenceManager().persist(shandle,
1712: createAndFillPersistentObject(), justCreated);
1713: // persistProcessContext(t);
1714: // persistActivityToFollowedTransitions(t);
1715: this .justCreated = false;
1716: }
1717:
1718: protected void persistProcessContext(WMSessionHandle shandle)
1719: throws Exception {
1720: if (variableIdsToPersist.size() == 0)
1721: return;
1722: PersistentManagerInterface pmgr = SharkEngineManager
1723: .getInstance().getInstancePersistenceManager();
1724: // System.out.println("Persisting proc var map="+getContext(t));
1725: Iterator it = getContext(shandle).entrySet().iterator();
1726: while (it.hasNext()) {
1727: Map.Entry me = (Map.Entry) it.next();
1728: String defId = (String) me.getKey();
1729: if (variableIdsToPersist.contains(defId)) {
1730: Object val = me.getValue();
1731: ProcessVariablePersistenceObject var = new ProcessVariablePersistenceObject();
1732: var.setProcessId(key);
1733: var.setDefinitionId(defId);
1734: var.setValue(val);
1735: // System.out.println("Persisting process variable "+defId+", val="+val+"
1736: // for proc "+key);
1737: pmgr.persist(shandle, var, justCreatedVariables);
1738: }
1739: }
1740: variableIdsToPersist.clear();
1741: this .justCreatedVariables = false;
1742: }
1743:
1744: public void delete(WMSessionHandle shandle) throws Exception {
1745: // if (isDeleted) return;
1746: // try {System.err.println("Deleting process "+key);}catch (Exception ex){};
1747: // System.err.println("I'm going to delete activities "+getActivityList());
1748:
1749: checkReadOnly();
1750: // deleteProcessContext();
1751:
1752: // Iterator it=getActivityList(t).iterator();
1753: /*
1754: * Iterator it=getAllActivities(t).iterator(); while (it.hasNext()) {
1755: * ((WfActivityInternal)it.next()).delete(t); }
1756: */
1757: // activeActivitiesMap=null;
1758: SharkEngineManager.getInstance()
1759: .getInstancePersistenceManager().deleteProcess(shandle,
1760: key, false);
1761:
1762: // if (processContext!=null) processContext.clear();
1763: // System.out.println("Removing process "+key+" from cache");
1764: SharkUtilities.removeProcessFromCache(shandle, this );
1765: // isDeleted=true;
1766: // System.out.println("Deleting of process "+key+" finished");
1767: }
1768:
1769: public void mandatoryDelete(WMSessionHandle shandle)
1770: throws Exception {
1771: checkReadOnly();
1772: SharkEngineManager.getInstance()
1773: .getInstancePersistenceManager().deleteProcess(shandle,
1774: key, true);
1775:
1776: SharkUtilities.removeProcessFromCache(shandle, this );
1777: }
1778:
1779: protected void synchronizeProcess(WMSessionHandle shandle)
1780: throws Exception {
1781: SharkEngineManager.getInstance()
1782: .getInstancePersistenceManager().synchronizeProcess(
1783: shandle, key);
1784: }
1785:
1786: /*
1787: * protected void deleteProcessContext () throws TransactionException { try {
1788: * PersistentManagerInterface
1789: * pm=SharkEngineManager.getInstance().getPersistentManager(); Iterator
1790: * it=getContext().keySet().iterator(); while (it.hasNext()) { String
1791: * defId=(String)it.next(); ProcessVariablePersistenceInterface
1792: * var=pm.createProcessVariable(); var.setProcessId(key); var.setDefinitionId(defId);
1793: * pm.delete(var,SharkEngineManager.getTransaction()); } } catch (Exception ex) { throw
1794: * new TransactionException("Exception while deleting process context"); } }
1795: */
1796:
1797: protected XMLCollectionElement getXPDLObject(WMSessionHandle shandle)
1798: throws Exception {
1799: return getProcessDefinition(shandle);
1800: }
1801:
1802: public Map getContext(WMSessionHandle shandle) throws Exception {
1803: if (!contextInitialized) {
1804: setProcessVariables(shandle);
1805: }
1806: return processContext;
1807: }
1808:
1809: public Evaluator evaluator(WMSessionHandle shandle)
1810: throws Exception {
1811: if (evaluator == null) {
1812: evaluator = SharkEngineManager.getInstance()
1813: .getScriptingManager().getEvaluator(
1814: shandle,
1815: SharkUtilities.getScriptType(shandle,
1816: pkgId, mgrVer));
1817: }
1818: return evaluator;
1819: }
1820:
1821: protected ProcessPersistenceObject createAndFillPersistentObject() {
1822: ProcessPersistenceObject po = new ProcessPersistenceObject();
1823: fillPersistentObject(po);
1824: return po;
1825: }
1826:
1827: protected void fillPersistentObject(ProcessPersistenceObject po) {
1828: po.setId(this .key);
1829: po.setActivityRequesterId(this .actRequesterId);
1830: po.setActivityRequestersProcessId(this .actRequestersProcessId);
1831: po.setResourceRequesterId(this .resRequesterId);
1832: po
1833: .setExternalRequesterClassName(this .externalRequesterClassName);
1834: po.setState(this .state);
1835: po.setLastStateTime(this .lastStateTime);
1836: po.setCreatedTime(this .creationTime);
1837: po.setStartedTime(this .startTime);
1838: po.setProcessMgrName(this .managerName);
1839: po.setName(this .name);
1840: po.setDescription(this .description);
1841: po.setPriority(this .priority);
1842: po.setLimitTime(this .limitTime);
1843: }
1844:
1845: protected void restore(ProcessPersistenceObject po) {
1846: this .key = po.getId();
1847: this .actRequesterId = po.getActivityRequesterId();
1848: this .actRequestersProcessId = po
1849: .getActivityRequestersProcessId();
1850: this .resRequesterId = po.getResourceRequesterId();
1851: this .externalRequesterClassName = po
1852: .getExternalRequesterClassName();
1853: this .state = po.getState();
1854: this .lastStateTime = po.getLastStateTime();
1855: this .creationTime = po.getCreatedTime();
1856: this .startTime = po.getStartedTime();
1857: this .managerName = po.getProcessMgrName();
1858: this .name = po.getName();
1859: this .description = po.getDescription();
1860: this .priority = po.getPriority();
1861: this .limitTime = po.getLimitTime();
1862:
1863: setXPDLAttribs();
1864: }
1865:
1866: public String package_id(WMSessionHandle shandle) throws Exception {
1867: return pkgId;
1868: }
1869:
1870: public WfActivityInternal getActiveActivity(
1871: WMSessionHandle shandle, String actId) throws Exception {
1872: return activityCache.getOpen(shandle, actId);
1873: }
1874:
1875: public List getActiveActivities(WMSessionHandle shandle)
1876: throws Exception {
1877: return activityCache.getOpen(shandle);
1878: }
1879:
1880: public List getAllActivities(WMSessionHandle shandle)
1881: throws Exception {
1882: return activityCache.getAll(shandle);
1883: }
1884:
1885: public WfActivityInternal getActivity(WMSessionHandle shandle,
1886: String actId) throws Exception {
1887: return activityCache.getAny(shandle, key, actId);
1888: }
1889:
1890: public long getCreationTime(WMSessionHandle shandle)
1891: throws Exception {
1892: return creationTime;
1893: }
1894:
1895: public long getStartTime(WMSessionHandle shandle) throws Exception {
1896: return startTime;
1897: }
1898:
1899: public String getResourceRequesterId(WMSessionHandle shandle)
1900: throws Exception {
1901: return this .resRequesterId;
1902: }
1903:
1904: public String getActivityRequesterId(WMSessionHandle shandle)
1905: throws Exception {
1906: return this .actRequesterId;
1907: }
1908:
1909: public String getActivityRequesterProcessId(WMSessionHandle shandle)
1910: throws Exception {
1911: return this .actRequestersProcessId;
1912: }
1913:
1914: protected void setXPDLAttribs() {
1915: this .pkgId = MiscUtilities.getProcessMgrPkgId(this .managerName);
1916: this .pDefId = MiscUtilities
1917: .getProcessMgrProcDefId(this .managerName);
1918: this .mgrVer = MiscUtilities
1919: .getProcessMgrVersion(this .managerName);
1920: }
1921:
1922: protected int restoreActivityToFollowedTransitionsMap(
1923: WMSessionHandle shandle, AndJoinHelperStruct ajhs)
1924: throws Exception {
1925: Integer followed = (Integer) activityToFollowedTransitions
1926: .get(ajhs);
1927:
1928: if (followed == null) {
1929: PersistentManagerInterface pmi = SharkEngineManager
1930: .getInstance().getInstancePersistenceManager();
1931: int noOfFollowed = 0;
1932:
1933: noOfFollowed = pmi.howManyAndJoinEntries(shandle, key, ajhs
1934: .getBlockActId(), ajhs.getActivityDef().getId());
1935:
1936: // get a list of followed transition to this activity
1937: followed = new Integer(noOfFollowed);
1938: activityToFollowedTransitions.put(ajhs, followed);
1939: }
1940:
1941: return followed.intValue();
1942: }
1943:
1944: protected void persistActivityToFollowedTransitions(
1945: WMSessionHandle shandle) throws Exception {
1946: PersistentManagerInterface pmi = SharkEngineManager
1947: .getInstance().getInstancePersistenceManager();
1948: Iterator it = newActivityToFollowedTransitions.entrySet()
1949: .iterator();
1950:
1951: while (it.hasNext()) {
1952: Map.Entry me = (Map.Entry) it.next();
1953: AndJoinHelperStruct ajhs = (AndJoinHelperStruct) me
1954: .getKey();
1955: Set actInstances = (Set) me.getValue();
1956: if (actInstances == null || actInstances.size() == 0) {
1957: pmi
1958: .deleteAndJoinEntries(shandle, key, ajhs
1959: .getBlockActId(), ajhs.getActivityDef()
1960: .getId());
1961: } else {
1962: Iterator aInst = actInstances.iterator();
1963:
1964: while (aInst.hasNext()) {
1965: String actId = (String) aInst.next();
1966: AndJoinEntryPersitenceObject aji = new AndJoinEntryPersitenceObject();
1967: aji.setProcessId(key);
1968: aji.setBlockActivityId(ajhs.getBlockActId());
1969: aji.setActivityDefinitionId(ajhs.getActivityDef()
1970: .getId());
1971: aji.setActivityId(actId);
1972: pmi.persist(shandle, aji);
1973: }
1974: }
1975: }
1976: newActivityToFollowedTransitions.clear();
1977: }
1978:
1979: // Runs a BLOCK activity
1980: protected void runBlock(WMSessionHandle shandle,
1981: Activity bActivity, WfActivityInternal blockActivity)
1982: throws Exception, ToolAgentGeneralException {
1983: BlockActivity ba = bActivity.getActivityTypes()
1984: .getBlockActivity();
1985: if (ba != null) {
1986: String asId = ba.getBlockId();
1987: ActivitySet as = XMLUtil.getWorkflowProcess(bActivity)
1988: .getActivitySet(asId);
1989: if (as != null) {
1990: List starts = as.getStartingActivities();
1991: for (Iterator it = starts.iterator(); it.hasNext();) {
1992: Activity act = (Activity) it.next();
1993: startActivity(shandle, act, blockActivity);
1994: }
1995: // while
1996: // (blockActivity.state(shandle).startsWith(SharkConstants.STATEPREFIX_OPEN))
1997: // {
1998: // System.out.println("1111111111111");
1999: // if (lastFinishedActivities.size()>0) {
2000: // System.out.println("222222222222222222");
2001: // WfActivityInternal
2002: // lf=(WfActivityInternal)lastFinishedActivities.get(lastFinishedActivities.size()-1);
2003: // System.out.println("RBL, lfa="+lf);
2004: //
2005: // if (lf.block_activity(shandle)==blockActivity) {
2006: // System.out.println("333333333333333");
2007: // queueNext(shandle, lf);
2008: // lastFinishedActivities.remove(lastFinishedActivities.size()-1);
2009: // System.out.println("4444444444444");
2010: //
2011: // }else {
2012: // break;
2013: // }
2014: // } else {
2015: // break;
2016: // }
2017: // }
2018: }
2019: }
2020:
2021: }
2022:
2023: public WfActivityInternal[] checkDeadlines(WMSessionHandle shandle)
2024: throws Exception {
2025: // check only open.running processes
2026: checkReadOnly();
2027: if (!state(shandle).equals(SharkConstants.STATE_OPEN_RUNNING))
2028: throw new Exception(
2029: "Process "
2030: + toString()
2031: + " - can't check deadlines for the closed process instance");
2032:
2033: List deadlineActs = new ArrayList();
2034:
2035: List activeActs = getActiveActivities(shandle);
2036: long timeLimitBoundary = System.currentTimeMillis();
2037: Map actToExcNames = new HashMap();
2038: for (int i = 0; i < activeActs.size(); i++) {
2039: WfActivityInternal act = (WfActivityInternal) activeActs
2040: .get(i);
2041: if (act.block_activity_id(shandle) == null) {
2042:
2043: Map ataens = new HashMap();
2044: boolean syncDeadlineHappened = act.checkDeadlines(
2045: shandle, timeLimitBoundary, ataens);
2046: if (syncDeadlineHappened) {
2047: deadlineActs.add(act);
2048: continue;
2049: }
2050:
2051: if (ataens != null && ataens.size() > 0) {
2052: deadlineActs.add(act);
2053: actToExcNames.putAll(ataens);
2054: }
2055: }
2056: }
2057: if (actToExcNames.size() > 0) {
2058: handleBrokenAsyncDeadlines(shandle, actToExcNames);
2059: }
2060:
2061: WfActivityInternal[] daArr = new WfActivityInternal[deadlineActs
2062: .size()];
2063: deadlineActs.toArray(daArr);
2064: return daArr;
2065: }
2066:
2067: public boolean checkDeadline(WMSessionHandle shandle, String actId)
2068: throws Exception {
2069: checkReadOnly();
2070: // check only open.running processes
2071: if (!state(shandle).equals(SharkConstants.STATE_OPEN_RUNNING))
2072: throw new Exception(
2073: "Process "
2074: + toString()
2075: + " - can't check deadlines for the closed process instance");
2076:
2077: WfActivityInternal act = getActiveActivity(shandle, actId);
2078: if (act == null)
2079: throw new Exception("Process " + toString()
2080: + " - there is no active activity with Id=" + actId
2081: + " within this process");
2082: Map actToExcNames = new HashMap();
2083: boolean deadlineHappened = act.checkDeadlines(shandle, System
2084: .currentTimeMillis(), actToExcNames);
2085:
2086: if (actToExcNames != null && actToExcNames.size() > 0) {
2087: deadlineHappened = true;
2088: handleBrokenAsyncDeadlines(shandle, actToExcNames);
2089: }
2090: return deadlineHappened;
2091: }
2092:
2093: protected void handleBrokenAsyncDeadlines(WMSessionHandle shandle,
2094: Map actToExcNames) throws Exception {
2095: WorkflowProcess wp = getProcessDefinition(shandle);
2096: Iterator excs = actToExcNames.entrySet().iterator();
2097:
2098: while (excs.hasNext()) {
2099: Map.Entry me = (Map.Entry) excs.next();
2100: WfActivityInternal act = (WfActivityInternal) me.getKey();
2101: List excNames = (List) me.getValue();
2102: WfActivityInternal blockActivity = act
2103: .block_activity(shandle);
2104: Activity aDef = SharkUtilities.getActivityDefinition(
2105: shandle, act, wp);
2106: List resultingTransitions = new ArrayList();
2107: for (Iterator it = excNames.iterator(); it.hasNext();) {
2108: List ets = getExceptionTransFrom(shandle, act, aDef,
2109: (String) it.next());
2110: Iterator itets = ets.iterator();
2111: while (itets.hasNext()) {
2112: Object trans = itets.next();
2113: if (!resultingTransitions.contains(trans)) {
2114: resultingTransitions.add(trans);
2115: }
2116: }
2117: }
2118: for (Iterator it = resultingTransitions.iterator(); it
2119: .hasNext();) {
2120: Transition trans = (Transition) it.next();
2121:
2122: Activity actToDef = trans.getToActivity();
2123: // TODO: is it OK? which blockActivity it is?
2124: startActivity(shandle, actToDef, blockActivity);
2125: }
2126: }
2127: }
2128:
2129: public List getAllActiveActivitiesForBlockActivity(
2130: WMSessionHandle shandle, String blockActivityId)
2131: throws Exception {
2132: List allActiveActivities = getActiveActivities(shandle);
2133: Iterator it = allActiveActivities.iterator();
2134: List ret = new ArrayList();
2135: while (it.hasNext()) {
2136: WfActivityInternal act = (WfActivityInternal) it.next();
2137: if (blockActivityId.equals(act.block_activity_id(shandle))) {
2138: ret.add(act);
2139: }
2140: }
2141:
2142: return ret;
2143: }
2144:
2145: public boolean isReadOnly() {
2146: return isReadOnly;
2147: }
2148:
2149: public void setReadOnly(boolean ro) {
2150: boolean useReadOnlyConcept = Boolean.valueOf(
2151: SharkEngineManager.getInstance().getCallbackUtilities()
2152: .getProperty("SharkKernel.useReadOnlyConcept",
2153: "true")).booleanValue();
2154:
2155: if (useReadOnlyConcept) {
2156: this .isReadOnly = ro;
2157: if (ro) {
2158: activityCache.clear();
2159: processContext.clear();
2160: contextInitialized = false;
2161: }
2162: } else {
2163: isReadOnly = false;
2164: }
2165: }
2166:
2167: public WfProcessInternal duplicate() throws Exception {
2168: WfProcessImpl procImpl = (WfProcessImpl) SharkEngineManager
2169: .getInstance().getObjectFactory().createProcess(
2170: createAndFillPersistentObject());
2171: procImpl.lastStateEventAudit = this .lastStateEventAudit;
2172: procImpl.evaluator = this .evaluator;
2173: procImpl.manager = this .manager;
2174: procImpl.xpdlProcess = this .xpdlProcess;
2175: procImpl.initialTransaction = this .initialTransaction;
2176: procImpl.startingThread = this .startingThread;
2177:
2178: // if (this.contextInitialized) {
2179: // try {
2180: // procImpl.processContext = this.duplicateContext(processContext);
2181: // procImpl.contextInitialized = true;
2182: // } catch (Exception ex) {
2183: // }
2184: // }
2185: //
2186: // procImpl.activityCache = this.activityCache.duplicate(procImpl);
2187:
2188: return procImpl;
2189: }
2190:
2191: // Meant to be used only from SharkTxSynchronization
2192: // public void clearActivityCache () {
2193: // activityCache.clear();
2194: // }
2195: //
2196: // Meant to be used only from SharkTxSynchronization
2197: // public void clearVariableCache () {
2198: // processContext.clear();
2199: // contextInitialized=false;
2200: // }
2201:
2202: protected void checkReadOnly() throws Exception {
2203: if (isReadOnly()) {
2204: throw new Exception("Process " + this + " is read-only!");
2205: }
2206: }
2207:
2208: protected String getUnsatisfiedSplitConditionHandlingMode(
2209: WMSessionHandle shandle) throws Exception {
2210: return SharkEngineManager
2211: .getInstance()
2212: .getCallbackUtilities()
2213: .getProperty(
2214: "SharkKernel.UnsatisfiedSplitConditionsHandling",
2215: SharkConstants.UNSATISFIED_SPLIT_CONDITIONS_HANDLING_FINISH_IF_POSSIBLE);
2216: }
2217:
2218: }
2219:
2220: class AndJoinHelperStruct {
2221: protected Activity actDef;
2222:
2223: protected String blockActId;
2224:
2225: public AndJoinHelperStruct(String blockActId, Activity actDef) {
2226: this .blockActId = blockActId;
2227: this .actDef = actDef;
2228: }
2229:
2230: public Activity getActivityDef() {
2231: return actDef;
2232: }
2233:
2234: public String getBlockActId() {
2235: return blockActId;
2236: }
2237:
2238: public int hashCode() {
2239: return actDef.hashCode();
2240: }
2241:
2242: public boolean equals(Object obj) {
2243: AndJoinHelperStruct ajhs = (AndJoinHelperStruct) obj;
2244: return actDef == ajhs.actDef
2245: && ((blockActId == null) ? ajhs.blockActId == null
2246: : blockActId.equals(ajhs.blockActId));
2247: }
2248: }
|