Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / TrustUi / MS / Internal / documents / Application / DocumentManager.cs / 1 / DocumentManager.cs
//------------------------------------------------------------------------------ //// Copyright (C) Microsoft Corporation. All rights reserved. // ///// Exposes the basic operations that can be performed on documents. (Open, /// EnableEdit, Save) // // // History: // 08/28/2005: [....]: Initial implementation. //----------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.IO; using System.Security; using MS.Internal.PresentationUI; namespace MS.Internal.Documents.Application { ////// Exposes the basic operations that can be performed on documents. (Open, /// EnableEdit, Save) /// ////// Responsibility: /// The class is responsible for delegating the work to the appropriate /// controller(s) in the order needed based on document dependencies. /// /// Design Comments: /// Packages are dependent on EncryptedPackages who are dependent on FileStreams /// however all these classes are very different in function. /// /// By design once a controller has reported handling a document it will not be /// given to other controllers. A controller should not see documents they are /// not in the dependency chain for. /// /// Example: FileController should never see RightsDocument. /// [FriendAccessAllowed] internal sealed class DocumentManager : ChainOfResponsiblity{ #region Constructors //------------------------------------------------------------------------- // Constructors //------------------------------------------------------------------------- /// /// Will construct a DocumentManager using the provided controllers. /// /// Controllers in order of responsiblity from /// top to bottom. internal DocumentManager(params IDocumentController[] controllers) : base(controllers) { } #endregion Constructors #region Internal Methods //-------------------------------------------------------------------------- // Internal Methods //------------------------------------------------------------------------- ////// Creates the default chain of controllers. (PackageController, /// RightsController and FileController) /// ///A DocumentManager. ////// This exists because of a a design compromise; see SaveAs below. /// /// This compromise breaks encapsulation, because we have an understanding of /// begin used within a navigation application. /// internal static DocumentManager CreateDefault() { if (_singleton == null) { _controllers.Add(new HostedController()); _controllers.Add(new PackageController()); _controllers.Add(new RightsController()); _controllers.Add(new FileController()); _singleton = new DocumentManager( _controllers.ToArray()); Trace.SafeWrite(Trace.File, "DocumentManager singleton created."); } return _singleton; } ////// Creates the default chain of documents. (PackageDocument, /// RightsDocument and FileDocument) /// ///A Document. ////// Critical: /// - sets Document.Uri which is critical /// NotSafe: /// - only the caller can assert that this is the source of the request /// [SecurityCritical] internal static PackageDocument CreateDefaultDocument( Uri source, CriticalFileToken fileToken) { // because we have a fileToken we might be able to save _canSave = true; PackageDocument doc = new PackageDocument( new RightsDocument( new FileDocument(fileToken))); doc.Uri = source; return doc; } ////// Creates the default chain of documents. (PackageDocument, /// RightsDocument and FileDocument) /// ///A Document. ////// Critical: /// - call FileDocument ctor which uses stream as source /// - sets Document.Uri which is critical /// NotSafe: /// - origin of stream is known only to caller /// - only the caller can assert that this is the source of the request /// [SecurityCritical] internal static PackageDocument CreateDefaultDocument( Uri source, Stream stream) { PackageDocument doc = new PackageDocument( new RightsDocument( new FileDocument(stream))); doc.Uri = source; return doc; } ////// Allows IDocumentControllers to be properly cleaned up when created /// by the factory method of this class. /// internal static void CleanUp() { foreach (IDocumentController controller in _controllers) { IDisposable disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); } } } ////// Will enable editing for the document. /// /// A document. internal void EnableEdit(Document document) { if (document == null) { document = _current; } if (!_isEditEnabled) { _isEditEnabled = OrderByLeastDependent(DispatchEnableEdit, document); } } ////// Will open the specified document. /// /// A document. ///True if the operation succeeded internal bool Open(Document document) { ThrowIfNull(document); _current = document; // since we just loaded the document, it is now unmodified from the saved version _isModified = false; return OrderByLeastDependent(DispatchOpen, document); } ////// Will save the current document to a user-specified location. /// ///True if the operation succeeded internal bool SaveAs(Document document) { if (document == null) { document = _current; } bool result = OrderByLeastDependent(DispatchSaveAsPreperation, document); if (result) { result = OrderByMostDependent(DispatchSaveCommit, document); } if (result) { // since we just saved the document, it is now unmodified from the saved version _isModified = false; result = OrderByLeastDependent(DispatchRebind, document); } return result; } ////// Will save the specified document. /// /// A document. ///True if the operation succeeded internal bool Save(Document document) { if (document == null) { document = _current; } bool result = OrderByLeastDependent(DispatchSavePreperation, document); if (result) { result = OrderByMostDependent(DispatchSaveCommit, document); } // We always Rebind even if the Commit failed -- if we fail we still // need to Rebind the original document. OrderByLeastDependent(DispatchRebind, document); // since we just saved the document, it is now unmodified from the saved version _isModified = false; return result; } ////// This event handler is called to notify us that the document was modified. /// /// sender of the event (not used) /// arguments of the event (not used) internal static void OnModify(Object sender, EventArgs args) { _isModified = true; } ////// Forces the given document to reload. /// /// The document ///True if the operation succeeded internal bool Reload(Document document) { if (document == null) { document = _current; } // Set IsReloadNeeded to force reloading the document document.IsReloadNeeded = true; // Dispatch a rebind operation, which will cause a reload return OrderByLeastDependent(DispatchRebind, document); } #endregion Internal Methods #region Internal Properties //-------------------------------------------------------------------------- // Internal Properties //-------------------------------------------------------------------------- ////// Gets or sets whether saving to the source of the document may be possible. /// ////// Currently we only support saving when opened by a file Uri. /// internal bool CanSave { get { return _canSave; } set { _canSave = value; } } ////// This property returns true if the document has been modified from the /// version on disk (and therefore it makes sense for the user to save it). /// This property combines modification information from multiple sources. /// ////// Some changes are reflected in Package.IsDirty -- all other changes /// will notify us by writing to this property. The document is considered /// modified if it is modified either according to the PackageDocument or /// our internal flag. /// internal bool IsModified { get { PackageDocument doc = _current as PackageDocument; // If we don't have a PackageDocument (for example, if we are viewing // a read-only file), then only our internal flag is used. if (doc == null || doc.Package == null) { return _isModified; } else { return doc.Package.IsDirty || _isModified; } } } #endregion Internal Properties #region Private Methods //------------------------------------------------------------------------- // Private Methods //-------------------------------------------------------------------------- ////// Invokes EnableEdit on the controller provided using the document given. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private static bool DispatchEnableEdit (IDocumentController controller, Document document) { if ((document.Dependency != null) && (document.Dependency.Workspace == null)) { Trace.SafeWrite( Trace.File, "Skipping EnableEdit for {0} because dependent Stream is null.", controller); return true; } return controller.EnableEdit(document); } ////// Invokes Open on the controller provided using the document given. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private static bool DispatchOpen (IDocumentController controller, Document document) { if ((document.Dependency != null) && (document.Dependency.Source == null)) { Trace.SafeWrite( Trace.File, "Skipping Open for {0} because dependent Stream is null.", controller); return true; } return controller.Open(document); } ////// Invokes Rebind on the controller provided using the document given. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private static bool DispatchRebind (IDocumentController controller, Document document) { if ((document.Dependency != null) && (document.Dependency.Source == null)) { Trace.SafeWrite( Trace.File, "Skipping Rebind for {0} because dependent Stream is null.", controller); return true; } return controller.Rebind(document); } ////// Invokes SaveAsPreperation on the controller provided using the document /// given. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private static bool DispatchSaveAsPreperation (IDocumentController controller, Document document) { if ((document.Dependency != null) && (document.Dependency.Destination == null)) { Trace.SafeWrite( Trace.File, "Skipping SaveAsPreperation for {0} because dependent Stream is null.", controller); return true; } return controller.SaveAsPreperation(document); } ////// Invokes SaveCommit on the controller provided using the document given. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private static bool DispatchSaveCommit (IDocumentController controller, Document document) { if ((document.Dependency != null) && (document.Dependency.Destination == null)) { Trace.SafeWrite( Trace.File, "Skipping SaveCommit for {0} because dependent Stream is null.", controller); return true; } return controller.SaveCommit(document); } ////// Invokes SavePreperation on the controller provided using the document /// given. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private static bool DispatchSavePreperation (IDocumentController controller, Document document) { if ((document.Dependency != null) && (document.Dependency.Destination == null)) { Trace.SafeWrite( Trace.File, "Skipping SavePreperation for {0} because dependent Stream is null.", controller); return true; } return controller.SavePreperation(document); } ////// Invokes the action from the top of the document dependency chain to the /// bottom, for each provider under it in the chain. /// ////// OrderByMostDependent is implement in the ChainOfDependency /// (not a GoF pattern), it walks the tree of dependencies in this case the /// most dependent would be first. The Chain of Responsiblity pattern is /// invoke by the inherited member 'Dispatch' which is called for each /// dependency. /// /// The action to perform. /// The document to perform it on. private bool OrderByMostDependent(DispatchDelegate action, Document document) { return ChainOfDependencies.OrderByMostDependent( document, delegate(Document member) { return this.Dispatch(delegate( IDocumentController controller, Document subject) { return action(controller, subject); }, member); }); } /// /// Invokes the action from the bottom of the document dependency chain up /// to the top, for each provider under it in the chain. /// ////// OrderByLeastDependent is implement in the ChainOfDependency /// (not a GoF pattern), it walks the tree of dependencies in this case the /// least dependent would be first. The Chain of Responsiblity pattern is /// invoke by the inherited member 'Dispatch' which is called for each /// dependency. /// /// The action to perform. /// The document to perform it on. private bool OrderByLeastDependent(DispatchDelegate action, Document document) { return ChainOfDependencies.OrderByLeastDependent( document, delegate(Document member) { return this.Dispatch(delegate( IDocumentController controller, Document subject) { return action(controller, subject); }, member); }); } /// /// Will throw if the document is null. /// ////// The document to validate. private static void ThrowIfNull(Document document) { if (document == null) { throw new ArgumentNullException("document"); } } #endregion Private Methods #region Private Delegates //------------------------------------------------------------------------- // Private Delegates //------------------------------------------------------------------------- /// /// Defines the delegate for actions invoked by DocumentManager. /// /// The controller to perform the action. /// The document to perform it on. ///True if handled by controller. private delegate bool DispatchDelegate( IDocumentController controller, Document document); #endregion Private Delegates #region Private Fields //------------------------------------------------------------------------- // Private Fields //-------------------------------------------------------------------------- // Fields below simply prevents undesired user experience, they do not // impact security constraints nor are they used as protection private static Document _current; private static DocumentManager _singleton; private static bool _canSave; private static bool _isEditEnabled; private static bool _isModified; private static List_controllers = new List (); #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Cursors.cs
- DbDataSourceEnumerator.cs
- _LazyAsyncResult.cs
- MetadataCache.cs
- CollectionCodeDomSerializer.cs
- CacheOutputQuery.cs
- Roles.cs
- HeaderCollection.cs
- HttpRuntimeSection.cs
- EventTrigger.cs
- DetailsViewUpdatedEventArgs.cs
- MeasureData.cs
- SmiEventSink_Default.cs
- XmlUrlResolver.cs
- OdbcReferenceCollection.cs
- DictionaryEntry.cs
- BindingMAnagerBase.cs
- FormsAuthenticationModule.cs
- ValidatedControlConverter.cs
- OracleDataReader.cs
- HebrewNumber.cs
- OrderingInfo.cs
- CookieHandler.cs
- COSERVERINFO.cs
- ReceiveSecurityHeaderElementManager.cs
- ToolStripRendererSwitcher.cs
- DbDataReader.cs
- ExtensionDataReader.cs
- X509Utils.cs
- ClientProtocol.cs
- RuleSetCollection.cs
- WebConfigurationHostFileChange.cs
- SapiAttributeParser.cs
- OdbcCommandBuilder.cs
- AttributeSetAction.cs
- DataFormat.cs
- FontSource.cs
- TagMapCollection.cs
- Baml6Assembly.cs
- DecoderFallback.cs
- CatalogZone.cs
- SubtreeProcessor.cs
- EntityDataSourceQueryBuilder.cs
- BindingOperations.cs
- TagPrefixInfo.cs
- ADMembershipProvider.cs
- FieldNameLookup.cs
- XmlTextReader.cs
- TableCell.cs
- ContainerParagraph.cs
- ToolStripItemDesigner.cs
- OleDbCommandBuilder.cs
- BitmapDecoder.cs
- grammarelement.cs
- TimeSpanParse.cs
- Page.cs
- SettingsPropertyWrongTypeException.cs
- WebEventCodes.cs
- ClientTargetSection.cs
- LazyTextWriterCreator.cs
- Annotation.cs
- EntityDataSourceState.cs
- AnnotationResourceCollection.cs
- TypeForwardedToAttribute.cs
- Exceptions.cs
- EventBuilder.cs
- WSDualHttpSecurityMode.cs
- ProgressBar.cs
- DragCompletedEventArgs.cs
- SynchronizedDispatch.cs
- DataServiceHost.cs
- LogicalExpr.cs
- BigInt.cs
- XmlComment.cs
- ITextView.cs
- BamlStream.cs
- RayHitTestParameters.cs
- AdornedElementPlaceholder.cs
- CodeLinePragma.cs
- ChangeProcessor.cs
- TimeoutHelper.cs
- DesignerActionListCollection.cs
- Slider.cs
- Registry.cs
- ObjectContext.cs
- HeaderUtility.cs
- TdsRecordBufferSetter.cs
- SingleObjectCollection.cs
- Point4D.cs
- CustomAttribute.cs
- X509SecurityTokenProvider.cs
- SrgsOneOf.cs
- DynamicResourceExtension.cs
- TextDecorations.cs
- MDIControlStrip.cs
- NativeMethods.cs
- HttpHeaderCollection.cs
- DiagnosticsConfiguration.cs
- BinaryEditor.cs
- Double.cs