/// <summary>
        /// Add initialized active transition to the collection of active transitions
        /// </summary>
        /// <param name="at"></param>
        private void AddActiveTransition(TaskShell at)
        {
            if (at.CorrelationId == null) throw new Exception("Correlation id required");
            if (at.Tokens.Count == 0) throw new Exception("Cannot add a transition without tokens");
            Debug.Assert(InstanceId == at.ProcessInstanceId);
            Debug.Assert(Definition.GetTask(at.TaskId) != null);
            //find shared transitions...
            IDictionary<string, TaskShell> sharedTrans = new Dictionary<string, TaskShell>();
            foreach (string tid in at.Tokens)
            {
                Token t = GetToken(tid);
                foreach (string atid in t.ActiveTransitions)
                {
                    if (!sharedTrans.ContainsKey(atid))
                        sharedTrans[atid] = GetActiveTransition(atid);
                }
            }
            List<TaskShell> strans = new List<TaskShell>(sharedTrans.Values);
            if (strans.Count > 0)
            {
                log.Info("Transition shares the same tokens with {0} active transitions.");
                if (strans.Count == 1)
                {
                    strans[0].SharedId = strans[0].CorrelationId;
                }
                at.SharedId = strans[0].SharedId;
                foreach (TaskShell at2 in strans) Debug.Assert(at2.SharedId == at.SharedId);
            }

            Task tsk = Definition.GetTask(at.TaskId);
            _activeTransitions[at.CorrelationId] = at;
            IList<TaskShell> ats;
            if (!_activeTaskTransitions.TryGetValue(at.TaskId, out ats))
            {
                ats = new List<TaskShell>();
                _activeTaskTransitions[at.TaskId] = ats;
            }
            ats.Add(at);
            foreach (string tokid in at.Tokens)
            {
                Token tok = GetToken(tokid);
                tok.ActiveTransitions.Add(at.CorrelationId);
            }
        }
Example #2
0
 private TaskShell CreateActiveTransitionForTask(Task tsk)
 {
     TaskShell ts;
     if (tsk.IsMultiInstance)
     {
         ts = new MultiTaskShell();
     }
     else
     {
         ts = new TaskShell();
     }
     ts.TaskId = tsk.Id;
     ts.CorrelationId = GetNextTransitionId();
     ts.SetProcessInstance(this);
     ts.ParentCallback = this;
     ts.EnvironmentContext = this.Environment;
     return ts;
 }
 /// <summary>
 /// Create input data for transition by executing task input data bindings.
 /// TODO: Implement
 /// All task input variables have to be bound...
 /// 1. execute data bindings - get input variables in xml
 /// 2. validate the xml document
 /// 3. add local variables initial values
 /// </summary>
 /// <param name="at"></param>
 private void TransferDataToTransition(TaskShell at)
 {
     log.Debug("Transferring data to transition {0}", at.CorrelationId);
     at.TransferInputDataToTask(GetProcessDataSource());
 }
        /// <summary>
        /// This function is responsible for updating net status after transition has fired.
        /// It consumes transition input tokens and produces tokens in transition output places.
        /// Also, transition input conditions are evaluated before creating output tokens.
        /// </summary>
        /// <param name="at"></param>
        private void UpdateNetStatusAfterTransition(TaskShell at)
        {
            Task tsk = Definition.GetTask(at.TaskId);
            foreach (string tokid in at.Tokens)
            {
                Token tok = GetToken(tokid);
                Debug.Assert(tok.Status == TokenStatus.LOCKED_ALLOCATED);
                Debug.Assert(tok.ActiveTransitions.Count == 1);
                Debug.Assert(tok.ActiveTransitions[0] == at.CorrelationId);
                tok.Status = TokenStatus.CONSUMED;
            }

            IList<Token> newTokens = new List<Token>();
            if (tsk.SplitType == JoinType.AND)
            {
                foreach (Flow fl in tsk.FlowsOut)
                {
                    if (fl.InputCondition != null && fl.InputCondition.Length > 0) throw new Exception();
                    Token t = CreateNewTokenInPlace(fl.To.Id);
                    newTokens.Add(t);
                }
            }
            else if (tsk.SplitType == JoinType.XOR)
            {
                IList<Flow> flows = tsk.FlowsOutOrdered;
                for (int i = 0; i < flows.Count; i++)
                {
                    if (i == flows.Count - 1) //last flow - the default one
                    {
                        Token t = CreateNewTokenInPlace(flows[i].To.Id);
                        log.Debug("Produced token in default flow: {0}, token: {1}", flows[i].ToString(), t.TokenId);
                        newTokens.Add(t);
                    }
                    else
                    {
                        if (EvaluateFlowInputCondition(flows[i]))
                        {
                            Token t = CreateNewTokenInPlace(flows[i].To.Id);
                            log.Debug("Produced token in flow: {0}, token: {1}", flows[i].ToString(), t.TokenId);
                            newTokens.Add(t);
                            break;
                        }
                    }
                }
            }
            else if (tsk.SplitType == JoinType.OR)
            {
                IList<Flow> flows = tsk.FlowsOutOrdered;
                for (int i = 0; i < flows.Count; i++)
                {
                    if (EvaluateFlowInputCondition(flows[i]))
                    {
                        Token t = CreateNewTokenInPlace(flows[i].To.Id);
                        log.Debug("Produced token in flow: {0}, token: {1}", flows[i].ToString(), t.TokenId);
                        newTokens.Add(t);
                    }
                }
            }
            else throw new Exception();
            if (newTokens.Count == 0)
                throw new ApplicationException("No tokens were produced after transition " + at.CorrelationId);
            foreach (Token t in newTokens)
            {
                t.Status = TokenStatus.READY;
                AddToken(t);
            }
        }
 /// <summary>
 /// Initiate task
 /// </summary>
 /// <param name="at"></param>
 private void InitiateTransition(TaskShell at)
 {
     log.Info("Initiating transition {0}", at.TaskId);
     TransferDataToTransition(at);
     at.InitiateTask();
 }
 /// <summary>
 /// Extract output data from finished transition by executing task output data bindings
 /// </summary>
 /// <param name="at"></param>
 private void TransferDataFromTransition(TaskShell at)
 {
     at.ReceiveOutputDataFromTask(GetProcessVariablesContainer());
     ValidateProcessInternalData();
 }
        /// <summary>
        /// Execute immediate transition
        /// </summary>
        /// <param name="at"></param>
        private void ExecuteTransition(TaskShell at)
        {
            Debug.Assert(at.IsImmediate);
            TransferDataToTransition(at);
            foreach (string tokId in at.Tokens)
            {
                Token tok1 = GetToken(tokId);
                tok1.Status = TokenStatus.LOCKED_ENABLED;
            }
            at.ExecuteTask();

            //not needed (because of transition callback)
            //OnTransitionCompleted(at.CorrelationId);
        }
 /// <summary>
 /// Return a list of transitions sharing some tokens with specified transition
 /// </summary>
 /// <param name="at"></param>
 /// <returns></returns>
 private IList<TaskShell> GetSharedActiveTransitionsForTransition(TaskShell at)
 {
     IDictionary<string, TaskShell> dict = new Dictionary<string, TaskShell>();
     foreach (string tokid in at.Tokens)
     {
         Token t = GetToken(tokid);
         foreach (string atid in t.ActiveTransitions)
         {
             if (dict.ContainsKey(atid)) continue;
             TaskShell at2 = GetActiveTransition(atid);
             if (at2 == at) continue;
             if (at2.Status == TransitionStatus.ENABLED)
             {
                 dict[atid] = at2;
             }
         }
     }
     return new List<TaskShell>(dict.Values);
 }
 /// <summary>
 /// Cancel active transition instance
 /// How do we do that?
 /// 1. Do activity-specific cancellation
 /// 2. Update status of each input token: if it has no more enabled transitions, put it into READY state. Otherwise, leave it in WAITING_TASK
 /// </summary>
 /// <param name="at"></param>
 private void CancelActiveTransition(TaskShell at)
 {
     log.Info("Cancelling transition {0}", at.CorrelationId);
     if (at.IsImmediate) throw new Exception("Cannot cancel an immediate transition");
     if (at.Status != TransitionStatus.ENABLED && at.Status != TransitionStatus.STARTED) throw new Exception("Invalid transition status");
     at.CancelTask();
     Debug.Assert(at.Status == TransitionStatus.CANCELLED);
     foreach (string t in at.Tokens)
     {
         Token tok = GetToken(t);
         Debug.Assert(tok.Status == TokenStatus.LOCKED_ENABLED || tok.Status == TokenStatus.LOCKED_ALLOCATED);
         Debug.Assert(tok.ActiveTransitions.Contains(at.CorrelationId));
         if (!tok.ActiveTransitions.Remove(at.CorrelationId)) throw new Exception("Error removing transition id from token"); //should never happen
         if (tok.ActiveTransitions.Count == 0)
         {
             tok.Status = TokenStatus.READY;
         }
     }
     ActiveTransitionCancelled ac = new ActiveTransitionCancelled();
     ac.CorrelationId = at.CorrelationId;
     ac.DefinitionId = ProcessDefinitionId;
     ac.InstanceId = InstanceId;
     ac.TaskId = at.TaskId;
     ac.TaskType = Definition.GetTask(at.TaskId).GetType().Name;
     NotifyProcessEvent(ac);
 }
        /// <summary>
        /// Add initialized active transition to the collection of active transitions
        /// Updates transition list for each input token of at. 
        /// </summary>
        /// <param name="at"></param>
        private void RegisterNewTransition(TaskShell at)
        {
            if (at.CorrelationId == null) throw new Exception("Correlation id required");
            if (at.Tokens.Count == 0) throw new Exception("Cannot add a transition without tokens");
            Debug.Assert(InstanceId == at.ProcessInstanceId);
            Debug.Assert(Definition.GetTask(at.TaskId) != null);

            _activeTransitions[at.CorrelationId] = at;

            foreach (string tokid in at.Tokens)
            {
                Token tok = GetToken(tokid);
                tok.ActiveTransitions.Add(at.CorrelationId);
            }
        }
 /// <summary>
 /// Initiate task
 /// </summary>
 /// <param name="at"></param>
 private void InitiateTransition(TaskShell at)
 {
     log.Info("Initiating transition {0}", at.TaskId);
     Debug.Assert(at.Tokens.Count > 0);
     foreach (string tokid in at.Tokens)
     {
         Token tok = GetToken(tokid);
         Debug.Assert(tok.Status == TokenStatus.READY || tok.Status == TokenStatus.WAITING || tok.Status == TokenStatus.LOCKED_ENABLED);
         Debug.Assert(tok.Status != TokenStatus.LOCKED_ENABLED || at.Tokens.Count == 1);
     }
     at.InitiateTask(GetProcessDataSource());
 }
        private TaskShell CreateActiveTransitionForTask(Task tsk)
        {
            if (tsk.IsMultiInstance)
            {
                MultiTaskShell mts = new MultiTaskShell(this, tsk.Id);
                mts.CorrelationId = GetNextTransitionId();
                mts.SetProcessInstance(this);
                mts.ParentCallback = this;
                return mts;
            }
            else
            {

                TaskShell ts = new TaskShell(this, tsk.Id);
                ts.CorrelationId = GetNextTransitionId();
                ts.SetProcessInstance(this);
                ts.ParentCallback = this;
                return ts;
            }
        }
Example #13
0
 public static TaskShell RestoreTaskShell(DataObject state)
 {
     string tname = (string)state["Type"];
     TaskShell ts;
     if (tname == "MultiTaskShell")
     {
         ts = new MultiTaskShell();
     }
     else if (tname == "TaskShell")
     {
         ts = new TaskShell();
     }
     else throw new Exception();
     ts.RestoreState(state);
     return ts;
 }