RuntimeTrackingProfile.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Tracking / RuntimeTrackingProfile.cs / 1305376 / RuntimeTrackingProfile.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Activities.Tracking 
{
    using System; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Linq; 
    using System.Text;
    using System.Collections.Specialized;
    using System.Collections.ObjectModel;
    using System.Runtime; 
    using System.Runtime.CompilerServices;
 
    class RuntimeTrackingProfile 
    {
        static RuntimeTrackingProfileCache profileCache; 

        List activityScheduledSubscriptions;
        List faultPropagationSubscriptions;
        List cancelRequestedSubscriptions; 
        Dictionary> activitySubscriptions;
        List customTrackingQuerySubscriptions; 
        Dictionary bookmarkSubscriptions; 
        Dictionary workflowEventSubscriptions;
 
        TrackingProfile associatedProfile;
        TrackingRecordPreFilter trackingRecordPreFilter;
        List activityNames;
 
        bool isRootNativeActivity;
 
        internal RuntimeTrackingProfile(TrackingProfile profile, Activity rootElement) 
        {
            this.associatedProfile = profile; 
            this.isRootNativeActivity = rootElement is NativeActivity;
            this.trackingRecordPreFilter = new TrackingRecordPreFilter();

            foreach (TrackingQuery query in this.associatedProfile.Queries) 
            {
                if (query is ActivityStateQuery) 
                { 
                    AddActivitySubscription((ActivityStateQuery)query);
                } 
                else if (query is WorkflowInstanceQuery)
                {
                    AddWorkflowSubscription((WorkflowInstanceQuery)query);
                } 
                else if (query is BookmarkResumptionQuery)
                { 
                    AddBookmarkSubscription((BookmarkResumptionQuery)query); 
                }
                else if (query is CustomTrackingQuery) 
                {
                    AddCustomTrackingSubscription((CustomTrackingQuery)query);
                }
                else if (query is ActivityScheduledQuery) 
                {
                    AddActivityScheduledSubscription((ActivityScheduledQuery)query); 
                } 
                else if (query is CancelRequestedQuery)
                { 
                    AddCancelRequestedSubscription((CancelRequestedQuery)query);
                }
                else if (query is FaultPropagationQuery)
                { 
                    AddFaultPropagationSubscription((FaultPropagationQuery)query);
                } 
            } 
        }
 
        static RuntimeTrackingProfileCache Cache
        {
            get
            { 
                // We do not take a lock here because a true singleton is not required.
                if (profileCache == null) 
                { 
                    profileCache = new RuntimeTrackingProfileCache();
                } 
                return profileCache;
            }
        }
 
        internal TrackingRecordPreFilter Filter
        { 
            get 
            {
                return this.trackingRecordPreFilter; 
            }
        }

        internal IEnumerable GetSubscribedActivityNames() 
        {
            return this.activityNames; 
        } 

        bool ShouldTrackActivity(ActivityInfo activityInfo, string queryName) 
        {
            if (activityInfo != null && queryName == "*")
            {
                if (this.isRootNativeActivity) 
                {
                    if (activityInfo.Instance.Activity.MemberOf.ParentId != 0) 
                    { 
                        return false;
                    } 
                }
                else
                {
                    if ((activityInfo.Instance.Activity.MemberOf.ParentId != 0) 
                        && (activityInfo.Instance.Activity.MemberOf.Parent.ParentId != 0))
                    { 
                        return false; 
                    }
                } 
            }

            return true;
        } 

        void AddActivityName(string name) 
        { 
            if (this.activityNames == null)
            { 
                this.activityNames = new List();
            }
            this.activityNames.Add(name);
        } 

        internal static RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingProfile profile, Activity rootElement) 
        { 
            return RuntimeTrackingProfile.Cache.GetRuntimeTrackingProfile(profile, rootElement);
        } 

        void AddActivitySubscription(ActivityStateQuery query)
        {
            this.trackingRecordPreFilter.TrackActivityStateRecords = true; 

            foreach (string state in query.States) 
            { 
                if (string.CompareOrdinal(state, "*") == 0)
                { 
                    this.trackingRecordPreFilter.TrackActivityStateRecordsClosedState = true;
                    this.trackingRecordPreFilter.TrackActivityStateRecordsExecutingState = true;
                    break;
                } 
                if (string.CompareOrdinal(state, ActivityStates.Closed) == 0)
                { 
                    this.trackingRecordPreFilter.TrackActivityStateRecordsClosedState = true; 
                }
                else if (string.CompareOrdinal(state, ActivityStates.Executing) == 0) 
                {
                    this.trackingRecordPreFilter.TrackActivityStateRecordsExecutingState = true;
                }
            } 

            if (this.activitySubscriptions == null) 
            { 
                this.activitySubscriptions = new Dictionary>();
            } 

            HybridCollection subscription;
            if (!this.activitySubscriptions.TryGetValue(query.ActivityName, out subscription))
            { 
                subscription = new HybridCollection();
                this.activitySubscriptions[query.ActivityName] = subscription; 
            } 
            subscription.Add((ActivityStateQuery)query);
            AddActivityName(query.ActivityName); 
        }

        void AddActivityScheduledSubscription(ActivityScheduledQuery activityScheduledQuery)
        { 
            this.trackingRecordPreFilter.TrackActivityScheduledRecords = true;
            if (this.activityScheduledSubscriptions == null) 
            { 
                this.activityScheduledSubscriptions = new List();
            } 
            this.activityScheduledSubscriptions.Add(activityScheduledQuery);
        }

        void AddCancelRequestedSubscription(CancelRequestedQuery cancelQuery) 
        {
            this.trackingRecordPreFilter.TrackCancelRequestedRecords = true; 
            if (this.cancelRequestedSubscriptions == null) 
            {
                this.cancelRequestedSubscriptions = new List(); 
            }
            this.cancelRequestedSubscriptions.Add(cancelQuery);
        }
 
        void AddFaultPropagationSubscription(FaultPropagationQuery faultQuery)
        { 
            this.trackingRecordPreFilter.TrackFaultPropagationRecords = true; 
            if (this.faultPropagationSubscriptions == null)
            { 
                this.faultPropagationSubscriptions = new List();
            }
            this.faultPropagationSubscriptions.Add(faultQuery);
        } 

        void AddBookmarkSubscription(BookmarkResumptionQuery bookmarkTrackingQuery) 
        { 
            this.trackingRecordPreFilter.TrackBookmarkResumptionRecords = true;
            if (this.bookmarkSubscriptions == null) 
            {
                this.bookmarkSubscriptions = new Dictionary();
            }
            //if duplicates are found, use only the first subscription for a given bookmark name. 
            if (!this.bookmarkSubscriptions.ContainsKey(bookmarkTrackingQuery.Name))
            { 
                this.bookmarkSubscriptions.Add(bookmarkTrackingQuery.Name, bookmarkTrackingQuery); 
            }
        } 

        void AddCustomTrackingSubscription(CustomTrackingQuery customQuery)
        {
            if (this.customTrackingQuerySubscriptions == null) 
            {
                this.customTrackingQuerySubscriptions = new List(); 
            } 
            this.customTrackingQuerySubscriptions.Add(customQuery);
        } 

        void AddWorkflowSubscription(WorkflowInstanceQuery workflowTrackingQuery)
        {
            this.trackingRecordPreFilter.TrackWorkflowInstanceRecords = true; 

            if (this.workflowEventSubscriptions == null) 
            { 
                this.workflowEventSubscriptions = new Dictionary();
            } 
            if (workflowTrackingQuery.HasStates)
            {
                foreach (string state in workflowTrackingQuery.States)
                { 
                    //if duplicates are found, use only the first subscription for a given state.
                    if (!this.workflowEventSubscriptions.ContainsKey(state)) 
                    { 
                        this.workflowEventSubscriptions.Add(state, workflowTrackingQuery);
                    } 
                }
            }
        }
 
        internal TrackingRecord Match(TrackingRecord record, bool shouldClone)
        { 
            TrackingQuery resultQuery = null; 
            if (record is WorkflowInstanceRecord)
            { 
                resultQuery = Match((WorkflowInstanceRecord)record);
            }
            else if (record is ActivityStateRecord)
            { 
                resultQuery = Match((ActivityStateRecord)record);
            } 
            else if (record is BookmarkResumptionRecord) 
            {
                resultQuery = Match((BookmarkResumptionRecord)record); 
            }
            else if (record is CustomTrackingRecord)
            {
                resultQuery = Match((CustomTrackingRecord)record); 
            }
            else if (record is ActivityScheduledRecord) 
            { 
                resultQuery = Match((ActivityScheduledRecord)record);
            } 
            else if (record is CancelRequestedRecord)
            {
                resultQuery = Match((CancelRequestedRecord)record);
            } 
            else if (record is FaultPropagationRecord)
            { 
                resultQuery = Match((FaultPropagationRecord)record); 
            }
 
            return resultQuery == null ? null : PrepareRecord(record, resultQuery, shouldClone);
        }

        ActivityStateQuery Match(ActivityStateRecord activityStateRecord) 
        {
            ActivityStateQuery query = null; 
            if (this.activitySubscriptions != null) 
            {
                HybridCollection eventSubscriptions; 
                //first look for a specific match, if not found, look for a generic match.
                if (this.activitySubscriptions.TryGetValue(activityStateRecord.Activity.Name, out eventSubscriptions))
                {
                    query = MatchActivityState(activityStateRecord, eventSubscriptions.AsReadOnly()); 
                }
 
                if (query == null && this.activitySubscriptions.TryGetValue("*", out eventSubscriptions)) 
                {
                    query = MatchActivityState(activityStateRecord, eventSubscriptions.AsReadOnly()); 

                    if ((query != null) && (this.associatedProfile.ImplementationVisibility == ImplementationVisibility.RootScope))
                    {
                        if (!ShouldTrackActivity(activityStateRecord.Activity, "*")) 
                        {
                            return null; 
                        } 
                    }
                } 
            }

            return query;
        } 

        static ActivityStateQuery MatchActivityState(ActivityStateRecord activityRecord, ReadOnlyCollection subscriptions) 
        { 
            ActivityStateQuery genericMatch = null;
            for (int i = 0; i < subscriptions.Count; i++) 
            {
                if (subscriptions[i].States.Contains(activityRecord.State))
                {
                    return subscriptions[i]; 
                }
                else if (subscriptions[i].States.Contains("*")) 
                { 
                    if (genericMatch == null)
                    { 
                        genericMatch = subscriptions[i];
                    }
                }
            } 
            return genericMatch;
        } 
 
        WorkflowInstanceQuery Match(WorkflowInstanceRecord workflowRecord)
        { 
            WorkflowInstanceQuery trackingQuery = null;
            if (this.workflowEventSubscriptions != null)
            {
                if (!this.workflowEventSubscriptions.TryGetValue(workflowRecord.State, out trackingQuery)) 
                {
                    this.workflowEventSubscriptions.TryGetValue("*", out trackingQuery); 
                } 
            }
            return trackingQuery; 
        }

        BookmarkResumptionQuery Match(BookmarkResumptionRecord bookmarkRecord)
        { 
            BookmarkResumptionQuery trackingQuery = null;
            if (this.bookmarkSubscriptions != null) 
            { 
                if (bookmarkRecord.BookmarkName != null)
                { 
                    this.bookmarkSubscriptions.TryGetValue(bookmarkRecord.BookmarkName, out trackingQuery);
                }
                if (trackingQuery == null)
                { 
                    this.bookmarkSubscriptions.TryGetValue("*", out trackingQuery);
                } 
            } 
            return trackingQuery;
        } 

        ActivityScheduledQuery Match(ActivityScheduledRecord activityScheduledRecord)
        {
            ActivityScheduledQuery query = null; 
            if (this.activityScheduledSubscriptions != null)
            { 
                for (int i = 0; i < this.activityScheduledSubscriptions.Count; i++) 
                {
                    //check specific and then generic 
                    string activityName = activityScheduledRecord.Activity == null ? null : activityScheduledRecord.Activity.Name;
                    if (string.CompareOrdinal(this.activityScheduledSubscriptions[i].ActivityName, activityName) == 0)
                    {
                        if (CheckSubscription(this.activityScheduledSubscriptions[i].ChildActivityName, activityScheduledRecord.Child.Name)) 
                        {
                            query = this.activityScheduledSubscriptions[i]; 
                            break; 
                        }
 
                    }
                    else if (string.CompareOrdinal(this.activityScheduledSubscriptions[i].ActivityName, "*") == 0)
                    {
                        if (CheckSubscription(this.activityScheduledSubscriptions[i].ChildActivityName, activityScheduledRecord.Child.Name)) 
                        {
                            query = this.activityScheduledSubscriptions[i]; 
                            break; 
                        }
                    } 
                }
            }

            if ((query != null) && (this.associatedProfile.ImplementationVisibility == ImplementationVisibility.RootScope)) 
            {
                if ((!ShouldTrackActivity(activityScheduledRecord.Activity, query.ActivityName)) || 
                        (!ShouldTrackActivity(activityScheduledRecord.Child, query.ChildActivityName))) 
                {
                    return null; 
                }
            }

            return query; 
        }
 
        FaultPropagationQuery Match(FaultPropagationRecord faultRecord) 
        {
            FaultPropagationQuery query = null; 
            if (this.faultPropagationSubscriptions != null)
            {
                for (int i = 0; i < this.faultPropagationSubscriptions.Count; i++)
                { 
                    //check specific and then generic
                    string faultHandlerName = faultRecord.FaultHandler == null ? null : faultRecord.FaultHandler.Name; 
                    if (string.CompareOrdinal(this.faultPropagationSubscriptions[i].FaultSourceActivityName, faultRecord.FaultSource.Name) == 0) 
                    {
                        if (CheckSubscription(this.faultPropagationSubscriptions[i].FaultHandlerActivityName, faultHandlerName)) 
                        {
                            query = this.faultPropagationSubscriptions[i];
                            break;
                        } 
                    }
                    else if (string.CompareOrdinal(this.faultPropagationSubscriptions[i].FaultSourceActivityName, "*") == 0) 
                    { 
                        if (CheckSubscription(this.faultPropagationSubscriptions[i].FaultHandlerActivityName, faultHandlerName))
                        { 
                            query = this.faultPropagationSubscriptions[i];
                            break;
                        }
                    } 
                }
            } 
 
            if ((query != null) && (this.associatedProfile.ImplementationVisibility == ImplementationVisibility.RootScope))
            { 
                if ((!ShouldTrackActivity(faultRecord.FaultHandler, query.FaultHandlerActivityName)) ||
                    (!ShouldTrackActivity(faultRecord.FaultSource, query.FaultSourceActivityName)))
                {
                    return null; 
                }
            } 
 
            return query;
        } 

        CancelRequestedQuery Match(CancelRequestedRecord cancelRecord)
        {
            CancelRequestedQuery query = null; 

            if (this.cancelRequestedSubscriptions != null) 
            { 
                for (int i = 0; i < this.cancelRequestedSubscriptions.Count; i++)
                { 
                    //check specific and then generic
                    string activityName = cancelRecord.Activity == null ? null : cancelRecord.Activity.Name;
                    if (string.CompareOrdinal(this.cancelRequestedSubscriptions[i].ActivityName, activityName) == 0)
                    { 
                        if (CheckSubscription(this.cancelRequestedSubscriptions[i].ChildActivityName, cancelRecord.Child.Name))
                        { 
                            query = this.cancelRequestedSubscriptions[i]; 
                            break;
                        } 
                    }
                    else if (string.CompareOrdinal(this.cancelRequestedSubscriptions[i].ActivityName, "*") == 0)
                    {
                        if (CheckSubscription(this.cancelRequestedSubscriptions[i].ChildActivityName, cancelRecord.Child.Name)) 
                        {
                            query = this.cancelRequestedSubscriptions[i]; 
                            break; 
                        }
                    } 
                }
            }

            if ((query != null) && (this.associatedProfile.ImplementationVisibility == ImplementationVisibility.RootScope)) 
            {
                if ((!ShouldTrackActivity(cancelRecord.Activity, query.ActivityName)) || 
                    (!ShouldTrackActivity(cancelRecord.Child, query.ChildActivityName))) 
                {
                    return null; 
                }
            }

            return query; 
        }
 
        CustomTrackingQuery Match(CustomTrackingRecord customRecord) 
        {
            CustomTrackingQuery query = null; 

            if (this.customTrackingQuerySubscriptions != null)
            {
                for (int i = 0; i < this.customTrackingQuerySubscriptions.Count; i++) 
                {
                    //check specific and then generic 
                    if (string.CompareOrdinal(this.customTrackingQuerySubscriptions[i].Name, customRecord.Name) == 0) 
                    {
                        if (CheckSubscription(this.customTrackingQuerySubscriptions[i].ActivityName, customRecord.Activity.Name)) 
                        {
                            query = this.customTrackingQuerySubscriptions[i];
                            break;
                        } 
                    }
                    else if (string.CompareOrdinal(this.customTrackingQuerySubscriptions[i].Name, "*") == 0) 
                    { 
                        if (CheckSubscription(this.customTrackingQuerySubscriptions[i].ActivityName, customRecord.Activity.Name))
                        { 
                            query = this.customTrackingQuerySubscriptions[i];
                            break;
                        }
                    } 
                }
            } 
            return query; 
        }
 
        static bool CheckSubscription(string name, string value)
        {
            //check specific and then generic
            return (string.CompareOrdinal(name, value) == 0 || 
                string.CompareOrdinal(name, "*") == 0);
        } 
 
        static void ExtractVariables(ActivityStateRecord activityStateRecord, ActivityStateQuery activityStateQuery)
        { 
            if (activityStateQuery.HasVariables)
            {
                activityStateRecord.Variables = activityStateRecord.GetVariables(activityStateQuery.Variables);
            } 
            else
            { 
                activityStateRecord.Variables = ActivityUtilities.EmptyParameters; 
            }
        } 

        static void ExtractArguments(ActivityStateRecord activityStateRecord, ActivityStateQuery activityStateQuery)
        {
            if (activityStateQuery.HasArguments) 
            {
                activityStateRecord.Arguments = activityStateRecord.GetArguments(activityStateQuery.Arguments); 
            } 
            else
            { 
                activityStateRecord.Arguments = ActivityUtilities.EmptyParameters;
            }
        }
 
        static TrackingRecord PrepareRecord(TrackingRecord record, TrackingQuery query, bool shouldClone)
        { 
            TrackingRecord preparedRecord = shouldClone ? record.Clone() : record; 

            if (query.HasAnnotations) 
            {
                preparedRecord.Annotations = new ReadOnlyDictionary(query.QueryAnnotations, false);
            }
 
            if (query is ActivityStateQuery)
            { 
                ExtractArguments((ActivityStateRecord)preparedRecord, (ActivityStateQuery)query); 
                ExtractVariables((ActivityStateRecord)preparedRecord, (ActivityStateQuery)query);
            } 
            return preparedRecord;
        }

 
        class RuntimeTrackingProfileCache
        { 
            [Fx.Tag.Cache(typeof(RuntimeTrackingProfile), Fx.Tag.CacheAttrition.PartialPurgeOnEachAccess)] 
            ConditionalWeakTable> cache;
 
            public RuntimeTrackingProfileCache()
            {
                this.cache = new ConditionalWeakTable>();
            } 

            public RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingProfile profile, Activity rootElement) 
            { 
                Fx.Assert(rootElement != null, "Root element must be valid");
 
                RuntimeTrackingProfile foundRuntimeProfile = null;
                HybridCollection runtimeProfileList = null;

                lock (this.cache) 
                {
                    if (!this.cache.TryGetValue(rootElement, out runtimeProfileList)) 
                    { 
                        foundRuntimeProfile = new RuntimeTrackingProfile(profile, rootElement);
                        runtimeProfileList = new HybridCollection(); 
                        runtimeProfileList.Add(foundRuntimeProfile);

                        this.cache.Add(rootElement, runtimeProfileList);
                    } 
                    else
                    { 
                        ReadOnlyCollection runtimeProfileCollection = runtimeProfileList.AsReadOnly(); 
                        foreach (RuntimeTrackingProfile runtimeProfile in runtimeProfileCollection)
                        { 
                            if (string.CompareOrdinal(profile.Name, runtimeProfile.associatedProfile.Name) == 0 &&
                                string.CompareOrdinal(profile.ActivityDefinitionId, runtimeProfile.associatedProfile.ActivityDefinitionId) == 0)
                            {
                                foundRuntimeProfile = runtimeProfile; 
                                break;
                            } 
                        } 

                        if (foundRuntimeProfile == null) 
                        {
                            foundRuntimeProfile = new RuntimeTrackingProfile(profile, rootElement);
                            runtimeProfileList.Add(foundRuntimeProfile);
                        } 
                    }
                } 
                return foundRuntimeProfile; 
            }
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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