File: AuthoringOM\Filters\ActivityExecutionFilter.cs
Project: ndp\cdf\src\WF\Common\System.Workflow.ComponentModel.csproj (System.Workflow.ComponentModel)
namespace System.Workflow.ComponentModel
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
 
    internal abstract class ActivityExecutionFilter : ActivityExecutor, ISupportWorkflowChanges
    {
        #region ISupportWorkflowChanges Members
 
        public virtual void OnActivityAdded(ActivityExecutionContext executionContext, Activity addedActivity)
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
            if (addedActivity == null)
                throw new ArgumentNullException("addedActivity");
 
            NextDynamicChangeExecutorInChain(executionContext.Activity).OnActivityAdded(executionContext, addedActivity);
        }
        public virtual void OnActivityRemoved(ActivityExecutionContext executionContext, Activity removedActivity)
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
            if (removedActivity == null)
                throw new ArgumentNullException("removedActivity");
 
            NextDynamicChangeExecutorInChain(executionContext.Activity).OnActivityRemoved(executionContext, removedActivity);
        }
        public virtual void OnWorkflowChangesCompleted(ActivityExecutionContext executionContext)
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            NextDynamicChangeExecutorInChain(executionContext.Activity).OnWorkflowChangesCompleted(executionContext);
        }
        #endregion ISupportWorkflowChanges
 
        #region Execute, Cancel, Compensate and HandleFault
 
        public override ActivityExecutionStatus Execute(Activity activity, ActivityExecutionContext executionContext)
        {
            if (activity == null)
                throw new ArgumentNullException("activity");
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            return NextActivityExecutorInChain(executionContext.Activity).Execute(activity, executionContext);
        }
 
        public override ActivityExecutionStatus Cancel(Activity activity, ActivityExecutionContext executionContext)
        {
            if (activity == null)
                throw new ArgumentNullException("activity");
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            // If primary activity is Closed, then return, these filters might have acquired locks 
            // on to the primary activity, and in that case even if the activity has closed itself
            // it might get Cancel signal. So we don't want activity to get Cancel signal, when it 
            // already has declared itself Closed.
            ActivityExecutor nextActivityExecutor = NextActivityExecutorInChain(executionContext.Activity);
            if (!(nextActivityExecutor is ActivityExecutionFilter) && executionContext.Activity.HasPrimaryClosed)
                return ActivityExecutionStatus.Closed;
 
            return nextActivityExecutor.Cancel(activity, executionContext);
        }
        public override ActivityExecutionStatus HandleFault(Activity activity, ActivityExecutionContext executionContext, Exception exception)
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
            if (exception == null)
                throw new ArgumentNullException("exception");
 
            // If primary activity is Closed, then return, these filters might have acquired locks 
            // on to the primary activity, and in that case even if the activity has closed itself
            // it might get HandleFault signal. So we don't want activity to get HandleFault signal, when it 
            // already has declared itself Closed.
            ActivityExecutor nextActivityExecutor = NextActivityExecutorInChain(executionContext.Activity);
            if (!(nextActivityExecutor is ActivityExecutionFilter) && executionContext.Activity.HasPrimaryClosed)
                return ActivityExecutionStatus.Closed;
 
            return nextActivityExecutor.HandleFault(activity, executionContext, exception);
        }
        public override ActivityExecutionStatus Compensate(Activity activity, ActivityExecutionContext executionContext)
        {
            if (activity == null)
                throw new ArgumentNullException("activity");
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            return NextActivityExecutorInChain(executionContext.Activity).Compensate(activity, executionContext);
        }
 
        #endregion
 
        #region Helper Methods
 
        protected ActivityExecutor NextActivityExecutorInChain(Activity activity)
        {
            if (activity == null)
                throw new ArgumentNullException("activity");
 
            ActivityExecutor nextActivityExecutor = null;
            IList activityExecutors = ActivityExecutors.GetActivityExecutors(activity);
            int thisIndex = activityExecutors.IndexOf(this);
            if (thisIndex < activityExecutors.Count - 1)
                nextActivityExecutor = (ActivityExecutor)activityExecutors[thisIndex + 1];
            return nextActivityExecutor;
        }
        protected ISupportWorkflowChanges NextDynamicChangeExecutorInChain(Activity activity)
        {
            return NextActivityExecutorInChain(activity) as ISupportWorkflowChanges;
        }
        #endregion
    }
}