Esempio n. 1
0
        /// <summary>
        /// Validate actual trace angainst expected trace.
        /// This method validates next same level expected step
        /// </summary>
        /// <param name="curExpIndex">expected trace step index</param>
        /// <param name="actualTrace">actual trace</param>
        /// <param name="startIndex">index to start searches from</param>
        /// <param name="lastTime">time last step occured at</param>
        /// <param name="mustBeAfter">subsequent step must occur after time specified</param>
        /// <returns>true if traces match</returns>
        private static bool Validate(TraceGroup currentTrace, int curExpIndex, int startIndex, DateTime lastTime, DateTime mustBeAfter)
        {
            // is this a last step to check?
            if (curExpIndex >= currentTrace.Steps.Count)
            {
                bool match = false;

                if (null == currentTrace.parent)
                {
                    //Oracle.LogDebugInfo("End of step list. Verifying completeness");
                    return(TraceValidator.VerifyAllStepsValidated());
                }
                else
                {
                    //Oracle.LogDebugInfo("Check next parent step");
                    if (currentTrace.Async)
                    {
                        match = TraceValidator.ValidateNextSibling(currentTrace.parent, currentTrace.indexInParent, currentTrace.startIndex);
                    }
                    else
                    {
                        if (currentTrace.ordered)
                        {
                            match = TraceValidator.ValidateNextSibling(currentTrace.parent, currentTrace.indexInParent, currentTrace.startIndex);
                        }
                        else
                        {
                            match = TraceValidator.ValidateNextSibling(currentTrace.parent, currentTrace.indexInParent, TraceValidator.GetMaxEndIndex(currentTrace));
                        }
                    }
                }

                return(match);
            }

            WorkflowTraceStep step = currentTrace.Steps[curExpIndex];

            if (step is TraceGroup)
            {
                // check inner composite step
                return(TraceValidator.ValidateFirst((TraceGroup)step, startIndex));
            }
            else if (step is DelayTrace)
            {
                mustBeAfter = lastTime.Add(((DelayTrace)step).TimeSpan);

                return(TraceValidator.Validate(currentTrace, curExpIndex + 1, startIndex, lastTime, mustBeAfter));
            }
            else if (step is IActualTraceStep)
            {
                int[] entryIndexes = TraceValidator.FindAllEntries((IActualTraceStep)step, startIndex, mustBeAfter);
                bool  match        = false;

                if (entryIndexes.Length == 0)
                {
                    // step not found
                    if (!step.Optional)
                    {
                        string msg = String.Format("Step '{0}' is not found. Start index {1}", step, startIndex);
                        //Oracle.LogDebugInfo("Adding error: {0}", msg);
                        TraceValidator.s_errorList.Add(msg);
                    }
                }
                else if (entryIndexes.Length == 1 &&
                         !step.Optional)
                {
                    // this branch can be commented out
                    // it's an optimization for the most common case

                    // only one option
                    int index = entryIndexes[0];

                    TraceValidator.MarkAsFound(index, out lastTime);
                    currentTrace.endIndexes[curExpIndex] = index;

                    if (currentTrace.ordered && !step.Async)
                    {
                        match = TraceValidator.Validate(currentTrace, curExpIndex + 1, index + 1, lastTime, mustBeAfter);
                    }
                    else
                    {
                        match = TraceValidator.Validate(currentTrace, curExpIndex + 1, startIndex, lastTime, mustBeAfter);
                    }
                }
                else
                {
                    // many options. try each choice until succeed
                    foreach (int index in entryIndexes)
                    {
                        TraceValidator.SetRestorePoint();
                        //this.Dump("After SetRestorePoint");
                        TraceValidator.MarkAsFound(index, out lastTime);
                        currentTrace.endIndexes[curExpIndex] = index;
                        //this.Dump("After mark as found");

                        if (currentTrace.ordered && !step.Async)
                        {
                            match = TraceValidator.Validate(currentTrace, curExpIndex + 1, entryIndexes[0] + 1, lastTime, mustBeAfter);
                        }
                        else
                        {
                            match = TraceValidator.Validate(currentTrace, curExpIndex + 1, startIndex, lastTime, mustBeAfter);
                        }

                        //this.Dump("After searched subsequent steps");

                        if (match)
                        {
                            TraceValidator.Commit();
                            //this.Dump("After Commit");
                            break;
                        }
                        else
                        {
                            TraceValidator.Rollback();
                            //this.Dump("After Rollback1");
                        }
                    }
                }

                if (!match && step.Optional)
                {
                    //Oracle.LogDebugInfo("Skipping optional step");
                    match = TraceValidator.Validate(currentTrace, curExpIndex + 1, startIndex, lastTime, mustBeAfter);
                }

                return(match);
            }
            else
            {
                throw new Exception(String.Format(
                                        "Internal validation error. Unknown step type found {0}",
                                        step.GetType().Name));
            }
        }