BookmarkManager.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 / Runtime / BookmarkManager.cs / 1305376 / BookmarkManager.cs

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

namespace System.Activities.Runtime 
{
    using System; 
    using System.Activities.Hosting; 
    using System.Collections.Generic;
    using System.Runtime; 
    using System.Runtime.Serialization;

    [DataContract(Name = XD.Runtime.BookmarkManager, Namespace = XD.Runtime.Namespace)]
    class BookmarkManager 
    {
        [DataMember] 
        long nextId; 

        [DataMember(EmitDefaultValue = false)] 
        Dictionary bookmarks;

        [DataMember(EmitDefaultValue = false)]
        BookmarkScope scope; 

        [DataMember(EmitDefaultValue = false)] 
        BookmarkScopeHandle scopeHandle; 

        public BookmarkManager() 
        {
            this.nextId = 1;
        }
 
        internal BookmarkManager(BookmarkScope scope, BookmarkScopeHandle scopeHandle)
            : this() 
        { 
            this.scope = scope;
            this.scopeHandle = scopeHandle; 
        }


        public bool HasBookmarks 
        {
            get 
            { 
                return this.bookmarks != null && this.bookmarks.Count > 0;
            } 
        }

        public Bookmark CreateBookmark(string name, BookmarkCallback callback, ActivityInstance owningInstance, BookmarkOptions options)
        { 
            Bookmark toAdd = new Bookmark(name);
 
            if (this.bookmarks != null && this.bookmarks.ContainsKey(toAdd)) 
            {
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkAlreadyExists(name))); 
            }

            AddBookmark(toAdd, callback, owningInstance, options);
            //Regular bookmarks are never important 
            UpdateAllExclusiveHandles(toAdd, owningInstance);
 
            return toAdd; 
        }
 
        public Bookmark CreateBookmark(BookmarkCallback callback, ActivityInstance owningInstance, BookmarkOptions options)
        {
            Fx.Assert(this.scope == null, "We only support named bookmarks within bookmark scopes right now.");
 
            Bookmark bookmark = Bookmark.Create(GetNextBookmarkId());
            AddBookmark(bookmark, callback, owningInstance, options); 
            //Regular bookmarks are never important 
            UpdateAllExclusiveHandles(bookmark, owningInstance);
 
            return bookmark;
        }

        void UpdateAllExclusiveHandles(Bookmark bookmark, ActivityInstance owningInstance) 
        {
            Fx.Assert(bookmark != null, "Invalid call to UpdateAllExclusiveHandles. Bookmark was null"); 
            Fx.Assert(owningInstance != null, "Invalid call to UpdateAllExclusiveHandles. ActivityInstance was null"); 

            if (owningInstance.PropertyManager == null) 
            {
                return;
            }
 
            if (!owningInstance.PropertyManager.HasExclusiveHandlesInScope)
            { 
                return; 
            }
 
            List handles = owningInstance.PropertyManager.FindAll();

            if (handles == null)
            { 
                return;
            } 
 
            for(int i =0; i(Bookmark.Comparer);
            }
 
            bookmark.Scope = this.scope;
 
            BookmarkCallbackWrapper bookmarkCallbackWrapper = new BookmarkCallbackWrapper(callback, owningInstance, options) 
            {
                 Bookmark = bookmark 
            };
            this.bookmarks.Add(bookmark, bookmarkCallbackWrapper);

            owningInstance.AddBookmark(bookmark, options); 

            if (TD.CreateBookmarkIsEnabled()) 
            { 
                TD.CreateBookmark(owningInstance.Activity.GetType().ToString(), owningInstance.Activity.DisplayName, owningInstance.Id, ActivityUtilities.GetTraceString(bookmark), ActivityUtilities.GetTraceString((BookmarkScope)bookmark.Scope));
            } 
        }

        long GetNextBookmarkId()
        { 
            if (this.nextId == long.MaxValue)
            { 
                throw FxTrace.Exception.AsError(new NotSupportedException(SR.OutOfInternalBookmarks)); 
            }
 
            long result = this.nextId;
            this.nextId++;
            return result;
        } 

        // This method translates from a bookmark that we may have received from the outside world (IE - new Bookmark(someName)) 
        // to our internal Bookmark object.  This is necessary because we use bookmark objects as the key to our dictionary 
        // (hence our ability to resolve an externally created one), but we keep a lot of important information on our internal
        // instance of that bookmark.  We must always perform this translation when doing exclusive handle housekeeping. 
        public bool TryGetBookmarkFromInternalList(Bookmark bookmark, out Bookmark internalBookmark, out BookmarkCallbackWrapper callbackWrapper)
        {
            internalBookmark = null;
            callbackWrapper = null; 
            if (this.bookmarks == null)
            { 
                return false; 
            }
 
            BookmarkCallbackWrapper wrapper;
            if (this.bookmarks.TryGetValue(bookmark,out wrapper))
            {
                internalBookmark = wrapper.Bookmark; 
                callbackWrapper = wrapper;
                return true; 
            } 

            return false; 
        }

        public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, bool isExternal, ref Bookmark bookmark, object value, ActivityInstance isolationInstance, out ActivityExecutionWorkItem workItem)
        { 
            Bookmark internalBookmark = null;
            BookmarkCallbackWrapper callbackWrapper = null; 
            if (!this.TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper)) 
            {
                workItem = null; 
                return BookmarkResumptionResult.NotFound;
            }

            bookmark = internalBookmark; 
            if (!ActivityUtilities.IsInScope(callbackWrapper.ActivityInstance, isolationInstance))
            { 
                workItem = null; 

                // We know about the bookmark, but we can't resume it yet 
                return BookmarkResumptionResult.NotReady;
            }

            workItem = callbackWrapper.CreateWorkItem(executor, isExternal, bookmark, value); 

            if (!BookmarkOptionsHelper.SupportsMultipleResumes(callbackWrapper.Options)) 
            { 
                // cleanup bookmark on resumption unless the user opts into multi-resume
                Remove(bookmark, callbackWrapper); 
            }

            return BookmarkResumptionResult.Success;
        } 

        public void PopulateBookmarkInfo(List bookmarks) 
        { 
            Fx.Assert(this.HasBookmarks, "Should only be called if this actually has bookmarks.");
 
            foreach (KeyValuePair bookmarkEntry in this.bookmarks)
            {
                if (bookmarkEntry.Key.IsNamed)
                { 
                    bookmarks.Add(bookmarkEntry.Key.GenerateBookmarkInfo(bookmarkEntry.Value));
                } 
            } 
        }
 
        // No need to translate using TryGetBookmarkFromInternalList because we already have
        // internal instances since this call comes from bookmarks hanging off of the
        // ActivityInstance and not from an external source
        public void PurgeBookmarks(Bookmark singleBookmark, IList multipleBookmarks) 
        {
            if (singleBookmark != null) 
            { 
                PurgeSingleBookmark(singleBookmark);
            } 
            else
            {
                Fx.Assert(multipleBookmarks != null, "caller should never pass null");
                for (int i = 0; i < multipleBookmarks.Count; i++) 
                {
                    Bookmark bookmark = multipleBookmarks[i]; 
                    PurgeSingleBookmark(bookmark); 
                }
            } 
        }

        internal void PurgeSingleBookmark(Bookmark bookmark)
        { 
            Fx.Assert(this.bookmarks.ContainsKey(bookmark) && object.ReferenceEquals(bookmark, this.bookmarks[bookmark].Bookmark), "Something went wrong with our housekeeping - it must exist and must be our intenral reference");
            UpdateExclusiveHandleList(bookmark); 
            this.bookmarks.Remove(bookmark); 
        }
 
        public bool Remove(Bookmark bookmark, ActivityInstance instanceAttemptingRemove)
        {
            // We need to translate to our internal instance of the bookmark.  See TryGetBookmarkFromInternalList
            // for more details. 
            BookmarkCallbackWrapper callbackWrapper;
            Bookmark internalBookmark; 
            if (TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper)) 
            {
                if (callbackWrapper.ActivityInstance != instanceAttemptingRemove) 
                {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(SR.OnlyBookmarkOwnerCanRemove));
                }
 
                Remove(internalBookmark, callbackWrapper);
                return true; 
            } 
            else
            { 
                return false;
            }
        }
 
        void Remove(Bookmark bookmark, BookmarkCallbackWrapper callbackWrapper)
        { 
            callbackWrapper.ActivityInstance.RemoveBookmark(bookmark, callbackWrapper.Options); 
            UpdateExclusiveHandleList(bookmark);
            this.bookmarks.Remove(bookmark); 
        }

        void UpdateExclusiveHandleList(Bookmark bookmark)
        { 
            if (bookmark.ExclusiveHandles != null)
            { 
                for (int i = 0; i < bookmark.ExclusiveHandles.Count; i++) 
                {
                    ExclusiveHandle handle = bookmark.ExclusiveHandles[i]; 
                    Fx.Assert(handle != null, "Internal error.. ExclusiveHandle was null");
                    handle.RemoveBookmark(bookmark);
                }
            } 
        }
    } 
} 

// 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