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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- StylusEventArgs.cs
- ChangePassword.cs
- MSG.cs
- FormView.cs
- SQLDecimal.cs
- XmlSchemaCompilationSettings.cs
- DefaultPropertyAttribute.cs
- IUnknownConstantAttribute.cs
- PowerStatus.cs
- MethodMessage.cs
- CompiledQuery.cs
- BitmapEffectDrawingContextState.cs
- BulletedListEventArgs.cs
- SqlUserDefinedAggregateAttribute.cs
- RSACryptoServiceProvider.cs
- UnSafeCharBuffer.cs
- ProcessModelSection.cs
- RequestCachingSection.cs
- SoapFault.cs
- documentation.cs
- XsdDuration.cs
- WebPartChrome.cs
- Positioning.cs
- SqlDelegatedTransaction.cs
- SqlInternalConnectionTds.cs
- OrderedDictionaryStateHelper.cs
- HtmlAnchor.cs
- FixedFlowMap.cs
- TypeDependencyAttribute.cs
- SecurityContextTokenCache.cs
- DocumentViewer.cs
- XmlObjectSerializerContext.cs
- DataMember.cs
- APCustomTypeDescriptor.cs
- OdbcEnvironment.cs
- ContractAdapter.cs
- GlobalProxySelection.cs
- FloaterParaClient.cs
- DefaultProxySection.cs
- XmlDictionary.cs
- GestureRecognizer.cs
- SqlDataSource.cs
- ZipIOLocalFileHeader.cs
- BuildResult.cs
- Environment.cs
- BuildProvider.cs
- ParseChildrenAsPropertiesAttribute.cs
- SelectionItemPattern.cs
- ArgIterator.cs
- ApplicationDirectoryMembershipCondition.cs
- _HelperAsyncResults.cs
- GreenMethods.cs
- AdditionalEntityFunctions.cs
- WrapPanel.cs
- StateManagedCollection.cs
- CallInfo.cs
- UrlPath.cs
- SoapFormatExtensions.cs
- LineGeometry.cs
- ping.cs
- SemanticAnalyzer.cs
- DataColumnCollection.cs
- ProgressBarAutomationPeer.cs
- ColorPalette.cs
- TextTreeExtractElementUndoUnit.cs
- LoginView.cs
- ISAPIWorkerRequest.cs
- PropertyEmitter.cs
- PauseStoryboard.cs
- ControlLocalizer.cs
- ZipIORawDataFileBlock.cs
- RenderingEventArgs.cs
- TraceContext.cs
- ButtonField.cs
- Root.cs
- SimpleHandlerBuildProvider.cs
- RenderCapability.cs
- SevenBitStream.cs
- DictionaryItemsCollection.cs
- MILUtilities.cs
- VirtualPath.cs
- ChameleonKey.cs
- DataSourceProvider.cs
- SrgsOneOf.cs
- XmlEntityReference.cs
- SqlLiftIndependentRowExpressions.cs
- CodeTypeDeclarationCollection.cs
- Single.cs
- TablePatternIdentifiers.cs
- HttpServerVarsCollection.cs
- StatusBar.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- PropertyDescriptor.cs
- Maps.cs
- StrongTypingException.cs
- QilXmlWriter.cs
- SubMenuStyleCollection.cs
- TraceUtils.cs
- SoapIncludeAttribute.cs
- HtmlElement.cs