Exemplo n.º 1
0
        /// <summary>
        /// add States and Transitions in WIT
        /// </summary>
        /// <param name="wf">Handle to Workflow item</param>
        private void ProcessStatesAndTransitions(Workflow wf)
        {
            Logger.EnteredMethod(LogSource.CQ, wf);

            // get all states from CQ
            object[] cqStates = (object[])CQWrapper.GetStateDefNames(cqEntityDef);
            if (cqStates.Length > 0)
            {
                string[] states = new string[cqStates.Length];
                Logger.Write(LogSource.CQ, TraceLevel.Verbose, "No of CQ States: [{0}]", cqStates.Length);
                int l = 0;
                foreach (string aState in cqStates)
                {
                    Logger.Write(LogSource.CQ, TraceLevel.Verbose, "CQ State: [{0}]", aState);
                    State witState = new State();
                    witState.value = aState;

                    wf.WITDSTATES.Add(witState);

                    // add the state in states array
                    states[l++] = aState;
                }

                string   startState       = null;
                object[] cqActions        = (object[])CQWrapper.GetActionDefNames(cqEntityDef);
                string   submitActionName = null;
                foreach (string action in cqActions)
                {
                    Logger.Write(LogSource.CQ, TraceLevel.Verbose, "CQ Action: [{0}]", action);
                    int actType = CQWrapper.GetActionDefType(cqEntityDef, action);
                    if (actType == CQConstants.ACTION_SUBMIT)
                    {
                        submitActionName = action;
                        startState       = CQWrapper.GetActionDestStateName(cqEntityDef, submitActionName);
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Found Start State : From [\"\"] to [{0}]", startState);

                        // add a transition from NULL state to START state
                        Transition witTransition = new Transition();
                        witTransition.from = String.Empty;
                        witTransition.to   = startState;

                        // add the default reason as NEW for first transition
                        Reason transReason = new Reason();
                        transReason.value = submitActionName;

                        witTransition.REASONS.DEFAULTREASON = transReason;
                        wf.WITDTRANSITIONS.Add(witTransition);

                        break;
                    }
                }


                // find out all the duplicate and unduplicate actions and duplicate states
                List <string> unduplicateActions = new List <string>();
                List <string> duplicateStates    = new List <string>();
                object[]      allActions         = (object[])CQWrapper.GetActionDefNames(cqEntityDef);
                foreach (string action in allActions)
                {
                    int actionType = CQWrapper.GetActionDefType(cqEntityDef, action);
                    if (actionType == CQConstants.ACTION_DUPLICATE)
                    {
                        string dupActState = CQWrapper.GetActionDestStateName(cqEntityDef, action);
                        if (!string.IsNullOrEmpty(dupActState))
                        {
                            duplicateStates.Add(dupActState);
                        }

                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Duplicate Action : [{0}]", action);
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Duplicate State : [{0}]", dupActState);
                    }
                    else if (actionType == CQConstants.ACTION_UNDUPLICATE)
                    {
                        unduplicateActions.Add(action);
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "UnDuplicate Action : [{0}]", action);
                    }
                }

                // prepare the state transition matrix
                for (int dstState = 0; dstState < states.Length; dstState++)
                {
                    // visit all the source states which can lead to the current destination state
                    for (int srcState = 0; srcState < states.Length; srcState++)
                    {
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Calling DoesTransitionExist Source State: [{0}], Dest State: [{1}]", states[srcState], states[dstState]);
                        object[] transitions = (object[])CQWrapper.DoesTransitionExist(cqEntityDef, states[srcState], states[dstState]);

                        if (transitions != null && transitions.Length > 0)
                        {
                            Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Does Transition returned [{0}] transitions", transitions.Length);
                            Transition witTransition = new Transition();
                            witTransition.from = states[srcState];
                            witTransition.to   = states[dstState];

                            // add the reason as the ACTION defined in CQ
                            Reason transReason = new Reason();
                            transReason.value = (string)transitions.GetValue(0);

                            witTransition.REASONS.DEFAULTREASON = transReason;

                            wf.WITDTRANSITIONS.Add(witTransition);
                            Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Adding Transitions [{0}] to [{1}] with Reason [{2}]", states[srcState], states[dstState], transReason.value);
                        }
                        else
                        {
                            Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Does Transition returned No transitions");
                        }
                    }

                    // now for each duplicate action find out all the states that lead to duplicate action
                    // so that back transition could be added
                    for (int dupStateIndex = 0; dupStateIndex < duplicateStates.Count; dupStateIndex++)
                    {
                        string dupState = duplicateStates[dupStateIndex];
                        // here dststate is being used as the source state and the destination state is Duplicate
                        Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Calling DoesTransitionExist Source State: [{0}], Dest State: [{1}]", states[dstState], dupState);
                        object[] transitions = (object[])CQWrapper.DoesTransitionExist(cqEntityDef, states[dstState], dupState);

                        if (transitions != null && transitions.Length > 0)
                        {
                            Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Does Transition returned [{0}] transitions", transitions.Length);
                            bool found = false;
                            // if this transition is not already there..
                            foreach (Transition trans in wf.WITDTRANSITIONS)
                            {
                                if (TFStringComparer.WorkItemStateName.Equals(trans.from, dupState) &&
                                    TFStringComparer.WorkItemStateName.Equals(trans.to, states[dstState]))
                                {
                                    found = true;
                                    // add all the unduplicate actions name as allowed reasons
                                    foreach (string undupActionName in unduplicateActions)
                                    {
                                        // string undupActionName = (string)duplicateActions[dupStateIndex];
                                        if (trans.REASONS.DEFAULTREASON.Equals(undupActionName))
                                        {
                                            // reason already there.. skip this duplicate state and move to next state
                                            continue; // skip this reason and add other reasons
                                        }

                                        // check in other reasons
                                        if (trans.REASONS.REASON == null)
                                        {
                                            // no reasons added yet.. add this
                                            trans.REASONS.WITDREASON.Add(undupActionName);
                                        }
                                        else
                                        {
                                            // check if this reason already there
                                            if (!trans.REASONS.REASON.Contains(undupActionName))
                                            {
                                                trans.REASONS.REASON.Add(undupActionName);
                                            }
                                        }
                                    }
                                    // move to next state
                                    break;
                                } // end of if transition exist
                            }

                            if (!found)
                            {
                                // this back transition is not defined.. create it now
                                // add a unduplicate transition
                                Transition witTransition = new Transition();
                                witTransition.from = dupState;
                                witTransition.to   = states[dstState];

                                // add the reason as the ACTION defined in CQ
                                bool isFirst = true;
                                foreach (string undupActionName in unduplicateActions)
                                {
                                    Reason transReason = new Reason();
                                    transReason.value = undupActionName;
                                    if (isFirst)
                                    {
                                        witTransition.REASONS.DEFAULTREASON = transReason;
                                        isFirst = false;
                                    }
                                    else
                                    {
                                        witTransition.REASONS.WITDREASON.Add(transReason);
                                    }
                                }

                                wf.WITDTRANSITIONS.Add(witTransition);
                            }
                        }
                        else
                        {
                            Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Does Transition returned No transitions");
                        }
                    } // end of duplicate action handling
                }     // end of preparing state transition matrix for loop
            }         //if (cqStates.Length > 0)
            else
            {
                // if the current entity does not have any states the minimal
                // state model has top be created
                Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Creating Dummy Workflow for {0}", schemaXMLFileName);
                CreateDummyWorkflow(wf);
            }

            Logger.ExitingMethod(LogSource.CQ);
        } // end of ProcessStatesAndTransitions