Esempio n. 1
0
        /// <summary>
        /// 开始节点触发
        /// </summary>
        /// <param name="tk"></param>
        public override void fire(IToken tk)
        {
            if (!tk.IsAlive)//如果token是false,那么直接返回
            {
                return;//
            }
            if (tk.Value != this.Volume)
            {
                KernelException exception = new KernelException(tk.ProcessInstance,
                        this.startNode,
                        "Error:Illegal StartNodeInstance,the tokenValue MUST be equal to the volume ");
                throw exception;

            }

            tk.NodeId = this.Synchronizer.Id;//到开始节点(同步器)

            IProcessInstance processInstance = tk.ProcessInstance;//从token中获得流程实例对象

            //触发token_entered事件
            NodeInstanceEvent event1 = new NodeInstanceEvent(this);
            event1.Token=tk;
            event1.EventType=NodeInstanceEventEnum.NODEINSTANCE_TOKEN_ENTERED;//token进入
            this.fireNodeEvent(event1);

            //触发fired事件
            NodeInstanceEvent event2 = new NodeInstanceEvent(this);
            event2.Token=tk;
            event2.EventType=NodeInstanceEventEnum.NODEINSTANCE_FIRED;//token 触发
            this.fireNodeEvent(event2);

            //触发leaving事件
            NodeInstanceEvent event4 = new NodeInstanceEvent(this);
            event4.Token=tk;
            event4.EventType=NodeInstanceEventEnum.NODEINSTANCE_LEAVING;//token 离开
            this.fireNodeEvent(event4);

            Boolean activiateDefaultCondition = true;//激活默认弧线的标志
            ITransitionInstance defaultTransInst = null;
            //找到所有开始节点的输出弧
            for (int i = 0; LeavingTransitionInstances != null && i < LeavingTransitionInstances.Count; i++)
            {
                ITransitionInstance transInst = LeavingTransitionInstances[i];//开始节点的边的类型只能是transition
                String condition = transInst.Transition.Condition;
                //如果弧线的条件!=null 并且 =“default” ,那么弧线实例就是default的弧线了。
                if (condition != null && condition.Equals(ConditionConstant.DEFAULT))
                {
                    defaultTransInst = transInst;//记录default转移线,其他条件都未false,才执行它
                    continue;
                }

                Token token = new Token(); // 产生新的token
                token.IsAlive = true;
                token.ProcessInstance = processInstance;
                token.FromActivityId = tk.FromActivityId;
                token.StepNumber = tk.StepNumber + 1;//步骤号+1

                Boolean alive = transInst.take(token);//触发弧线的token
                if (alive)
                {
                    activiateDefaultCondition = false;
                }

            }
            if (defaultTransInst != null)//如果defaultTransInst!=null ,走的是default值的弧线
            {
                Token token = new Token();
                token.IsAlive = activiateDefaultCondition;//设置token为dead
                token.ProcessInstance = processInstance;
                token.FromActivityId = token.FromActivityId;
                token.StepNumber = tk.StepNumber + 1;
                defaultTransInst.take(token);
            }

            //触发completed事件
            NodeInstanceEvent event3 = new NodeInstanceEvent(this);
            event3.Token=tk;
            event3.EventType=NodeInstanceEventEnum.NODEINSTANCE_COMPLETED;
            this.fireNodeEvent(event3);
        }
Esempio n. 2
0
        public void run(IProcessInstance processInstance)
        {
            if (StartNodeInstance == null)
            {
                KernelException exception = new KernelException(processInstance,
                        this.WorkflowProcess,
                        "Error:NetInstance is illegal ,the startNodeInstance can NOT be NULL ");
                throw exception;
            }

            Token token = new Token();//初始化token
            token.IsAlive = true;//活动的
            token.ProcessInstance = processInstance;//对应流程实例
            token.Value = StartNodeInstance.Volume;//token容量
            token.StepNumber = 0;//步骤号,开始节点的第一步默认为0
            token.FromActivityId = TokenFrom.FROM_START_NODE;//从哪个节点来 "FROM_START_NODE" 规定的节点。

            //注意这里并没有保存token
            StartNodeInstance.fire(token);//启动开始节点
        }
        public static Token GetToken(IDataReader dr)
        {
            Token token = new Token();
            token.Id=Convert.ToString(dr["id"]);
            token.IsAlive=Convert.ToInt32(dr["alive"]) == 1 ? true : false;
            token.Value=Convert.ToInt32(dr["value"]);
            token.NodeId=Convert.ToString(dr["node_id"]);
            token.ProcessInstanceId=Convert.ToString(dr["processinstance_id"]);
            token.StepNumber=Convert.ToInt32(dr["step_number"]);
            token.FromActivityId=Convert.ToString(dr["from_activity_id"]);

            return token;
        }
        /// <summary>
        /// 自由流方法扩展,去除“同一执行线”的限制
        /// </summary>
        /// <param name="workItem"></param>
        /// <param name="targetActivityId"></param>
        /// <param name="comments"></param>
        public void completeWorkItemAndJumpToEx(IWorkItem workItem, String targetActivityId, String comments)
        {
            // 首先检查是否可以正确跳转
            WorkflowProcess workflowProcess = workItem.TaskInstance.WorkflowProcess;
            String thisActivityId = workItem.TaskInstance.ActivityId;
            TaskInstance thisTaskInst = (TaskInstance)workItem.TaskInstance;
            //如果是在同一条执行线上,那么可以直接跳过去,只是重复判断了是否在同一条执行线上
            Boolean isInSameLine = workflowProcess.isInSameLine(thisActivityId, targetActivityId);
            if (isInSameLine)
            {
                this.completeWorkItemAndJumpTo(workItem, targetActivityId, comments);
                return;
            }

            // 1)检查是否在同一个“执行线”上(关闭该检查,20091002)
            //		if (!isInSameLine) {
            //			throw new EngineException(
            //					thisTaskInst.ProcessInstanceId,
            //					thisTaskInst.WorkflowProcess,
            //					thisTaskInst.TaskId,
            //					"Jumpto refused because of the current activitgy and the target activity are NOT in the same 'Execution Thread'.");
            //		}

            // 2)检查目标Activity Form Task的数量(暂时关闭该检查项目)
            // Activity targetActivity =
            // (Activity)workflowProcess.findWFElementById(activityId);
            // int count = getFormTaskCount(targetActivity);
            // if (count!=1){
            // if (!isInSameLine) throw new
            // EngineException("Jumpto refused because of the  FORM-type-task count of the target activitgy  is NOT 1; the count is "+count);
            // }

            // 3)检查当前的 taskinstance是否可以结束
            IPersistenceService persistenceService = this.RuntimeContext.PersistenceService;

            Int32 aliveWorkItemCount = persistenceService.GetAliveWorkItemCountForTaskInstance(thisTaskInst.Id);
            if ( aliveWorkItemCount > 1)
            {
                throw new EngineException(
                        thisTaskInst.ProcessInstanceId,
                        thisTaskInst.WorkflowProcess,
                        thisTaskInst.TaskId,
                        "Jumpto refused because of current taskinstance can NOT be completed. some workitem of this taskinstance is in runing state or initialized state");
            }

            // 4)检查当前的activity instance是否可以结束
            if (workItem.TaskInstance.Activity.CompletionStrategy == FormTaskEnum.ALL)
            {
                Int32 aliveTaskInstanceCount4ThisActivity = persistenceService.GetAliveTaskInstanceCountForActivity(
                    workItem.TaskInstance.ProcessInstanceId, workItem.TaskInstance.ActivityId);
                if (aliveTaskInstanceCount4ThisActivity > 1)
                {// 大于1表明当前Activity不可以complete
                    throw new EngineException(
                            thisTaskInst.ProcessInstanceId,
                            thisTaskInst.WorkflowProcess,
                            thisTaskInst.TaskId,
                            "Jumpto refused because of current activity instance can NOT be completed. some task instance of this activity instance is in runing state or initialized state");
                }
            }

            //4)首先检查目标状态M是否存在冲突,如果存在冲突则不允许跳转;如果不存在冲突,则需要调整token
            List<IToken> allTokens = persistenceService.FindTokensForProcessInstance(thisTaskInst.ProcessInstanceId, null);
            WorkflowProcess thisProcess = thisTaskInst.WorkflowProcess;//找到当前的工作里模型
            List<String> aliveActivityIdsAfterJump = new List<String>();//计算跳转后,哪些activity节点复活
            aliveActivityIdsAfterJump.Add(targetActivityId);

            for (int i = 0; allTokens != null && i < allTokens.Count; i++)
            {
                IToken tokenTmp = allTokens[i];
                IWFElement workflowElement = thisProcess.findWFElementById(tokenTmp.NodeId); //找到拥有此token的工作流元素
                if ((workflowElement is Activity) && !workflowElement.Id.Equals(thisActivityId))
                {
                    //注意:不能自己跳转到自己,同时此工作流元素是activity类型
                    aliveActivityIdsAfterJump.Add(workflowElement.Id);

                    if (thisProcess.isReachable(targetActivityId, workflowElement.Id)
                        || thisProcess.isReachable(workflowElement.Id, targetActivityId))
                    {
                        throw new EngineException(
                                thisTaskInst.ProcessInstanceId,
                                thisTaskInst.WorkflowProcess,
                                thisTaskInst.TaskId,
                                "Jumpto refused because of the business-logic conflict!");

                    }
                }
            }

            //所有检查结束,开始执行跳转操作

            INetInstance netInstance = this.RuntimeContext.KernelManager.getNetInstance(
                    workflowProcess.Id,
                    workItem.TaskInstance.Version);
            if (netInstance == null)
            {
                throw new EngineException(thisTaskInst.ProcessInstanceId,
                        thisTaskInst.WorkflowProcess,
                        thisTaskInst.TaskId,
                        "Not find the net instance for workflow process [id=" + workflowProcess.Id + ", version=" + workItem.TaskInstance.Version + "]");
            }
            Object obj = netInstance.getWFElementInstance(targetActivityId);
            IActivityInstance targetActivityInstance = (IActivityInstance)obj;
            if (targetActivityInstance == null)
            {
                throw new EngineException(thisTaskInst.ProcessInstanceId, thisTaskInst.WorkflowProcess, thisTaskInst.TaskId,
                        "Not find the activity instance  for activity[process id=" + workflowProcess.Id + ", version=" + workItem.TaskInstance.Version + ",activity id=" + targetActivityId + "]");
            }

            if (this.RuntimeContext.IsEnableTrace)
            {
                ProcessInstanceTrace trace = new ProcessInstanceTrace();
                trace.ProcessInstanceId=workItem.TaskInstance.ProcessInstanceId;
                trace.StepNumber=workItem.TaskInstance.StepNumber + 1;
                trace.Type = ProcessInstanceTraceEnum.JUMPTO_TYPE;
                trace.FromNodeId=workItem.TaskInstance.ActivityId;
                trace.ToNodeId=targetActivityId;
                trace.EdgeId="";
                this.RuntimeContext.PersistenceService.SaveOrUpdateProcessInstanceTrace(trace);
            }

            //调整token布局
            List<Synchronizer> allSynchronizersAndEnds = new List<Synchronizer>();
            allSynchronizersAndEnds.AddRange(thisProcess.Synchronizers);
            allSynchronizersAndEnds.AddRange((IEnumerable<Synchronizer>)thisProcess.EndNodes.ToArray());
            for (int i = 0; i < allSynchronizersAndEnds.Count; i++)
            {
                Synchronizer synchronizer = allSynchronizersAndEnds[i];

                int volumn = 0;
                if (synchronizer is EndNode)
                {
                    volumn = synchronizer.EnteringTransitions.Count;
                }
                else
                {
                    volumn = synchronizer.EnteringTransitions.Count * synchronizer.LeavingTransitions.Count;
                }
                IToken tokenTmp = new Token();
                tokenTmp.NodeId = synchronizer.Id;
                tokenTmp.IsAlive = false;
                tokenTmp.ProcessInstanceId = thisTaskInst.ProcessInstanceId;
                tokenTmp.StepNumber = -1;

                List<String> incomingTransitionIds = new List<String>();
                Boolean reachable = false;
                List<Transition> enteringTrans = synchronizer.EnteringTransitions;
                for (int m = 0; m < aliveActivityIdsAfterJump.Count; m++)
                {
                    String aliveActivityId = aliveActivityIdsAfterJump[m];
                    if (thisProcess.isReachable(aliveActivityId, synchronizer.Id))
                    {
                        Transition trans = null;
                        reachable = true;
                        for (int j = 0; j < enteringTrans.Count; j++)
                        {
                            trans = enteringTrans[j];
                            Node fromNode = trans.FromNode;
                            if (thisProcess.isReachable(aliveActivityId, fromNode.Id))
                            {
                                if (!incomingTransitionIds.Contains(trans.Id))
                                {
                                    incomingTransitionIds.Add(trans.Id);
                                }
                            }
                        }
                    }
                }
                if (reachable)
                {
                    tokenTmp.Value = volumn - (incomingTransitionIds.Count * volumn / enteringTrans.Count);

                    IToken virtualToken = getJoinInfo(allTokens, synchronizer.Id); //获取一个虚拟的综合性token

                    if (virtualToken != null)
                    {
                        persistenceService.DeleteTokensForNode(thisTaskInst.ProcessInstanceId, synchronizer.Id);
                    }

                    if (tokenTmp.Value != 0)
                    {
                        tokenTmp.ProcessInstance = thisTaskInst.AliveProcessInstance;
                        persistenceService.SaveOrUpdateToken(tokenTmp);
                    }
                }
            }
            this.completeWorkItem(workItem, targetActivityInstance, comments);
        }
Esempio n. 5
0
        public override void fire(IToken tk)
        {
            IJoinPoint joinPoint = synchronized(tk);
            if (joinPoint == null) return;
            IProcessInstance processInstance = tk.ProcessInstance;
            NodeInstanceEvent event2 = new NodeInstanceEvent(this);
            event2.Token=tk;
            event2.EventType=NodeInstanceEventEnum.NODEINSTANCE_FIRED;
            this.fireNodeEvent(event2);

            //在此事件监听器中,删除原有的token
            NodeInstanceEvent event4 = new NodeInstanceEvent(this);
            event4.Token=tk;
            event4.EventType=NodeInstanceEventEnum.NODEINSTANCE_LEAVING;
            this.fireNodeEvent(event4);

            //首先必须检查是否有满足条件的循环
            Boolean doLoop = false;//表示是否有满足条件的循环,false表示没有,true表示有。
            if (joinPoint.Alive)
            {
                IToken tokenForLoop = null;

                tokenForLoop = new Token(); // 产生新的token
                tokenForLoop.IsAlive=joinPoint.Alive;
                tokenForLoop.ProcessInstance=processInstance;
                tokenForLoop.StepNumber=joinPoint.StepNumber - 1;
                tokenForLoop.FromActivityId=joinPoint.FromActivityId;

                for (int i = 0; i < this.LeavingLoopInstances.Count; i++)
                {
                    ILoopInstance loopInstance = this.LeavingLoopInstances[i];
                    doLoop = loopInstance.take(tokenForLoop);
                    if (doLoop)
                    {
                        break;
                    }
                }
            }

            if (!doLoop)
            {
                NodeInstanceEvent event3 = new NodeInstanceEvent(this);
                event3.Token=tk;
                event3.EventType=NodeInstanceEventEnum.NODEINSTANCE_COMPLETED;
                this.fireNodeEvent(event3);
            }

            //        NodeInstanceEvent event4 = new NodeInstanceEvent(this);
            //        event4.setToken(tk);
            //        event4.setEventType(NodeInstanceEvent.NODEINSTANCE_LEAVING);
            //        this.fireNodeEvent(event4);
        }
        public void abortTaskInstanceEx(IWorkflowSession currentSession, IProcessInstance processInstance, 
            ITaskInstance thisTaskInst, String targetActivityId)
        {
            // 如果TaskInstance处于结束状态,则直接返回
            if (thisTaskInst.State == TaskInstanceStateEnum.COMPLETED || thisTaskInst.State == TaskInstanceStateEnum.CANCELED)
            {
                return;
            }

            // Initialized状态的TaskInstance也可以中止,20090830
            // if (taskInstance.State == ITaskInstance.INITIALIZED) {
            // WorkflowProcess process = taskInstance.getWorkflowProcess();
            // throw new EngineException(taskInstance.getProcessInstanceId(),
            // process,
            // taskInstance.getTaskId(),
            // "Complete task insatance failed.The state of the task insatnce[id=" +
            // taskInstance.getId() + "] is " + taskInstance.State);
            // }
            if (thisTaskInst.IsSuspended())
            {
                WorkflowProcess process = thisTaskInst.WorkflowProcess;
                throw new EngineException(thisTaskInst.ProcessInstanceId,
                        process, thisTaskInst.TaskId,
                        "Abort task insatance failed. The task instance [id="
                                + thisTaskInst.Id + "] is suspended");
            }

            //
            IPersistenceService persistenceService = this.RuntimeContext.PersistenceService;
            WorkflowProcess workflowProcess = thisTaskInst.WorkflowProcess;
            List<IToken> allTokens = null;
            List<String> aliveActivityIdsAfterJump = new List<String>();
            if (targetActivityId != null)
            {
                String thisActivityId = thisTaskInst.ActivityId;
                Boolean isInSameLine = workflowProcess.isInSameLine(thisActivityId, targetActivityId);

                if (isInSameLine)
                {
                    this.abortTaskInstance(currentSession, processInstance, thisTaskInst, targetActivityId);
                }

                //合法性检查
                allTokens = persistenceService.FindTokensForProcessInstance(thisTaskInst.ProcessInstanceId, null);

                aliveActivityIdsAfterJump.Add(targetActivityId);

                for (int i = 0; allTokens != null && i < allTokens.Count; i++)
                {
                    IToken tokenTmp = allTokens[i];
                    IWFElement workflowElement = workflowProcess.findWFElementById(tokenTmp.NodeId);
                    if ((workflowElement is Activity) && !workflowElement.Id.Equals(thisActivityId))
                    {
                        aliveActivityIdsAfterJump.Add(workflowElement.Id);

                        if (workflowProcess.isReachable(targetActivityId, workflowElement.Id)
                            || workflowProcess.isReachable(workflowElement.Id, targetActivityId))
                        {
                            throw new EngineException(
                                    thisTaskInst.ProcessInstanceId,
                                    thisTaskInst.WorkflowProcess,
                                    thisTaskInst.TaskId,
                                    "Abort refused because of the business-logic conflict!");

                        }
                    }
                }

                //1)检查是否在同一个“执行线”上(不做该检查,20091008)
                //			if (!isInSameLine) {
                //				throw new EngineException(
                //						taskInstance.getProcessInstanceId(),
                //						taskInstance.getWorkflowProcess(),
                //						taskInstance.getTaskId(),
                //						"Jumpto refused because of the current activitgy and the target activity are NOT in the same 'Execution Thread'.");
                //			}
            }

            INetInstance netInstance = this.RuntimeContext.KernelManager.getNetInstance(workflowProcess.Id, thisTaskInst.Version);
            IActivityInstance targetActivityInstance = null;
            if (targetActivityId != null)
            {
                targetActivityInstance = (IActivityInstance)netInstance.getWFElementInstance(targetActivityId);
            }

            IActivityInstance thisActivityInstance = (IActivityInstance)netInstance.getWFElementInstance(thisTaskInst.ActivityId);
            if (thisActivityInstance == null)
            {
                WorkflowProcess process = thisTaskInst.WorkflowProcess;
                throw new EngineException(thisTaskInst.ProcessInstanceId, process, thisTaskInst.TaskId,
                    "系统没有找到与activityId=" + thisTaskInst.ActivityId + "对应activityInstance,无法执行abort操作。");
            }

            if (targetActivityInstance != null)
            {
                ((TaskInstance)thisTaskInst).TargetActivityId=targetActivityInstance.Activity.Id;
            }

            // 第一步,首先Abort当前taskInstance
            persistenceService.AbortTaskInstance((TaskInstance)thisTaskInst);

            // 触发相应的事件
            TaskInstanceEvent e = new TaskInstanceEvent();
            e.Source=thisTaskInst;
            e.WorkflowSession=currentSession;
            e.ProcessInstance=processInstance;
            e.EventType = TaskInstanceEventEnum.AFTER_TASK_INSTANCE_COMPLETE;
            if (this.DefaultTaskInstanceEventListener != null)
            {
                this.DefaultTaskInstanceEventListener.onTaskInstanceEventFired(e);
            }

            this.fireTaskInstanceEvent(thisTaskInst, e);

            // 第二步,检查ActivityInstance是否可以结束
            if (!activityInstanceCanBeCompleted(thisTaskInst))
            {
                return;
            }

            // 第三步,尝试结束对应的activityInstance
            List<IToken> tokens = persistenceService.FindTokensForProcessInstance(thisTaskInst.ProcessInstanceId, thisTaskInst.ActivityId);
            // System.out.println("Inside TaskInstance.complete(targetActivityInstance):: tokens.size is "+tokens.size());
            if (tokens == null || tokens.Count == 0)
            {
                return;// 表明activityInstance已经结束了。
            }
            if (tokens.Count > 1)
            {
                WorkflowProcess process = thisTaskInst.WorkflowProcess;
                throw new EngineException(thisTaskInst.ProcessInstanceId, process, thisTaskInst.TaskId,
                    "与activityId=" + thisTaskInst.ActivityId + "对应的token数量(=" + tokens.Count + ")不正确,正确只能为1,因此无法完成complete操作");
            }
            IToken token = tokens[0];
            // stepNumber不相等,不允许执行结束操作。
            if (token.StepNumber != thisTaskInst.StepNumber)
            {
                return;
            }
            if (token.IsAlive == false)
            {
                WorkflowProcess process = thisTaskInst.WorkflowProcess;
                throw new EngineException(thisTaskInst.ProcessInstanceId, process, thisTaskInst.TaskId,
                    "与activityId=" + thisTaskInst.ActivityId + "对应的token.alive=false,因此无法完成complete操作");
            }

            token.ProcessInstance = processInstance;

            //调整token布局
            if (targetActivityId != null)
            {
                List<Synchronizer> allSynchronizersAndEnds = new List<Synchronizer>();
                allSynchronizersAndEnds.AddRange(workflowProcess.Synchronizers);
                allSynchronizersAndEnds.AddRange((IEnumerable<Synchronizer>)workflowProcess.EndNodes.ToArray());
                //allSynchronizersAndEnds.AddRange((List<Synchronizer>));
                for (int i = 0; i < allSynchronizersAndEnds.Count; i++)
                {
                    Synchronizer synchronizer = allSynchronizersAndEnds[i];
                    if (synchronizer.Name.Equals("Synchronizer4"))
                    {
                        //System.out.println(synchronizer.Name);
                    }
                    int volumn = 0;
                    if (synchronizer is EndNode)
                    {
                        volumn = synchronizer.EnteringTransitions.Count;
                    }
                    else
                    {
                        volumn = synchronizer.EnteringTransitions.Count * synchronizer.LeavingTransitions.Count;
                    }
                    IToken tokenTmp = new Token();
                    tokenTmp.NodeId = synchronizer.Id;
                    tokenTmp.IsAlive = false;
                    tokenTmp.ProcessInstanceId = thisTaskInst.ProcessInstanceId;
                    tokenTmp.StepNumber = -1;

                    List<String> incomingTransitionIds = new List<String>();
                    Boolean reachable = false;
                    List<Transition> enteringTrans = synchronizer.EnteringTransitions;
                    for (int m = 0; m < aliveActivityIdsAfterJump.Count; m++)
                    {
                        String aliveActivityId = aliveActivityIdsAfterJump[m];
                        if (workflowProcess.isReachable(aliveActivityId, synchronizer.Id))
                        {
                            Transition trans = null;
                            reachable = true;
                            for (int j = 0; j < enteringTrans.Count; j++)
                            {
                                trans = enteringTrans[j];
                                Node fromNode = (Node)trans.FromNode;
                                if (workflowProcess.isReachable(aliveActivityId, fromNode.Id))
                                {
                                    if (!incomingTransitionIds.Contains(trans.Id))
                                    {
                                        incomingTransitionIds.Add(trans.Id);
                                    }
                                }
                            }
                        }
                    }
                    if (reachable)
                    {
                        tokenTmp.Value = volumn - (incomingTransitionIds.Count * volumn / enteringTrans.Count);

                        IToken virtualToken = getJoinInfo(allTokens, synchronizer.Id);

                        if (virtualToken != null)
                        {
                            persistenceService.DeleteTokensForNode(thisTaskInst.ProcessInstanceId, synchronizer.Id);
                        }

                        if (tokenTmp.Value != 0)
                        {
                            tokenTmp.ProcessInstance = processInstance;
                            persistenceService.SaveOrUpdateToken(tokenTmp);
                        }
                    }
                }
            }
            thisActivityInstance.complete(token, targetActivityInstance);
        }
        /// <summary>
        /// 获取特定同步器的汇聚信息,如果该同步器已经存在token,则返回一个综合性的虚拟的token,否则返回null。
        /// </summary>
        /// <param name="allTokens"></param>
        /// <param name="synchronizerId"></param>
        /// <returns></returns>
        private IToken getJoinInfo(List<IToken> allTokens, String synchronizerId)
        {
            Boolean findTokens = false;
            Dictionary<String, IToken> tokensMap = new Dictionary<String, IToken>();
            for (int i = 0; i < allTokens.Count; i++)
            {
                IToken tmpToken = (IToken)allTokens[i];
                if (!tmpToken.NodeId.Equals(synchronizerId))
                {
                    continue;
                }
                findTokens = true;
                String tmpFromActivityId = tmpToken.FromActivityId;
                if (!tokensMap.ContainsKey(tmpFromActivityId))
                {
                    tokensMap.Add(tmpFromActivityId, tmpToken);
                }
                else
                {
                    IToken tmpToken2 = (IToken)tokensMap[tmpFromActivityId];
                    if (tmpToken2.StepNumber > tmpToken.StepNumber)
                    {
                        tokensMap.Add(tmpFromActivityId, tmpToken2);
                    }
                }
            }

            if (!findTokens) return null;
            IToken virtualToken = new Token();
            int stepNumber = 0;
            List<IToken> tokensList = new List<IToken>(tokensMap.Values);

            for (int i = 0; i < tokensList.Count; i++)
            {
                IToken _token = (IToken)tokensList[i];
                //Fixed by wmj2003  http://www.fireflow.org/viewthread.php?tid=1040&extra=page%3D1
                virtualToken.Value = virtualToken.Value == 0 ? 0 : virtualToken.Value + _token.Value;
                if (_token.IsAlive)
                {
                    virtualToken.IsAlive = true;
                    String oldFromActivityId = virtualToken.FromActivityId;
                    if (String.IsNullOrEmpty(oldFromActivityId.Trim()))
                    {
                        virtualToken.FromActivityId = _token.FromActivityId;
                    }
                    else
                    {
                        virtualToken.FromActivityId = oldFromActivityId + TokenFrom.FROM_ACTIVITY_ID_SEPARATOR + _token.FromActivityId;
                    }
                }
                if (_token.StepNumber > stepNumber)
                {
                    stepNumber = _token.StepNumber;
                }
            }

            virtualToken.StepNumber = stepNumber + 1;

            return virtualToken;
        }
        public IWorkItem withdrawWorkItem(IWorkItem workItem)
        {
            Activity thisActivity = workItem.TaskInstance.Activity;
            TaskInstance thisTaskInstance = (TaskInstance)workItem.TaskInstance;
            if ((int)workItem.State < 5)
            {//小于5的状态为活动状态
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Withdraw operation is refused! Current workitem is in running state!!");
            }
            //当前Activity只允许一个Form类型的Task
            if (thisActivity.getTasks().Count > 1)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Withdraw operation is refused! The activity[id=" + thisActivity.Id + "] has more than 1 tasks");
            }

            //汇签Task不允许撤销
            if (FormTaskEnum.ALL == thisTaskInstance.AssignmentStrategy)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Withdraw operation is refused! The assignment strategy for activity[id=" + thisActivity.Id + "] is 'ALL'");
            }
            // Activity targetActivity = null;
            // List targetActivityList = new ArrayList();
            IPersistenceService persistenceService = this.RuntimeContext.PersistenceService;
            List<ITaskInstance> targetTaskInstancesList = null;
            targetTaskInstancesList = persistenceService.FindTaskInstancesForProcessInstanceByStepNumber(
                thisTaskInstance.ProcessInstanceId, thisTaskInstance.StepNumber + 1);

            // String targetActivityId = workItem.getTaskInstance().getTargetActivityId();

            //如果targetTaskInstancesList为空或size 等于0,则表示流程实例执行了汇聚操作。
            if (targetTaskInstancesList == null || targetTaskInstancesList.Count == 0)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess,
                        thisTaskInstance.TaskId, "Withdraw operation is refused!Because the process instance has taken a join operation after this activity[id=" + thisActivity.Id + "].");
            }
            else
            {
                TaskInstance taskInstance = (TaskInstance)targetTaskInstancesList[0];
                if (!taskInstance.FromActivityId.Equals(thisTaskInstance.ActivityId))
                {
                    throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess,
                            thisTaskInstance.TaskId, "Withdraw operation is refused!Because the process instance has taken a join operation after this activity[id=" + thisActivity.Id + "].");
                }
            }

            for (int i = 0; targetTaskInstancesList != null && i < targetTaskInstancesList.Count; i++)
            {
                TaskInstance targetTaskInstanceTmp = (TaskInstance)targetTaskInstancesList[i];
                if (!targetTaskInstanceTmp.CanBeWithdrawn)
                {
                    //说明已经有某些WorkItem处于已签收状态,或者已经处于完毕状态,此时不允许退回
                    throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                            "Withdraw operation is refused! Some task instances of the  next activity[id=" + targetTaskInstanceTmp.ActivityId + "] are not in 'Initialized' state");
                }
            }

            INetInstance netInstance = this.RuntimeContext.KernelManager.getNetInstance(thisTaskInstance.ProcessId, workItem.TaskInstance.Version);
            if (netInstance == null)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess,
                        thisTaskInstance.TaskId, "Withdraw operation failed.Not find the net instance for workflow process [id=" + thisTaskInstance.ProcessId + ", version=" + workItem.TaskInstance.Version + "]");
            }
            Object obj = netInstance.getWFElementInstance(thisTaskInstance.ActivityId);
            IActivityInstance thisActivityInstance = (IActivityInstance)obj;

            //一切检查通过之后进行“收回”处理

            IWorkflowSession session = ((IWorkflowSessionAware)workItem).CurrentWorkflowSession;
            session.setWithdrawOrRejectOperationFlag(true);
            int newStepNumber = (int)thisTaskInstance.StepNumber + 2;
            try
            {
                DynamicAssignmentHandler dynamicAssignmentHandler = new DynamicAssignmentHandler();
                List<String> actorIds = new List<String>();
                actorIds.Add(workItem.ActorId);
                dynamicAssignmentHandler.ActorIdsList=actorIds;
                ((WorkflowSession)session).setCurrentDynamicAssignmentHandler(dynamicAssignmentHandler);

                //1、首先将后续环节的TaskInstance极其workItem变成Canceled状态
                List<String> targetActivityIdList = new List<String>();

                StringBuilder theFromActivityIds = new StringBuilder();
                for (int i = 0; i < targetTaskInstancesList.Count; i++)
                {
                    TaskInstance taskInstTemp = (TaskInstance)targetTaskInstancesList[i];

                    persistenceService.AbortTaskInstance(taskInstTemp);

                    if (!(targetActivityIdList.IndexOf(taskInstTemp.ActivityId) >= 0))
                    {
                        targetActivityIdList.Add(taskInstTemp.ActivityId);
                        if (theFromActivityIds.Length == 0)
                        {
                            theFromActivityIds.Append(taskInstTemp.ActivityId);
                        }
                        else
                        {
                            theFromActivityIds.Append(TokenFrom.FROM_ACTIVITY_ID_SEPARATOR).Append(taskInstTemp.ActivityId);
                        }
                    }
                }

                persistenceService.DeleteTokensForNodes(thisTaskInstance.ProcessInstanceId, targetActivityIdList);

                if (this.RuntimeContext.IsEnableTrace)
                {
                    for (int i = 0; targetActivityIdList != null && i < targetActivityIdList.Count; i++)
                    {
                        String tmpActId = (String)targetActivityIdList[i];
                        ProcessInstanceTrace trace = new ProcessInstanceTrace();
                        trace.ProcessInstanceId=thisTaskInstance.ProcessInstanceId;
                        trace.StepNumber=newStepNumber;
                        trace.Type=ProcessInstanceTraceEnum.WITHDRAW_TYPE;
                        trace.FromNodeId=tmpActId;
                        trace.ToNodeId=thisActivity.Id;
                        trace.EdgeId="";
                        this.RuntimeContext.PersistenceService.SaveOrUpdateProcessInstanceTrace(trace);
                    }
                }

                ITransitionInstance thisLeavingTransitionInstance = (ITransitionInstance)thisActivityInstance.LeavingTransitionInstances[0];
                ISynchronizerInstance synchronizerInstance = (ISynchronizerInstance)thisLeavingTransitionInstance.LeavingNodeInstance;
                if (synchronizerInstance.EnteringTransitionInstances.Count > 1)
                {
                    Token supplementToken = new Token();
                    ((Token)supplementToken).IsAlive = false;
                    ((Token)supplementToken).NodeId = synchronizerInstance.Synchronizer.Id;
                    supplementToken.ProcessInstanceId = thisTaskInstance.ProcessInstanceId;
                    supplementToken.ProcessInstance = ((TaskInstance)thisTaskInstance).AliveProcessInstance;
                    supplementToken.FromActivityId = "Empty(created by withdraw)";
                    supplementToken.StepNumber = newStepNumber;
                    supplementToken.Value = synchronizerInstance.Volume - thisLeavingTransitionInstance.Weight;
                    persistenceService.SaveOrUpdateToken(supplementToken);
                }

                Token newToken = new Token();
                ((Token)newToken).IsAlive = true;
                ((Token)newToken).NodeId = workItem.TaskInstance.ActivityId;
                newToken.ProcessInstanceId = thisTaskInstance.ProcessInstanceId;
                newToken.ProcessInstance = ((TaskInstance)thisTaskInstance).AliveProcessInstance;
                newToken.FromActivityId = theFromActivityIds.ToString();
                newToken.StepNumber = newStepNumber;
                newToken.Value = 0;
                persistenceService.SaveOrUpdateToken(newToken);

                this.createTaskInstances(newToken, thisActivityInstance);

                List<IWorkItem> workItems = persistenceService.FindTodoWorkItems(workItem.ActorId, workItem.TaskInstance.ProcessId, workItem.TaskInstance.TaskId);
                if (workItems == null || workItems.Count == 0)
                {
                    throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Withdraw operation failed.No work item has been created for Task[id=" + thisTaskInstance.TaskId + "]");
                }
                if (workItems.Count > 1)
                {
                    throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Withdraw operation failed.More than one work item have been created for Task[id=" + thisTaskInstance.TaskId + "]");
                }

                return (IWorkItem)workItems[0];
            }
            finally
            {
                session.setWithdrawOrRejectOperationFlag(false);
            }
        }
        public void rejectWorkItem(IWorkItem workItem, String comments)
        {
            Activity thisActivity = workItem.TaskInstance.Activity;
            TaskInstance thisTaskInstance = (TaskInstance)workItem.TaskInstance;
            if ((int)workItem.State > 5 || workItem.TaskInstance.IsSuspended())
            {//处于非活动状态,或者被挂起,则不允许reject
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Reject operation refused!Current work item is completed or the correspond task instance is suspended!!");
            }
            //当前Activity只允许一个Form类型的Task
            if (thisActivity.getTasks().Count > 1)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Reject operation refused!The correspond activity has more than 1 tasks");
            }
            //汇签Task不允许Reject
            if (FormTaskEnum.ALL == thisTaskInstance.AssignmentStrategy)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                        "Reject operation refused!The assignment strategy is 'ALL'");
            }
            //----added by wmj2003 20090915 ---start---
            //处理拒收的边界问题
            if (thisTaskInstance.FromActivityId == TokenFrom.FROM_START_NODE)
            {
                throw new EngineException(
                                thisTaskInstance.ProcessInstanceId,
                                thisTaskInstance.WorkflowProcess,
                                thisTaskInstance.TaskId,
                                "Reject operation refused!Because the from activityId equals " + TokenFrom.FROM_START_NODE);
            }
            //----added by wmj2003 20090915 ---end---

            IPersistenceService persistenceService = this.RuntimeContext.PersistenceService;
            List<ITaskInstance> siblingTaskInstancesList = null;

            siblingTaskInstancesList = persistenceService.FindTaskInstancesForProcessInstanceByStepNumber(
                workItem.TaskInstance.ProcessInstanceId, thisTaskInstance.StepNumber);

            //如果执行了split操作,则不允许reject
            if (siblingTaskInstancesList.Count > 1)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess, thisTaskInstance.TaskId,
                    "Reject operation refused!Because the process instance has taken a split operation.");
            }

            //检查From Activity中是否有ToolTask和SubflowTask
            List<String> fromActivityIdList = new List<String>();
            String[] tokenizer = thisTaskInstance.FromActivityId.Split(new String[] { TokenFrom.FROM_ACTIVITY_ID_SEPARATOR }, StringSplitOptions.RemoveEmptyEntries);//)new string[]{});
            fromActivityIdList.AddRange(tokenizer);
            //StringTokenizer tokenizer = new StringTokenizer(thisTaskInstance.FromActivityId, IToken.FROM_ACTIVITY_ID_SEPARATOR);
            //while (tokenizer.hasMoreTokens()) {
            //    fromActivityIdList.add(tokenizer.nextToken());
            //}
            WorkflowProcess workflowProcess = workItem.TaskInstance.WorkflowProcess;
            for (int i = 0; i < fromActivityIdList.Count; i++)
            {
                String fromActivityId = (String)fromActivityIdList[i];
                Activity fromActivity = (Activity)workflowProcess.findWFElementById(fromActivityId);
                List<Task> fromTaskList = fromActivity.getTasks();
                for (int j = 0; j < fromTaskList.Count; j++)
                {
                    Task task = (Task)fromTaskList[j];
                    if (TaskTypeEnum.TOOL == task.TaskType || TaskTypeEnum.SUBFLOW == task.TaskType)
                    {
                        throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess,
                                thisTaskInstance.TaskId, "Reject operation refused!The previous activity contains tool-task or subflow-task");
                    }
                }
            }
            //恢复所有的FromTaskInstance
            INetInstance netInstance = RuntimeContext.KernelManager.getNetInstance(workflowProcess.Id, workItem.TaskInstance.Version);
            if (netInstance == null)
            {
                throw new EngineException(thisTaskInstance.ProcessInstanceId, thisTaskInstance.WorkflowProcess,
                        thisTaskInstance.TaskId, "Not find the net instance for workflow process [id=" + workflowProcess.Id + ", version=" + workItem.TaskInstance.Version + "]");
            }

            //执行reject操作。
            IWorkflowSession session = ((IWorkflowSessionAware)workItem).CurrentWorkflowSession;
            session.setWithdrawOrRejectOperationFlag(true);
            int newStepNumber = (int)thisTaskInstance.StepNumber + 1;
            try
            {
                //首先将本WorkItem和TaskInstance cancel掉。
                workItem.Comments=comments;
                ((WorkItem)workItem).State = WorkItemEnum.CANCELED;
                ((WorkItem)workItem).EndTime=this.RuntimeContext.CalendarService.getSysDate();
                this.RuntimeContext.PersistenceService.SaveOrUpdateWorkItem(workItem);

                persistenceService.AbortTaskInstance(thisTaskInstance);

                //删除本环节的token
                persistenceService.DeleteTokensForNode(thisTaskInstance.ProcessInstanceId, thisTaskInstance.ActivityId);

                IActivityInstance fromActivityInstance = null;
                for (int i = 0; i < fromActivityIdList.Count; i++)
                {
                    String fromActivityId = (String)fromActivityIdList[i];
                    Object obj = netInstance.getWFElementInstance(fromActivityId);
                    fromActivityInstance = (IActivityInstance)obj;
                    Token newToken = new Token();
                    ((Token)newToken).IsAlive = true;
                    ((Token)newToken).NodeId = fromActivityId;
                    newToken.ProcessInstanceId = thisTaskInstance.ProcessInstanceId;
                    newToken.ProcessInstance = ((TaskInstance)thisTaskInstance).AliveProcessInstance;
                    newToken.FromActivityId = thisTaskInstance.ActivityId;
                    newToken.StepNumber = newStepNumber;
                    newToken.Value = 0;
                    persistenceService.SaveOrUpdateToken(newToken);

                    this.createTaskInstances(newToken, fromActivityInstance);

                    if (this.RuntimeContext.IsEnableTrace)
                    {
                        ProcessInstanceTrace trace = new ProcessInstanceTrace();
                        trace.ProcessInstanceId=thisTaskInstance.ProcessInstanceId;
                        trace.StepNumber=newStepNumber;
                        trace.Type=ProcessInstanceTraceEnum.REJECT_TYPE;
                        trace.FromNodeId=thisActivity.Id;
                        trace.ToNodeId=fromActivityId;
                        trace.EdgeId="";
                        this.RuntimeContext.PersistenceService.SaveOrUpdateProcessInstanceTrace(trace);
                    }
                }

                ITransitionInstance theLeavingTransitionInstance = (ITransitionInstance)fromActivityInstance.LeavingTransitionInstances[0];
                ISynchronizerInstance synchronizerInstance = (ISynchronizerInstance)theLeavingTransitionInstance.LeavingNodeInstance;
                if (synchronizerInstance.EnteringTransitionInstances.Count > fromActivityIdList.Count)
                {
                    Token supplementToken = new Token();
                    ((Token)supplementToken).IsAlive = false;
                    ((Token)supplementToken).NodeId = synchronizerInstance.Synchronizer.Id;
                    supplementToken.ProcessInstanceId = thisTaskInstance.ProcessInstanceId;
                    supplementToken.ProcessInstance = ((TaskInstance)thisTaskInstance).AliveProcessInstance;
                    supplementToken.FromActivityId = "EMPTY(created by reject)";
                    supplementToken.StepNumber = (int)thisTaskInstance.StepNumber + 1;
                    supplementToken.Value = synchronizerInstance.Volume - theLeavingTransitionInstance.Weight * fromActivityIdList.Count;
                    persistenceService.SaveOrUpdateToken(supplementToken);
                }
            }
            finally
            {
                session.setWithdrawOrRejectOperationFlag(false);
            }
        }
Esempio n. 10
0
        public override void fire(IToken tk)
        {
            //TODO 此处性能需要改善一下,20090312
            IJoinPoint joinPoint = synchronized(tk);
            if (joinPoint == null) return;

            //如果汇聚点的容量和同步器节点的容量相同
            IProcessInstance processInstance = tk.ProcessInstance;
            // Synchronize的fire条件应该只与joinPoint的value有关(value==volume),与alive无关
            NodeInstanceEvent event2 = new NodeInstanceEvent(this);
            event2.Token=tk;
            event2.EventType=NodeInstanceEventEnum.NODEINSTANCE_FIRED;
            this.fireNodeEvent(event2);

            //在此事件监听器中,删除原有的token
            NodeInstanceEvent event4 = new NodeInstanceEvent(this);
            event4.Token=tk;
            event4.EventType=NodeInstanceEventEnum.NODEINSTANCE_LEAVING;

            this.fireNodeEvent(event4);

            //首先必须检查是否有满足条件的循环,loop比transition有更高的优先级,
            //(只能够有一个loop的条件为true,流程定义的时候需要注意)
            Boolean doLoop = false;//表示是否有满足条件的循环,false表示没有,true表示有。
            if (joinPoint.Alive)
            {
                IToken tokenForLoop = null;

                tokenForLoop = new Token(); // 产生新的token
                tokenForLoop.IsAlive=joinPoint.Alive;
                tokenForLoop.ProcessInstance=processInstance;
                tokenForLoop.StepNumber=joinPoint.StepNumber - 1;
                tokenForLoop.FromActivityId=joinPoint.FromActivityId;

                for (int i = 0; i < this.LeavingLoopInstances.Count; i++)
                {
                    ILoopInstance loopInstance = this.LeavingLoopInstances[i];
                    doLoop = loopInstance.take(tokenForLoop);
                    if (doLoop)
                    {
                        break;
                    }
                }
            }
            if (!doLoop)
            {//如果没有循环,则执行transitionInstance
                //非顺序流转的需要生成新的token,
                Boolean activiateDefaultCondition = true;
                ITransitionInstance defaultTransInst = null;
                for (int i = 0; LeavingTransitionInstances != null && i < LeavingTransitionInstances.Count; i++)
                {
                    ITransitionInstance transInst = LeavingTransitionInstances[i];
                    String condition = transInst.Transition.Condition;
                    if (condition != null && condition.Equals(ConditionConstant.DEFAULT))
                    {
                        defaultTransInst = transInst;
                        continue;
                    }

                    Token token = new Token(); // 产生新的token
                    token.IsAlive=joinPoint.Alive;
                    token.ProcessInstance=processInstance;
                    token.StepNumber=joinPoint.StepNumber;
                    token.FromActivityId=joinPoint.FromActivityId;
                    Boolean alive = transInst.take(token);
                    if (alive)
                    {
                        activiateDefaultCondition = false;
                    }

                }
                if (defaultTransInst != null)
                {
                    Token token = new Token();
                    token.IsAlive=activiateDefaultCondition && joinPoint.Alive;
                    token.ProcessInstance=processInstance;
                    token.StepNumber=joinPoint.StepNumber;
                    token.FromActivityId=joinPoint.FromActivityId;
                    defaultTransInst.take(token);
                }

            }

            NodeInstanceEvent event3 = new NodeInstanceEvent(this);
            event3.Token=tk;
            event3.EventType=NodeInstanceEventEnum.NODEINSTANCE_COMPLETED;
            this.fireNodeEvent(event3);
        }