StateMachineWorkflowInstance.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / StateMachineWorkflowInstance.cs / 1305376 / StateMachineWorkflowInstance.cs

                            #pragma warning disable 1634, 1691 
namespace System.Workflow.Activities
{
    using System;
    using System.Xml.Serialization; 
    using System.ComponentModel;
    using System.ComponentModel.Design; 
    using System.Collections; 
    using System.Collections.ObjectModel;
    using System.Collections.Generic; 
    using System.Drawing;
    using System.Drawing.Design;
    using System.Reflection;
    using System.Workflow.Activities; 
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Design; 
    using System.ComponentModel.Design.Serialization; 
    using System.Workflow.ComponentModel.Compiler;
    using System.Security.Principal; 
    using System.Workflow.Runtime.Tracking;
    using System.Diagnostics;
    using System.Workflow.Runtime;
 
    public sealed class StateMachineWorkflowInstance
    { 
        private Guid _instanceId; 
        private WorkflowInstance _workflowInstance;
        private SqlTrackingQuery _sqlTrackingQuery; 
        private SqlTrackingService _sqlTrackingService;
        private SqlTrackingWorkflowInstance _sqlTrackingWorkflowInstance;
        private StateMachineWorkflowActivity _stateMachineWorkflow;
        private WorkflowRuntime _runtime; 

        internal const string StateHistoryPropertyName = "StateHistory"; 
 
        public StateMachineWorkflowInstance(WorkflowRuntime runtime, Guid instanceId)
        { 
            if (runtime == null)
                throw new ArgumentNullException("runtime");
            if (instanceId == Guid.Empty)
                throw new ArgumentNullException("instanceId"); 
            _runtime = runtime;
            _instanceId = instanceId; 
            _workflowInstance = runtime.GetWorkflow(instanceId); 
            _stateMachineWorkflow = _workflowInstance.GetWorkflowDefinition() as StateMachineWorkflowActivity;
            if (_stateMachineWorkflow == null) 
                throw new ArgumentException(SR.GetStateMachineWorkflowRequired(), "instanceId");
        }

        public StateMachineWorkflowActivity StateMachineWorkflow 
        {
            get 
            { 
                // we always get a new definition, in case a
                // dynamic updated happened. The exception handling here 
                // is because after the workflow completes, we can no longer
                // retrieve the workflow definition. In this case, we
                // return the last retrieved definition
                try 
                {
                    _stateMachineWorkflow = (StateMachineWorkflowActivity)this.WorkflowInstance.GetWorkflowDefinition(); 
                } 
                catch (InvalidOperationException)
                { 
                }

                return _stateMachineWorkflow;
            } 
        }
 
        public Guid InstanceId 
        {
            get 
            {
                return _instanceId;
            }
        } 

        public WorkflowInstance WorkflowInstance 
        { 
            get
            { 
                return _workflowInstance;
            }
        }
 
        public StateActivity CurrentState
        { 
            get 
            {
                return GetCurrentState(); 
            }
        }

        public string CurrentStateName 
        {
            get 
            { 
                StateActivity currentState = this.CurrentState;
                if (currentState == null) 
                    return null;
                return currentState.QualifiedName;
            }
        } 

        private static ReadOnlyCollection GetLeafStates(StateActivity parentState) 
        { 
            if (parentState == null)
                throw new ArgumentNullException("parentState"); 

            List leafStates = new List();
            Queue states = new Queue();
            states.Enqueue(parentState); 
            while (states.Count > 0)
            { 
                StateActivity parent = states.Dequeue(); 
                foreach (Activity childActivity in parent.EnabledActivities)
                { 
                    StateActivity childState = childActivity as StateActivity;
                    if (childState != null)
                    {
                        if (StateMachineHelpers.IsLeafState(childState)) 
                            leafStates.Add(childState);
                        else 
                            states.Enqueue(childState); 
                    }
                } 
            }
            return leafStates.AsReadOnly();
        }
 

        public ReadOnlyCollection States 
        { 
            get
            { 
                StateMachineWorkflowActivity stateMachineWorkflow = this.StateMachineWorkflow;

#pragma warning disable 56503
 
                if (stateMachineWorkflow == null)
                    throw new InvalidOperationException(); 
 
                return GetLeafStates(stateMachineWorkflow);
 
#pragma warning restore 56503
            }
        }
 
        public ReadOnlyCollection PossibleStateTransitions
        { 
            get 
            {
                return GetPossibleStateTransitions(); 
            }
        }

        public ReadOnlyCollection StateHistory 
        {
            get 
            { 
                return GetStateHistory();
            } 
        }

        public void EnqueueItem(IComparable queueName, object item)
        { 
            EnqueueItem(queueName, item, null, null);
        } 
 
        public void EnqueueItem(IComparable queueName, object item, IPendingWork pendingWork, object workItem)
        { 
            this.WorkflowInstance.EnqueueItemOnIdle(queueName, item, pendingWork, workItem);
        }

        public void SetState(StateActivity targetState) 
        {
            if (targetState == null) 
                throw new ArgumentNullException("targetState"); 
            SetState(targetState.QualifiedName);
        } 

        public void SetState(string targetStateName)
        {
            if (targetStateName == null) 
                throw new ArgumentNullException("targetStateName");
            StateActivity targetState = FindActivityByQualifiedName(targetStateName) as StateActivity; 
            if (targetState == null) 
                throw new ArgumentOutOfRangeException("targetStateName");
            SetStateEventArgs eventArgs = new SetStateEventArgs(targetStateName); 
            this.WorkflowInstance.EnqueueItemOnIdle(System.Workflow.Activities.StateMachineWorkflowActivity.SetStateQueueName, eventArgs, null, null);
        }

        internal Activity FindActivityByQualifiedName(string id) 
        {
            return StateMachineHelpers.FindActivityByName(this.StateMachineWorkflow, id); 
        } 

        private StateActivity GetCurrentState() 
        {
            ReadOnlyCollection workflowQueuedInfos = this.WorkflowInstance.GetWorkflowQueueData();
            foreach (WorkflowQueueInfo queueInfo in workflowQueuedInfos)
            { 
                if (queueInfo.QueueName.Equals(StateMachineWorkflowActivity.SetStateQueueName))
                { 
                    if (queueInfo.SubscribedActivityNames.Count == 0) 
                        return null;
                    Debug.Assert(queueInfo.SubscribedActivityNames.Count == 1); 
                    StateMachineWorkflowActivity stateMachineWorkflow = this.StateMachineWorkflow;
                    StateActivity currentState = StateMachineHelpers.FindStateByName(stateMachineWorkflow, queueInfo.SubscribedActivityNames[0]);
                    return currentState;
                } 
            }
            return null; 
        } 

 
        private ReadOnlyCollection GetPossibleStateTransitions()
        {
            List targetStates = new List();
            ReadOnlyCollection workflowQueuedInfos = this.WorkflowInstance.GetWorkflowQueueData(); 
            StateMachineWorkflowActivity stateMachineWorkflow = this.StateMachineWorkflow;
            foreach (WorkflowQueueInfo queueInfo in workflowQueuedInfos) 
            { 
                foreach (string subscribedActivityName in queueInfo.SubscribedActivityNames)
                { 
                    Activity subscribedActivity = StateMachineHelpers.FindActivityByName(stateMachineWorkflow, subscribedActivityName);
                    IEventActivity eventActivity = subscribedActivity as IEventActivity;
                    if (eventActivity == null)
                        continue; 

                    EventDrivenActivity eventDriven = StateMachineHelpers.GetParentEventDriven(eventActivity); 
                    Debug.Assert(eventDriven != null); 
                    Queue activities = new Queue();
                    activities.Enqueue(eventDriven); 
                    while (activities.Count > 0)
                    {
                        Activity activity = activities.Dequeue();
                        SetStateActivity setState = activity as SetStateActivity; 
                        if (setState != null)
                        { 
                            targetStates.Add(setState.TargetStateName); 
                        }
                        else 
                        {
                            CompositeActivity compositeActivity = activity as CompositeActivity;
                            if (compositeActivity != null)
                            { 
                                foreach (Activity childActivity in compositeActivity.EnabledActivities)
                                { 
                                    activities.Enqueue(childActivity); 
                                }
                            } 
                        }
                    }
                }
            } 
            return targetStates.AsReadOnly();
        } 
 
        private ReadOnlyCollection GetStateHistory()
        { 
            if (_sqlTrackingService == null)
            {
                _sqlTrackingService = _runtime.GetService();
                if (_sqlTrackingService == null) 
                    throw new InvalidOperationException(SR.GetSqlTrackingServiceRequired());
            } 
 
            if (_sqlTrackingQuery == null)
                _sqlTrackingQuery = new SqlTrackingQuery(_sqlTrackingService.ConnectionString); 

            StateMachineWorkflowActivity stateMachineWorkflow;
            Stack stateHistory = new Stack();
 
            try
            { 
                stateMachineWorkflow = this.StateMachineWorkflow; 
            }
            catch (InvalidOperationException) 
            {
                return new ReadOnlyCollection(stateHistory.ToArray());
            }
 
            if (_sqlTrackingWorkflowInstance == null)
            { 
                bool result = _sqlTrackingQuery.TryGetWorkflow(_instanceId, out _sqlTrackingWorkflowInstance); 
                if (!result)
                { 
                    // Workflow has not started yet, so we just return an
                    // empty collection
                    return new ReadOnlyCollection(stateHistory.ToArray());
                } 
            }
 
            _sqlTrackingWorkflowInstance.Refresh(); 
            IList events = _sqlTrackingWorkflowInstance.UserEvents;
            foreach (UserTrackingRecord record in events) 
            {
                if (record.UserDataKey != StateActivity.StateChangeTrackingDataKey)
                    continue;
 
                string stateQualifiedName = record.UserData as string;
                if (stateQualifiedName == null) 
                    throw new InvalidOperationException(SR.GetInvalidUserDataInStateChangeTrackingRecord()); 

                StateActivity state = StateMachineHelpers.FindStateByName(stateMachineWorkflow, record.QualifiedName); 
                if (state == null)
                    throw new InvalidOperationException(SR.GetInvalidUserDataInStateChangeTrackingRecord());

                if (StateMachineHelpers.IsLeafState(state)) 
                    stateHistory.Push(stateQualifiedName);
            } 
 
            ReadOnlyCollection history = new ReadOnlyCollection(stateHistory.ToArray());
            return history; 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
#pragma warning disable 1634, 1691 
namespace System.Workflow.Activities
{
    using System;
    using System.Xml.Serialization; 
    using System.ComponentModel;
    using System.ComponentModel.Design; 
    using System.Collections; 
    using System.Collections.ObjectModel;
    using System.Collections.Generic; 
    using System.Drawing;
    using System.Drawing.Design;
    using System.Reflection;
    using System.Workflow.Activities; 
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Design; 
    using System.ComponentModel.Design.Serialization; 
    using System.Workflow.ComponentModel.Compiler;
    using System.Security.Principal; 
    using System.Workflow.Runtime.Tracking;
    using System.Diagnostics;
    using System.Workflow.Runtime;
 
    public sealed class StateMachineWorkflowInstance
    { 
        private Guid _instanceId; 
        private WorkflowInstance _workflowInstance;
        private SqlTrackingQuery _sqlTrackingQuery; 
        private SqlTrackingService _sqlTrackingService;
        private SqlTrackingWorkflowInstance _sqlTrackingWorkflowInstance;
        private StateMachineWorkflowActivity _stateMachineWorkflow;
        private WorkflowRuntime _runtime; 

        internal const string StateHistoryPropertyName = "StateHistory"; 
 
        public StateMachineWorkflowInstance(WorkflowRuntime runtime, Guid instanceId)
        { 
            if (runtime == null)
                throw new ArgumentNullException("runtime");
            if (instanceId == Guid.Empty)
                throw new ArgumentNullException("instanceId"); 
            _runtime = runtime;
            _instanceId = instanceId; 
            _workflowInstance = runtime.GetWorkflow(instanceId); 
            _stateMachineWorkflow = _workflowInstance.GetWorkflowDefinition() as StateMachineWorkflowActivity;
            if (_stateMachineWorkflow == null) 
                throw new ArgumentException(SR.GetStateMachineWorkflowRequired(), "instanceId");
        }

        public StateMachineWorkflowActivity StateMachineWorkflow 
        {
            get 
            { 
                // we always get a new definition, in case a
                // dynamic updated happened. The exception handling here 
                // is because after the workflow completes, we can no longer
                // retrieve the workflow definition. In this case, we
                // return the last retrieved definition
                try 
                {
                    _stateMachineWorkflow = (StateMachineWorkflowActivity)this.WorkflowInstance.GetWorkflowDefinition(); 
                } 
                catch (InvalidOperationException)
                { 
                }

                return _stateMachineWorkflow;
            } 
        }
 
        public Guid InstanceId 
        {
            get 
            {
                return _instanceId;
            }
        } 

        public WorkflowInstance WorkflowInstance 
        { 
            get
            { 
                return _workflowInstance;
            }
        }
 
        public StateActivity CurrentState
        { 
            get 
            {
                return GetCurrentState(); 
            }
        }

        public string CurrentStateName 
        {
            get 
            { 
                StateActivity currentState = this.CurrentState;
                if (currentState == null) 
                    return null;
                return currentState.QualifiedName;
            }
        } 

        private static ReadOnlyCollection GetLeafStates(StateActivity parentState) 
        { 
            if (parentState == null)
                throw new ArgumentNullException("parentState"); 

            List leafStates = new List();
            Queue states = new Queue();
            states.Enqueue(parentState); 
            while (states.Count > 0)
            { 
                StateActivity parent = states.Dequeue(); 
                foreach (Activity childActivity in parent.EnabledActivities)
                { 
                    StateActivity childState = childActivity as StateActivity;
                    if (childState != null)
                    {
                        if (StateMachineHelpers.IsLeafState(childState)) 
                            leafStates.Add(childState);
                        else 
                            states.Enqueue(childState); 
                    }
                } 
            }
            return leafStates.AsReadOnly();
        }
 

        public ReadOnlyCollection States 
        { 
            get
            { 
                StateMachineWorkflowActivity stateMachineWorkflow = this.StateMachineWorkflow;

#pragma warning disable 56503
 
                if (stateMachineWorkflow == null)
                    throw new InvalidOperationException(); 
 
                return GetLeafStates(stateMachineWorkflow);
 
#pragma warning restore 56503
            }
        }
 
        public ReadOnlyCollection PossibleStateTransitions
        { 
            get 
            {
                return GetPossibleStateTransitions(); 
            }
        }

        public ReadOnlyCollection StateHistory 
        {
            get 
            { 
                return GetStateHistory();
            } 
        }

        public void EnqueueItem(IComparable queueName, object item)
        { 
            EnqueueItem(queueName, item, null, null);
        } 
 
        public void EnqueueItem(IComparable queueName, object item, IPendingWork pendingWork, object workItem)
        { 
            this.WorkflowInstance.EnqueueItemOnIdle(queueName, item, pendingWork, workItem);
        }

        public void SetState(StateActivity targetState) 
        {
            if (targetState == null) 
                throw new ArgumentNullException("targetState"); 
            SetState(targetState.QualifiedName);
        } 

        public void SetState(string targetStateName)
        {
            if (targetStateName == null) 
                throw new ArgumentNullException("targetStateName");
            StateActivity targetState = FindActivityByQualifiedName(targetStateName) as StateActivity; 
            if (targetState == null) 
                throw new ArgumentOutOfRangeException("targetStateName");
            SetStateEventArgs eventArgs = new SetStateEventArgs(targetStateName); 
            this.WorkflowInstance.EnqueueItemOnIdle(System.Workflow.Activities.StateMachineWorkflowActivity.SetStateQueueName, eventArgs, null, null);
        }

        internal Activity FindActivityByQualifiedName(string id) 
        {
            return StateMachineHelpers.FindActivityByName(this.StateMachineWorkflow, id); 
        } 

        private StateActivity GetCurrentState() 
        {
            ReadOnlyCollection workflowQueuedInfos = this.WorkflowInstance.GetWorkflowQueueData();
            foreach (WorkflowQueueInfo queueInfo in workflowQueuedInfos)
            { 
                if (queueInfo.QueueName.Equals(StateMachineWorkflowActivity.SetStateQueueName))
                { 
                    if (queueInfo.SubscribedActivityNames.Count == 0) 
                        return null;
                    Debug.Assert(queueInfo.SubscribedActivityNames.Count == 1); 
                    StateMachineWorkflowActivity stateMachineWorkflow = this.StateMachineWorkflow;
                    StateActivity currentState = StateMachineHelpers.FindStateByName(stateMachineWorkflow, queueInfo.SubscribedActivityNames[0]);
                    return currentState;
                } 
            }
            return null; 
        } 

 
        private ReadOnlyCollection GetPossibleStateTransitions()
        {
            List targetStates = new List();
            ReadOnlyCollection workflowQueuedInfos = this.WorkflowInstance.GetWorkflowQueueData(); 
            StateMachineWorkflowActivity stateMachineWorkflow = this.StateMachineWorkflow;
            foreach (WorkflowQueueInfo queueInfo in workflowQueuedInfos) 
            { 
                foreach (string subscribedActivityName in queueInfo.SubscribedActivityNames)
                { 
                    Activity subscribedActivity = StateMachineHelpers.FindActivityByName(stateMachineWorkflow, subscribedActivityName);
                    IEventActivity eventActivity = subscribedActivity as IEventActivity;
                    if (eventActivity == null)
                        continue; 

                    EventDrivenActivity eventDriven = StateMachineHelpers.GetParentEventDriven(eventActivity); 
                    Debug.Assert(eventDriven != null); 
                    Queue activities = new Queue();
                    activities.Enqueue(eventDriven); 
                    while (activities.Count > 0)
                    {
                        Activity activity = activities.Dequeue();
                        SetStateActivity setState = activity as SetStateActivity; 
                        if (setState != null)
                        { 
                            targetStates.Add(setState.TargetStateName); 
                        }
                        else 
                        {
                            CompositeActivity compositeActivity = activity as CompositeActivity;
                            if (compositeActivity != null)
                            { 
                                foreach (Activity childActivity in compositeActivity.EnabledActivities)
                                { 
                                    activities.Enqueue(childActivity); 
                                }
                            } 
                        }
                    }
                }
            } 
            return targetStates.AsReadOnly();
        } 
 
        private ReadOnlyCollection GetStateHistory()
        { 
            if (_sqlTrackingService == null)
            {
                _sqlTrackingService = _runtime.GetService();
                if (_sqlTrackingService == null) 
                    throw new InvalidOperationException(SR.GetSqlTrackingServiceRequired());
            } 
 
            if (_sqlTrackingQuery == null)
                _sqlTrackingQuery = new SqlTrackingQuery(_sqlTrackingService.ConnectionString); 

            StateMachineWorkflowActivity stateMachineWorkflow;
            Stack stateHistory = new Stack();
 
            try
            { 
                stateMachineWorkflow = this.StateMachineWorkflow; 
            }
            catch (InvalidOperationException) 
            {
                return new ReadOnlyCollection(stateHistory.ToArray());
            }
 
            if (_sqlTrackingWorkflowInstance == null)
            { 
                bool result = _sqlTrackingQuery.TryGetWorkflow(_instanceId, out _sqlTrackingWorkflowInstance); 
                if (!result)
                { 
                    // Workflow has not started yet, so we just return an
                    // empty collection
                    return new ReadOnlyCollection(stateHistory.ToArray());
                } 
            }
 
            _sqlTrackingWorkflowInstance.Refresh(); 
            IList events = _sqlTrackingWorkflowInstance.UserEvents;
            foreach (UserTrackingRecord record in events) 
            {
                if (record.UserDataKey != StateActivity.StateChangeTrackingDataKey)
                    continue;
 
                string stateQualifiedName = record.UserData as string;
                if (stateQualifiedName == null) 
                    throw new InvalidOperationException(SR.GetInvalidUserDataInStateChangeTrackingRecord()); 

                StateActivity state = StateMachineHelpers.FindStateByName(stateMachineWorkflow, record.QualifiedName); 
                if (state == null)
                    throw new InvalidOperationException(SR.GetInvalidUserDataInStateChangeTrackingRecord());

                if (StateMachineHelpers.IsLeafState(state)) 
                    stateHistory.Push(stateQualifiedName);
            } 
 
            ReadOnlyCollection history = new ReadOnlyCollection(stateHistory.ToArray());
            return history; 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK