XpsFixedDocumentReaderWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Print / Reach / Packaging / XpsFixedDocumentReaderWriter.cs / 1 / XpsFixedDocumentReaderWriter.cs

                            /*++ 

    Copyright (C) 2004 - 2005 Microsoft Corporation
    All rights reserved.
 
    Module Name:
        XpsFixedDocumentReaderWriter.cs 
 
    Abstract:
        This file contains the definition for IXpsFixedDocumentReader 
        and IXpsFixedDocumentWriter interfaces as well as definition
        and implementation of XpsFixedDocumentReaderWriter.  These
        interfaces and class are used for writing fixed document
        parts to a Xps package. 

    Author: 
        [....] ([....]) 1-November-2004 

    Revision History: 
    05/5/2005:  [....]: Addition of Digital Signing support
    07/12/2005: [....]: Reach -> Xps
--*/
 
using System;
using System.Collections; 
using System.Collections.ObjectModel; 
using System.Collections.Generic;
using System.IO; 
using System.IO.Packaging;
using System.Xml;
using System.Security.Cryptography.X509Certificates;
using System.Printing; 

namespace System.Windows.Xps.Packaging 
{ 
    #region IXpsFixedDocumentReader interface definition
 
    /// 
    /// Interface for reading fixed document parts from the Xps package.
    /// 
    /// Interface will be internal until reading/de-serialization is implemented. 
    public  interface IXpsFixedDocumentReader:
                      IDocumentStructureProvider 
    { 
        #region Public methods
 
        /// 
        /// This method retrieves a fixed page part from a Xps
        /// package using the given URI.
        ///  
        /// 
        /// The URI of the fixed page to retrieve. 
        ///  
        /// 
        /// Returns an interface to an IXpsFixedPageReader to read 
        /// the requested fixed page.
        /// 
        IXpsFixedPageReader
        GetFixedPage( 
            Uri         pageSource
            ); 
 
        #endregion Public methods
 
        #region Public properties

        /// 
        /// Gets the PrintTicket associated with this fixed document. 
        /// 
        /// Value can be a PrintTicket or null. 
        /// PrintTicket has already been committed. 
        /// Property is not a valid PrintTicket instance.
        PrintTicket PrintTicket { get; } 

        /// 
        /// Gets the URI assigned to this fixed document part.
        ///  
        /// Value is a URI for the Metro part.
        Uri Uri { get; } 
 
        /// 
        /// Gets a collection of all fixed pages that are contained within 
        /// this fixed document.
        /// 
        /// 
        /// Value is a Collection containing IXpsFixedPageReader interfaces. 
        /// 
        ReadOnlyCollection FixedPages { get; } 
 
        /// 
        /// 0 based document number in the document sequence 
        /// 
        int DocumentNumber{ get; }

        ///  
        /// A list of signature definitions associated with the document
        ///  
        ICollection 
        SignatureDefinitions{ get; }
 
        /// 
        /// thumbnail image associated with this doucment
        /// 
        XpsThumbnail 
        Thumbnail{ get; }
 
        ///  
        /// Document Structure associated with this doucment
        ///  
        XpsStructure
        DocumentStructure{ get; }

 
        #endregion Public properties
 
        ///  
        /// Adds the passed Signature Definiton to the cached
        /// Signature Definition list 
        /// Will not be written until FlushSignatureDefinition
        /// is called
        /// 
        ///  
        /// the Signature Definition to be added
        ///  
        void 
        AddSignatureDefinition(
            XpsSignatureDefinition signatureDefinition 
            );

        /// 
        /// This method removes a signature definitions associated with 
        /// the FixedDocument
        ///  
        ///  
        /// Signature Definition to remove
        ///  
        void
        RemoveSignatureDefinition(XpsSignatureDefinition signatureDefinition);

        ///  
        /// Writes out all modifications to Signature
        /// Definitions as well as new Signature Definitions 
        ///  
        void
        CommitSignatureDefinition(); 
    }

    #endregion IXpsFixedDocumentReader interface definition
 
    #region IXpsFixedDocumentWriter interface definition
 
    ///  
    /// Interface for writing fixed document parts to the xps package.
    ///  
    public interface IXpsFixedDocumentWriter:
                     IDocumentStructureProvider
    {
        #region Public methods 

        ///  
        /// This method adds a fixed page part to the Xps package 
        /// and associates it with the current fixed document.
        ///  
        /// 
        /// Returns an interface to the newly created fixed page.
        /// 
        /// The FixedDocument has already been disposed 
        /// FixedPage is not completed.
        IXpsFixedPageWriter 
        AddFixedPage( 
            );
 
        /// 
        /// This method adds a thumbnail to the current DocumentSequence.
        ///
        /// There can only be one thumbnail attached to the DocumentSequence. 
        ///  Calling this method when there
        /// is already a starting part causes InvalidOperationException to be 
        /// thrown. 
        /// 
        /// Returns a XpsThumbnail instance. 
        XpsThumbnail
        AddThumbnail(
            XpsImageType imageType
            ); 

        ///  
        /// This method commits any changes not already committed for this 
        /// fixed document.
        /// 
        /// 
        void
        Commit(
            ); 

        #endregion Public methods 
 
        #region Public properties
 
        /// 
        /// Sets the PrintTicket associated with this fixed document.
        /// 
        ///  
        /// The value must be a valid PrintTicket instance.
        /// 
        /// Note:  The PrintTicket can only be assigned to prior to if being 
        /// committed to the package.  The commit happens when a valid PrintTicket
        /// is set and a subsequent flush on the document occurs. 
        /// 
        /// PrintTicket has already been committed.
        /// Property is not a valid PrintTicket instance.
        PrintTicket PrintTicket { set; } 

        ///  
        /// Gets the URI assigned to this fixed document part. 
        /// 
        /// Value is a URI for the Metro part. 
        Uri Uri { get; }

        /// 
        /// 0 based document number in the document sequence 
        /// 
        int DocumentNumber{ get; } 
 
        #endregion Public properties
    } 

    #endregion IXpsFixedDocumentWriter interface definition

    ///  
    /// This class implements the reading and writing functionality for
    /// a fixed document within a Xps package. 
    ///  
    internal sealed class XpsFixedDocumentReaderWriter : XpsPartBase,
                          IXpsFixedDocumentReader, 
                          IXpsFixedDocumentWriter,
                          INode,
                          IDisposable
    { 
        #region Constructors
 
        ///  
        /// Internal constructor for the XpsFixedDocumentReaderWriter class.
        /// This class is created internally so we can keep the Xps hierarchy 
        /// completely under control when using these APIs.
        /// 
        /// 
        /// The XpsManager for the current Xps package. 
        /// 
        ///  
        /// The parent node of this fixed document. 
        /// 
        ///  
        /// The internal Metro part that represents this fixed document.
        /// 
        /// 
        ///  The 0 base document number in the document sequence 
        /// 
        /// part is null. 
        internal 
        XpsFixedDocumentReaderWriter(
            XpsManager    xpsManager, 
            INode           parent,
            PackagePart     part,
            int             documentNumber
            ) 
            : base(xpsManager)
        { 
            if (null == part) 
            {
                throw new ArgumentNullException("part"); 
            }

            this.Uri = part.Uri;
 
            _metroPart = part;
 
            _partEditor = new XmlPartEditor(_metroPart); 

            _pageCache = new List(); 

            _parentNode = parent;

            _hasParsedPages = false; 

            _documentNumber = documentNumber; 
       } 

        #endregion Constructors 

        #region Public properties

        ///  
        /// Gets or sets the PrintTicket to be stored with this fixed document.
        /// 
        /// NOTE:  The PrintTicket can only be assigned to prior to if being 
        /// committed to the package.  The commit happens when a valid PrintTicket
        /// is set and a subsequent flush on the document occurs. 
        /// 
        /// Value can be a PrintTicket or null.
        /// PrintTicket has already been committed.
        /// Property is not a valid PrintTicket instance. 
        public PrintTicket PrintTicket
        { 
            get 
            {
                if( _printTicket == null ) 
                {
                    _printTicket = CurrentXpsManager.EnsurePrintTicket( Uri );
                }
                return _printTicket; 
            }
            set 
            { 
                if(value != null)
                { 
                    if (_isPrintTicketCommitted)
                    {
                        throw new XpsPackagingException(ReachSR.Get(ReachSRID.ReachPackaging_PrintTicketAlreadyCommitted));
                    } 
                    if (!value.GetType().Equals(typeof(PrintTicket)))
                    { 
                        throw new XpsPackagingException(ReachSR.Get(ReachSRID.ReachPackaging_NotAPrintTicket)); 
                    }
 
                    _printTicket = value.Clone();
                }
                else
                { 
                    _printTicket = null;
                } 
            } 
        }
 
        /// 
        /// Gets a collection of all fixed pages that are contained within
        /// this fixed document.
        ///  
        /// 
        /// Value is a Collection containing IXpsFixedPageReader interfaces. 
        ///  
        /// 
        /// This is only internal until it is implemented. 
        /// 
        public ReadOnlyCollection FixedPages
        {
            get 
            {
                UpdatePageCache(); 
                return new ReadOnlyCollection(_pageCache ); 
            }
        } 

        /// 
        /// A list of signature definitions associated with the document
        ///  
        public
        ICollection 
        SignatureDefinitions 
        {
            get 
            {
                EnsureSignatureDefinitions();
                return _signatureDefinitions;
            } 
        }
 
        ///  
        /// 0 based document number in the document sequence
        ///  
         public int DocumentNumber
         {
            get
            { 
                return _documentNumber;
            } 
         } 

        public 
        XpsThumbnail
        Thumbnail
        {
            get 
            {
                EnsureThumbnail(); 
                return _thumbnail; 
            }
        } 

        public
        XpsStructure
        DocumentStructure 
        {
            get 
            { 
                EnsureDoucmentStructure();
                return _documentStructure; 
            }
        }

        #endregion Public properties 

        #region Public methods 
        ///  
        /// This method adds a fixed page part to the Xps package
        /// and associates it with the current fixed document. 
        /// 
        /// 
        /// Returns an interface to the newly created fixed page.
        ///  
        /// The FixedDocument has already been disposed
        /// FixedPage is not completed. 
        public 
        IXpsFixedPageWriter
        AddFixedPage( 
            )
        {

            if (null == _metroPart || null == CurrentXpsManager.MetroPackage) 
            {
                throw new ObjectDisposedException("XpsFixedDocumentReaderWriter"); 
            } 

            // 
            // Only one page can be created/written at a time.
            //
            if (null != _currentPage)
            { 
                throw new XpsPackagingException(ReachSR.Get(ReachSRID.ReachPackaging_PanelOrSequenceAlreadyOpen));
            } 
 

            _linkTargetStream = new List(); 

            //
            // Create the part and writer
            // 
            PackagePart metroPart = this.CurrentXpsManager.GenerateUniquePart(XpsS0Markup.FixedPageContentType);
            XpsFixedPageReaderWriter fixedPage = new XpsFixedPageReaderWriter(CurrentXpsManager, this, metroPart, _linkTargetStream, _pageCache.Count+1); 
 
            //
            // Make the new page the current page 
            //
            _currentPage = fixedPage;

            // 
            // Make sure the new fixed page makes it into the cached collection
            // 
            _pageCache.Add(fixedPage); 

 


            return fixedPage;
        } 

        ///  
        /// This method adds a thumbnail to the current DocumentSequence. 
        ///
        /// There can only be one thumbnail attached to the DocumentSequence. 
        ///  Calling this method when there
        /// is already a starting part causes InvalidOperationException to be
        /// thrown.
        ///  
        /// Returns a XpsThumbnail instance.
        public 
        XpsThumbnail 
        AddThumbnail(
            XpsImageType imageType 
            )
        {
            _thumbnail = CurrentXpsManager.AddThumbnail( imageType, this, Thumbnail );
            _metroPart.CreateRelationship( _thumbnail.Uri, 
                                           TargetMode.Internal,
                                           XpsS0Markup.ThumbnailRelationshipName 
                                          ); 
           return _thumbnail;
        } 

        /// 
        /// 
        public 
        XpsStructure
        AddDocumentStructure( 
            ) 
        {
            Uri pageUri = this.CurrentXpsManager.CreateStructureUri(); 
            //
            // Create the part and writer
            //
            PackagePart metroPart = this.CurrentXpsManager.GeneratePart( 
                        XpsS0Markup.DocumentStructureContentType,
                        pageUri); 
 
            _xpsStructure = new XpsStructure(CurrentXpsManager, this, metroPart);
 
            //
            // Create the relationship between the document and the document-structure
            // Not in INode.Flush because IXpsFixedDocumentReader has no commit.
            // 

            string structurePath = XpsManager.MakeRelativePath(this.Uri, _xpsStructure.Uri); 
 
            _metroPart.CreateRelationship(new Uri(structurePath, UriKind.Relative),
                                             TargetMode.Internal, 
                                             XpsS0Markup.StructureRelationshipName
                                           );

            return _xpsStructure; 
        }
 
        ///  
        /// This method adds a relationship for this part that
        /// targets the specified Uri and is based on the specified 
        /// content type.
        /// 
        /// 
        /// Uri target for relationship. 
        /// 
        ///  
        /// Relationship type to add. 
        /// 
        public 
        void
        AddRelationship(
            Uri         targetUri,
            string      relationshipName 
            )
        { 
            // 
            // We can not read from the file to do validation
            // when streaming 
            //
            if( !CurrentXpsManager.Streaming )
            {
                foreach (PackageRelationship rel in _metroPart.GetRelationships()) 
                {
                    if (rel.TargetUri.Equals(targetUri)) 
                    { 
                        //
                        // Relationship already exists 
                        //
                        return;
                    }
                } 
            }
 
            // 
            // Add the relationship using a relative path to this page.
            // 
            string relativePath = XpsManager.MakeRelativePath(this.Uri, targetUri);
            _metroPart.CreateRelationship(new Uri(relativePath, UriKind.Relative),
                                               TargetMode.Internal,
                                               relationshipName); 
        }
 
        ///  
        /// This method retrieves a fixed page part from a Xps
        /// package using the given URI. 
        /// 
        /// 
        /// The URI of the fixed page to retrieve.
        ///  
        /// 
        /// Returns an interface to an IXpsFixedPageReader to read 
        /// the requested fixed page. 
        /// 
        public 
        IXpsFixedPageReader
        GetFixedPage(
            Uri         pageUri
            ) 
        {
            UpdatePageCache(); 
            IXpsFixedPageReader pageReader = null; 

            foreach (IXpsFixedPageReader reader in _pageCache ) 
            {
                if( reader.Uri == pageUri )
                {
                    pageReader =  reader; 
                }
            } 
 
            return pageReader;
        } 

        public
        void
        AddSignatureDefinition( 
            XpsSignatureDefinition signatureDefinition
            ) 
        { 
            EnsureSignatureDefinitions();
            _signatureDefinitions.Add( signatureDefinition ); 
            _sigCollectionDirty = true;

        }
 
        public
        void 
        CommitSignatureDefinition() 
        {
            bool isDirty = false; 

            //
            // if the collection is dirty not point in testing
            // each signature. 
            //
            if( !_sigCollectionDirty ) 
            { 
                foreach( XpsSignatureDefinition sigDef in _signatureDefinitions )
                { 
                    if( sigDef.HasBeenModified )
                    {
                        isDirty = true;
                        break; 
                    }
                } 
            } 
            if( isDirty || _sigCollectionDirty )
            { 
                WriteSignatureDefinitions();
            }
        }
 
        /// 
        /// This method removes a signature definitions associated with 
        /// the FixedDocument 
        /// 
        ///  
        /// Signature Definition to remove
        /// 
        public
        void 
        RemoveSignatureDefinition(XpsSignatureDefinition signatureDefinition)
        { 
           EnsureSignatureDefinitions(); 
           _signatureDefinitions.Remove( signatureDefinition );
           _sigCollectionDirty = true; 

        }

        ///  
        /// This method commits any changes not already committed for this
        /// fixed document. 
        /// 
        /// NOTE:  This commits changes to all child object under this
        /// branch of the tree.  No further changes will be allowed. 
        /// 
        public
        void
        Commit( 
            )
        { 
            CommitInternal(); 
        }
 
        /// 
        /// This method closes streams and frees memory for this
        /// fixed document.
        ///  
        internal
        override 
        void 
        CommitInternal(
            ) 
        {
            CommitPrintTicket();
            if (null != _partEditor)
            { 
                if (null != _partEditor.XmlWriter)
                { 
                    if(_partEditor.DoesWriteStartEndTags) 
                    {
                        if(_partEditor.IsStartElementWritten) 
                        {
                            _partEditor.XmlWriter.WriteEndElement();
                            _partEditor.XmlWriter.WriteEndDocument();
                        } 
                    }
                } 
 
                ((INode)this).Flush();
                _partEditor.Close(); 


                _partEditor     = null;
                _metroPart      = null; 

                _parentNode     = null; 
 
                _thumbnail      = null;
 
                _pageCache      = null;

                _hasParsedPages = false;
           } 

            base.CommitInternal(); 
        } 

 

        /// 
        /// Adds itself and and its reationship if it exists
        /// Adds dependent part Uris to the passed list following the passed restrictions 
        /// dependents include pages, annotaions, properties, and signatures
        ///  
        internal 
        void
        CollectSelfAndDependents( 
            Dictionary                 dependentList,
            List   selectorList,
            XpsDigSigPartAlteringRestrictions   restrictions
            ) 
        {
 
            // 
            // Add this document
            // 
            dependentList[Uri] = Uri;

            //
            // Add Signature Definition if it exists 
            //
            PackagePart signatureDefinitionPart = 
                CurrentXpsManager.GetSignatureDefinitionPart(Uri); 

            // 
            // Add Signature Definitions
            //
            selectorList.Add( new PackageRelationshipSelector(
                                    Uri, 
                                    PackageRelationshipSelectorType.Type,
                                    XpsS0Markup.SignatureDefinitionRelationshipName 
                                    ) 
                                 );
 

            if( signatureDefinitionPart != null )
            {
                dependentList[signatureDefinitionPart.Uri] = signatureDefinitionPart.Uri; 
            }
            // 
            // Add Restricted Font relationship 
            //
            selectorList.Add( new PackageRelationshipSelector( 
                                    Uri,
                                    PackageRelationshipSelectorType.Type,
                                    XpsS0Markup.RestrictedFontRelationshipType
                                    ) 
                                 );
            // 
            // Add Document Structure relationship 
            //
            selectorList.Add( new PackageRelationshipSelector( 
                                    Uri,
                                    PackageRelationshipSelectorType.Type,
                                    XpsS0Markup.StructureRelationshipName
                                    ) 
                                 );
            // 
            // Add thumnail relationship 
            //
            selectorList.Add(new PackageRelationshipSelector( 
                                    Uri,
                                    PackageRelationshipSelectorType.Type,
                                    XpsS0Markup.ThumbnailRelationshipName
                                    ) 
                                 );
            // 
            // Add this documents dependants 
            //
            CollectDependents( dependentList, selectorList, restrictions); 


        }
 
        internal
        void 
        CollectXmlPartsAndDepenedents( 
            List xmlPartList
            ) 
        {
            //
            // Add my self to be tested for V&E Markup
            // 
            xmlPartList.Add(_metroPart);
            UpdatePageCache(); 
            // 
            // Add all pages
            // 
            foreach (IXpsFixedPageReader reader in _pageCache)
            {
                (reader as XpsFixedPageReaderWriter).CollectXmlPartsAndDepenedents(xmlPartList);
            } 
            //
            // Add DocumentStructure 
            // 
            EnsureDoucmentStructure();
            if (_documentStructure != null) 
            {
                //
                // Add my DocumentStructure to be tested for V&E Markup
                // 
                xmlPartList.Add((_documentStructure as INode).GetPart());
            } 
            // 
            // Add Signature Definition if it exists
            // 
            PackagePart signatureDefinitionPart =
                CurrentXpsManager.GetSignatureDefinitionPart(Uri);
            if (signatureDefinitionPart != null)
            { 
                //
                // Add my signatureDefinitionPart to be tested for V&E Markup 
                // 
                xmlPartList.Add(signatureDefinitionPart);
            } 
        }

        /// 
        /// Adds dependent part Uris to the passed list 
        /// 
        internal 
        void 
        CollectDependents(
            Dictionary                 dependents, 
            List   selectorList,
            XpsDigSigPartAlteringRestrictions   restrictions
            )
        { 
            UpdatePageCache();
            // 
            // Add all pages 
            //
            foreach( IXpsFixedPageReader reader in _pageCache) 
            {
                (reader as XpsFixedPageReaderWriter).
                    CollectSelfAndDependents(
                    dependents, 
                    selectorList,
                    restrictions 
                    ); 
            }
 
            //
            // Add thumbnail
            //
            EnsureThumbnail(); 
            if( _thumbnail != null )
            { 
                dependents[_thumbnail.Uri] = _thumbnail.Uri; 
            }
 
            //
            // Add DocumentStructure
            //
            EnsureDoucmentStructure(); 
            if( _documentStructure != null )
            { 
                dependents[_documentStructure.Uri] = _documentStructure.Uri; 
            }
       } 

        #endregion Public methods

        #region Private methods 

        private 
        void 
        AddPageToDocument(
            Uri                 partUri, 
            IList       linkTargetStream
            )
        {
            _partEditor.PrepareXmlWriter(XpsS0Markup.FixedDocument, XpsS0Markup.FixedDocumentNamespace); 
            XmlTextWriter xmlWriter = _partEditor.XmlWriter;
            // 
            // Write  
            //
            String relativePath = XpsManager.MakeRelativePath(Uri, partUri); 

            xmlWriter.WriteStartElement(XpsS0Markup.PageContent);
            xmlWriter.WriteAttributeString(XmlTags.Source, relativePath);
 
            //
            // Write out link targets if necessary 
            // 
            if (linkTargetStream.Count != 0)
            { 
                xmlWriter.WriteRaw ("");
                foreach (String nameElement in linkTargetStream)
                {
                     xmlWriter.WriteRaw (String.Format( 
                        System.Globalization.CultureInfo.InvariantCulture,
                        "", 
                        nameElement) 
                        );
                } 
                xmlWriter.WriteRaw ("");
            }

            xmlWriter.WriteEndElement(); 
        }
        ///  
        /// This method writes the PrintTicket associated with 
        /// this fixed document to the Metro package.
        ///  
        private
        void
        CommitPrintTicket(
            ) 
        {
            // 
            // Flush the PrintTicket if needed 
            //
            if (!_isPrintTicketCommitted ) 
            {
                if(null != _printTicket)
                {
                    CurrentXpsManager.WritePrintTicket(this,_metroPart, _printTicket); 
                }
                else 
                { 
                    CurrentXpsManager.WriteEmptyPrintTicket(this, _metroPart);
                } 
                _isPrintTicketCommitted = true;
            }
        }
 
        /// 
        /// CurrentPageCommitted signals that our current page 
        /// is complete and we can write out any associated link 
        /// targets and end the PageContent element.
        ///  
        internal
        void
        CurrentPageCommitted()
        { 
            if( _currentPage != null )
            { 
                //Write out the fixed page tag 
                AddPageToDocument(_currentPage.Uri, _linkTargetStream);
                _currentPage = null; 
            }
        }

        ///  
        /// Test if the page cache has been initialized  and
        /// updates it if necessary 
        ///  
        private
        void 
        UpdatePageCache()
        {
            if( !_hasParsedPages )
            { 
                ParsePages();
                _hasParsedPages = true; 
            } 
        }
        ///  
        /// This method parses the part pulling out the Page Referneces
        /// and populates the _pageCache
        /// 
        private 
        void
        ParsePages() 
        { 
            Stream stream = _metroPart.GetStream(FileMode.Open);
            // 
            // If the stream is empty there are no pages to parse
            //
            if( stream.Length > 0 )
            { 
                XmlTextReader reader = new XmlTextReader(stream);
 
                while( reader.Read() ) 
                {
                    if( reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.PageContent) 
                    {
                        string attribute = reader.GetAttribute(XmlTags.Source);
                        if( attribute != null )
                        { 
                            Uri relativeUri =  new Uri(attribute, UriKind.Relative);
                            AddPageToCache(PackUriHelper.ResolvePartUri( Uri, relativeUri)); 
                        } 
                    }
                } 
            }
        }

        private 
        IXpsFixedPageReader
        AddPageToCache( Uri pageUri ) 
        { 
            PackagePart pagePart = CurrentXpsManager.GetPart(pageUri);
 
            if (pagePart == null)
            {
                 throw new XpsPackagingException(ReachSR.Get(ReachSRID.ReachPackaging_PartNotFound));
            } 

            if (!pagePart.ValidatedContentType.AreTypeAndSubTypeEqual(XpsS0Markup.FixedPageContentType)) 
            { 
                throw new XpsPackagingException(ReachSR.Get(ReachSRID.ReachPackaging_NotAFixedPage));
            } 

            //
            // Create the reader/writer for the part
            // 
            IXpsFixedPageReader pageReader = new XpsFixedPageReaderWriter(CurrentXpsManager, this, pagePart, null, _pageCache.Count+1);
 
            // 
            // Cache the new reader/writer for later
            // 
            _pageCache.Add(pageReader );

            return pageReader;
        } 

        private 
        void 
        EnsureThumbnail()
        { 
            if( _thumbnail == null )
            {
                _thumbnail = CurrentXpsManager.EnsureThumbnail( this, _metroPart );
            } 
        }
 
 
        private
        void 
        EnsureSignatureDefinitions()
        {
            // if _xpsSignaturs is not null we have already initialized this
            // 
            if( null != _signatureDefinitions)
            { 
                return; 
            }
            _signatureDefinitions = new Collection(); 
            PackagePart sigDefPart =
                CurrentXpsManager.GetSignatureDefinitionPart(Uri);
            if( sigDefPart != null )
            { 
                ParseSignaturePart( sigDefPart, _signatureDefinitions );
            } 
        } 

        private 
        void
        EnsureDoucmentStructure()
        {
            // if _xpsSignaturs is not null we have already initialized this 
            //
            if( null != _documentStructure) 
            { 
                return;
            } 
            PackageRelationship documentStructureRelationship = null;
            PackagePart documentStructurePart = null;

            foreach (PackageRelationship rel in _metroPart.GetRelationshipsByType(XpsS0Markup.StructureRelationshipName)) 
            {
                if (documentStructureRelationship != null) 
                { 
                    throw new InvalidDataException(ReachSR.Get(ReachSRID.ReachPackaging_MoreThanOneDocStructure));
                } 

                documentStructureRelationship = rel;
            }
 
            if (documentStructureRelationship != null)
            { 
                Uri documentStructureUri = PackUriHelper.ResolvePartUri(documentStructureRelationship.SourceUri, 
                                                                documentStructureRelationship.TargetUri);
 
                if (CurrentXpsManager.MetroPackage.PartExists(documentStructureUri))
                {
                    documentStructurePart = CurrentXpsManager.MetroPackage.GetPart(documentStructureUri);
                    _documentStructure = new XpsStructure(CurrentXpsManager, this, documentStructurePart); 
                }
            } 
        } 
        private
        void 
        ParseSignaturePart(
            PackagePart                         sigDefPart,
            Collection  sigDefCollection
            ) 
        {
            XmlTextReader reader = new XmlTextReader( sigDefPart.GetStream(FileMode.Open) ); 
            while( reader.Read() ) 
            {
                if( reader.NodeType == XmlNodeType.Element && 
                    reader.Name == XpsS0Markup.SignatureDefinitions
                  )
                {
                    ParseSignatureDefinitions( reader, sigDefCollection ); 
                }
            } 
        } 

        private 
        void
        ParseSignatureDefinitions(
            XmlReader                           reader,
            Collection  sigDefCollection 
            )
        { 
            bool endLoop = false; 
            while (!endLoop && reader.Read())
            { 
               if( reader.NodeType == XmlNodeType.Element &&
                    reader.Name == XpsS0Markup.SignatureDefinition
                  )
                { 
                    XpsSignatureDefinition sigDef = new XpsSignatureDefinition();
                    sigDef.ReadXML(reader); 
                    sigDefCollection.Add( sigDef ); 
                }
 
               if( reader.NodeType == XmlNodeType.EndElement &&
                    reader.Name == XpsS0Markup.SignatureDefinitions
                  )
                { 
                    endLoop = true;
                } 
            } 
        }
 
        private
        void
        WriteSignatureDefinitions()
        { 
            PackagePart sigDefPart =
                CurrentXpsManager.GetSignatureDefinitionPart(Uri); 
            if( sigDefPart == null ) 
            {
                sigDefPart = CurrentXpsManager.AddSignatureDefinitionPart( _metroPart ); 
            }
            Stream stream = sigDefPart.GetStream(FileMode.Create);
            XmlTextWriter writer = new XmlTextWriter(
                stream, 
                System.Text.Encoding.UTF8
                ); 
            writer.WriteStartDocument(); 
            writer.WriteStartElement( XpsS0Markup.SignatureDefinitions,
            XpsS0Markup.SignatureDefinitionNamespace); 
            foreach( XpsSignatureDefinition sigDef in _signatureDefinitions )
            {
                sigDef.WriteXML( writer );
            } 
            writer.WriteEndElement();
            writer.Close(); 
            stream.Close(); 
            _sigCollectionDirty = false;
        } 



        #endregion Private methods 

        #region Private data 
 
        private PackagePart _metroPart;
        private PrintTicket _printTicket; 

        private XmlPartEditor _partEditor;

        private IList _linkTargetStream; 

        private List _pageCache; 
 
        //
        // This variable flags whether the PrintTicket property is 
        // committed.  A writer can only commit this property once.
        //
        private bool                                _isPrintTicketCommitted;
 
        //
        // These variables are used to keep track of the parent 
        // and current child of this node for walking up and 
        // down the current tree.  This is used be the flushing
        // policy to do interleave flushing of parts correctly. 
        //
        private INode                               _parentNode;

        // 
        // This variable flags wehter the pageCashe
        // has been populated by parsing the part for dependent pages 
        // 
        private bool                                _hasParsedPages;
 
        //
        // 0 based document number in the document sequence
        //
        private int                                 _documentNumber; 

        private XpsThumbnail                        _thumbnail; 
 
        private XpsStructure                        _xpsStructure;
 

        //
        // Since the current page may add link target information
        // we must track our current page 
        // for this reason we can not handle adding new page
        // until the the current page has been committed 
        // 
        private XpsFixedPageReaderWriter            _currentPage;
        // 
        // A cached list of Signature Definitions
        //
        private Collection  _signatureDefinitions;
        // 
        // Boolean indicating whetehr _signatureDefinitions collection
        // has been changed 
        // 
        private bool                                _sigCollectionDirty;
 
        private XpsStructure                        _documentStructure;
        #endregion Private data

        #region Internal properties 

        ///  
        /// Gets a reference to the XmlWriter for the Metro part 
        /// that represents this fixed document.
        ///  
        internal System.Xml.XmlWriter XmlWriter
        {
            get
            { 
                _partEditor.DoesWriteStartEndTags = false;
                return _partEditor.XmlWriter; 
            } 
        }
 
        #endregion Internal properties

        #region INode implementation
 
        void
        INode.Flush( 
            ) 
        {
            // 
            // Commit the PrintTicket (if necessary)
            //
            CommitPrintTicket();
 
            //
            // Flushing the relationship to get 
            // a rels peice before this peice is 
            // only necessary in streaming mode
            // 
            if( CurrentXpsManager.Streaming )
            {
                _partEditor.FlushRelationships();
                _partEditor.Flush(); 
            }
 
 

            // 
            // Create the relationship between the package and the tumbnail
            //
            if( _thumbnail != null )
            { 
                _thumbnail = null;
            } 
        } 

        void 
        INode.CommitInternal(
            )
        {
            CommitInternal(); 
        }
 
        PackagePart 
        INode.GetPart(
            ) 
        {
            return _metroPart;
        }
 
        #endregion INode implementation
 
        #region IDisposable implementation 

        void 
        IDisposable.Dispose(
            )
        {
            CommitInternal(); 
        }
 
        #endregion IDisposable implementation 
    }
} 


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