XamlTreeBuilder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Markup / XamlTreeBuilder.cs / 1 / XamlTreeBuilder.cs

                            /****************************************************************************\ 
*
* File: XamlTreeBuilder.cs
*
* Purpose: Class that builds a tree from XAML 
*
* History: 
*    6/06/01:    rogerg        Created 
*    5/29/03:    peterost      Ported to wcp
* 
* Copyright (C) 2003 by Microsoft Corporation.  All rights reserved.
*
\***************************************************************************/
 
using System;
using System.Xml; 
using System.IO; 
using System.Windows;
using System.Text; 
using System.Collections;
using System.ComponentModel;

using System.Diagnostics; 
using System.Reflection;
using System.Windows.Threading; 
 
using MS.Utility;
 
#if PBTCOMPILER
namespace MS.Internal.Markup
#else
namespace System.Windows.Markup 
#endif
{ 
    ///  
    /// XamlTree builder is the TreeBuilder implementation that loads a Tree
    /// from XAML. 
    /// 
    internal class XamlTreeBuilder : TreeBuilder
    {
#region Constructors 

        ///  
        /// Constructor 
        /// 
        /// ParserContext to Use 
        /// XmlReader input
        /// Should wrap 'reader' with an XML Compatibility Reader
        /// Xaml parse mode
        internal XamlTreeBuilder( 
            ParserContext parserContext,
            XmlReader     reader, 
            bool          wrapWithMarkupCompatReader, 
            XamlParseMode parseMode)
            : base() 
        {
            Debug.Assert(null != parserContext, "ParserContext is null");
            Debug.Assert(null != reader, "TextReader input is null");
            Debug.Assert(null != parserContext.XamlTypeMapper, "ParserContext XamlTypeMapper is null"); 

            XamlParser xamlParser = new TreeBuilderXamlTranslator(this, parserContext, reader, wrapWithMarkupCompatReader, parseMode); 
            Initialize(parserContext, xamlParser); 
        }
 
        /// 
        /// Constructor
        /// 
        /// ParserContext 
        /// input Stream containing the XAML
        /// Xaml parse mode 
        internal XamlTreeBuilder( 
            ParserContext parserContext,
            Stream        stream, 
            XamlParseMode parseMode)
            : base()
        {
            Debug.Assert(null != parserContext, "ParserContext is null"); 
            Debug.Assert(null != stream, "xamlStream is null");
            Debug.Assert(null != parserContext.XamlTypeMapper, "ParserContext XamlTypeMapper is null"); 
 
            XamlParser parser = new TreeBuilderXamlTranslator(this, parserContext, stream, parseMode);
            Initialize(parserContext, parser); 
        }

        /// 
        /// Constructor 
        /// 
        ///  
        /// This constructor is used by sub-classes like 
        /// StyleXamltreeBuilder or TemplateXamlTreeBuilder.
        ///  
        internal XamlTreeBuilder() : base()
        {
        }
 
#endregion Constructors
 
#region Overrides 

        // overrides from the base treebuilder class 
        /// 
        /// Internal Avalon method. Used to parse a BAML file.
        /// 
        /// An array containing the root objects in the XAML stream 
        public override object ParseFragment()
        { 
            // setup the ParserHooks 
            // !!! set this up before asking for the parser mode because
            // the parser mode will always force [....] for now if the ParserHooks is set. 
            _xamlParser.ParserHooks = ParserHooks;

            // Determine the Parse Mode by parsing the first element tag.  Note that
            // we don't want to build the tree top down until we figure out the [....] 
            // mode because of wierd dependencies on the RootList.
            RecordReader.BuildTopDown = false; 
            XamlParseMode = _xamlParser.GetParseMode(); 
            RecordReader.BuildTopDown = true;
 
            // Should this just silently set MultipleRoots to false?
            if(!((XamlParseMode.Synchronous == XamlParseMode)|| !MultipleRoots))
            {
                throw new ApplicationException(SR.Get(SRID.ParserMultiRoot)); 
            }
 
            // if Parse() is called when loading from XAML just turn around and call 
            // the XamlParser.
            if (Dispatcher.CurrentDispatcher != null) 
            {
                // Turn off property invalidation by using DependencyFastBuild.  This
                // creation-mode mechanism should only be used when building a tree
                // in isolation 
                //using (DependencyFastBuild.Start())
                { 
                    _xamlParser.Parse(); 
                }
            } 
            else
            {
                _xamlParser.Parse();
            } 

            // its okay for root to be null if its an empty file or the parse 
            // was stopped. 
            return GetRoot();
        } 

#endregion Overrides

#region Methods 

        ///  
        ///  Stops a parse and throws an exception on the TreeBuilder thread if in 
        /// asynchronous mode
        ///  
        /// Exception
        internal void XamlTreeBuildError(Exception e)
        {
            ParseException = e; 
        }
 
        ///  
        /// Called when the Parser is Cancelled before the
        /// Tree has been completely built. 
        /// 
        internal void XamlTreeBuildCancel()
        {
            ParseCancelled = true; 
        }
 
        // internal function for doing any cleanup immediately following 
        // the tree being complete.
        internal override void TreeBuildComplete() 
        {
            if (ParseCompleted != null)
            {
                // Fire the ParseCompleted event asynchronously 
                Dispatcher.CurrentDispatcher.BeginInvoke(
                    DispatcherPriority.Normal, 
                    (DispatcherOperationCallback) delegate(object obj) 
                    {
                        ParseCompleted(this, EventArgs.Empty); 
                        return null;
                    },
                    null);
            } 
        }
 
        ///  
        /// This event is fired when the parse is complete
        ///  
        internal event EventHandler ParseCompleted;

        /// 
        /// Callback in when a new record has been created from the parse 
        /// Builder can either immediately use the record "[....] mode"
        /// or false can be returned to indicate that the record was not 
        /// processed and should be written to BAML. 
        /// 
        /// bamlRecord to process 
        /// line number in associated xaml file
        /// offset from left margin in associated xaml file
        /// true if record was handled
        internal bool BamlRecordWriterSyncUpdate( 
            BamlRecord bamlRecord,
            int        lineNumber, 
            int        linePosition) 
        {
            bool bamlRecordHandled = true; 

            // !!!! this code relies on the XamlParser sitting on the UIThread
            // until we get a root. Therefore XamlParser can't go async until
            // after it has finished parsing the root. 

            // !!! Todo: This code needs to be reworked when get async binding support 
            // since in async we wouldn't need to sit in a loop to build the root. 

            if (XamlParseMode != XamlParseMode.Asynchronous || GetRoot() == null) 
            {

                Debug.Assert(false == RecordReader.EndOfDocument); // shouldn't be called after end
 
                // call read passing in the bamlRecord
                RecordReader.Read(bamlRecord, lineNumber, linePosition); 
 
                // if found the endOfDocument record then mark as complete.
                // !!Review, what if we never get an EndOfDocument. 
                if (RecordReader.EndOfDocument)
                {
                    TreeBuildComplete();
                } 
                else
                { 
                    // if got a root we are going to ignore the rest of the [....] calls 
                    // if we are in async mode so post a work item
                    if (GetRoot() != null && XamlParseMode == XamlParseMode.Asynchronous 
                        && false == RecordReader.EndOfDocument)
                    {
                        // !! first post post the priority as normal so
                        // don't always get a single record. 
                        Post(DispatcherPriority.Normal);
                    } 
                } 
            }
            else 
            {
                // we want to handle this async
                bamlRecordHandled = false;
            } 

            return bamlRecordHandled; 
 
        }
 

        // common call for Building From Xaml after the XamlParser class
        // has been created.
        void Initialize(ParserContext parserContext,XamlParser parser) 
        {
            Debug.Assert(null != parserContext,"ParserContext cannot be null"); 
            Debug.Assert(null != parser,"parser paramater is null"); 

            _xamlParser = parser; 

            // setup StreamManager, don't set our property since the StreamManager
            // property is only intended for Async BAML.
            ReadWriteStreamManager streamManager = new ReadWriteStreamManager(); 

            // since RecordReader alters the context make a copy to pass into the Reader. 
            ParserContext readerParserContext = new ParserContext(parserContext); 

            _bamlWriter = new XamlTreeBuilderBamlRecordWriter(this,streamManager.WriterStream, 
                                                     parserContext, false /*isSerializer*/ );

            RecordReader = new BamlRecordReader(streamManager.ReaderStream,readerParserContext,false /* loadMapTable */);
 
            // give Writer to the Parser.
            _xamlParser.BamlRecordWriter = _bamlWriter; 
            _xamlParser.StreamManager = streamManager; 
        }
 

#endregion Methods

#region Properties 

        ///  
        /// Indicates if Multiple top-level roots are allowed 
        /// 
        internal bool MultipleRoots 
        {
            get { return false; }
        }
 
        /// 
        ///  XamlParser that has the main parse loop and writer overrides 
        ///  
        internal XamlParser Parser
        { 
            get { return _xamlParser; }
            set { _xamlParser = value; }
        }
 
        /// 
        ///  Writer of baml records, either to a stream or to buffer. 
        ///  
        internal BamlRecordWriter RecordWriter
        { 
            get { return _bamlWriter; }
            set { _bamlWriter = value; }
        }
 
#endregion Properties
 
#region Data 

        // XamlParser that is being used for Parsing the XAML 
        XamlParser _xamlParser;

        // BamlWriter to use if writing out BAML
        BamlRecordWriter _bamlWriter; 

#endregion Data 
    } 

 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/****************************************************************************\ 
*
* File: XamlTreeBuilder.cs
*
* Purpose: Class that builds a tree from XAML 
*
* History: 
*    6/06/01:    rogerg        Created 
*    5/29/03:    peterost      Ported to wcp
* 
* Copyright (C) 2003 by Microsoft Corporation.  All rights reserved.
*
\***************************************************************************/
 
using System;
using System.Xml; 
using System.IO; 
using System.Windows;
using System.Text; 
using System.Collections;
using System.ComponentModel;

using System.Diagnostics; 
using System.Reflection;
using System.Windows.Threading; 
 
using MS.Utility;
 
#if PBTCOMPILER
namespace MS.Internal.Markup
#else
namespace System.Windows.Markup 
#endif
{ 
    ///  
    /// XamlTree builder is the TreeBuilder implementation that loads a Tree
    /// from XAML. 
    /// 
    internal class XamlTreeBuilder : TreeBuilder
    {
#region Constructors 

        ///  
        /// Constructor 
        /// 
        /// ParserContext to Use 
        /// XmlReader input
        /// Should wrap 'reader' with an XML Compatibility Reader
        /// Xaml parse mode
        internal XamlTreeBuilder( 
            ParserContext parserContext,
            XmlReader     reader, 
            bool          wrapWithMarkupCompatReader, 
            XamlParseMode parseMode)
            : base() 
        {
            Debug.Assert(null != parserContext, "ParserContext is null");
            Debug.Assert(null != reader, "TextReader input is null");
            Debug.Assert(null != parserContext.XamlTypeMapper, "ParserContext XamlTypeMapper is null"); 

            XamlParser xamlParser = new TreeBuilderXamlTranslator(this, parserContext, reader, wrapWithMarkupCompatReader, parseMode); 
            Initialize(parserContext, xamlParser); 
        }
 
        /// 
        /// Constructor
        /// 
        /// ParserContext 
        /// input Stream containing the XAML
        /// Xaml parse mode 
        internal XamlTreeBuilder( 
            ParserContext parserContext,
            Stream        stream, 
            XamlParseMode parseMode)
            : base()
        {
            Debug.Assert(null != parserContext, "ParserContext is null"); 
            Debug.Assert(null != stream, "xamlStream is null");
            Debug.Assert(null != parserContext.XamlTypeMapper, "ParserContext XamlTypeMapper is null"); 
 
            XamlParser parser = new TreeBuilderXamlTranslator(this, parserContext, stream, parseMode);
            Initialize(parserContext, parser); 
        }

        /// 
        /// Constructor 
        /// 
        ///  
        /// This constructor is used by sub-classes like 
        /// StyleXamltreeBuilder or TemplateXamlTreeBuilder.
        ///  
        internal XamlTreeBuilder() : base()
        {
        }
 
#endregion Constructors
 
#region Overrides 

        // overrides from the base treebuilder class 
        /// 
        /// Internal Avalon method. Used to parse a BAML file.
        /// 
        /// An array containing the root objects in the XAML stream 
        public override object ParseFragment()
        { 
            // setup the ParserHooks 
            // !!! set this up before asking for the parser mode because
            // the parser mode will always force [....] for now if the ParserHooks is set. 
            _xamlParser.ParserHooks = ParserHooks;

            // Determine the Parse Mode by parsing the first element tag.  Note that
            // we don't want to build the tree top down until we figure out the [....] 
            // mode because of wierd dependencies on the RootList.
            RecordReader.BuildTopDown = false; 
            XamlParseMode = _xamlParser.GetParseMode(); 
            RecordReader.BuildTopDown = true;
 
            // Should this just silently set MultipleRoots to false?
            if(!((XamlParseMode.Synchronous == XamlParseMode)|| !MultipleRoots))
            {
                throw new ApplicationException(SR.Get(SRID.ParserMultiRoot)); 
            }
 
            // if Parse() is called when loading from XAML just turn around and call 
            // the XamlParser.
            if (Dispatcher.CurrentDispatcher != null) 
            {
                // Turn off property invalidation by using DependencyFastBuild.  This
                // creation-mode mechanism should only be used when building a tree
                // in isolation 
                //using (DependencyFastBuild.Start())
                { 
                    _xamlParser.Parse(); 
                }
            } 
            else
            {
                _xamlParser.Parse();
            } 

            // its okay for root to be null if its an empty file or the parse 
            // was stopped. 
            return GetRoot();
        } 

#endregion Overrides

#region Methods 

        ///  
        ///  Stops a parse and throws an exception on the TreeBuilder thread if in 
        /// asynchronous mode
        ///  
        /// Exception
        internal void XamlTreeBuildError(Exception e)
        {
            ParseException = e; 
        }
 
        ///  
        /// Called when the Parser is Cancelled before the
        /// Tree has been completely built. 
        /// 
        internal void XamlTreeBuildCancel()
        {
            ParseCancelled = true; 
        }
 
        // internal function for doing any cleanup immediately following 
        // the tree being complete.
        internal override void TreeBuildComplete() 
        {
            if (ParseCompleted != null)
            {
                // Fire the ParseCompleted event asynchronously 
                Dispatcher.CurrentDispatcher.BeginInvoke(
                    DispatcherPriority.Normal, 
                    (DispatcherOperationCallback) delegate(object obj) 
                    {
                        ParseCompleted(this, EventArgs.Empty); 
                        return null;
                    },
                    null);
            } 
        }
 
        ///  
        /// This event is fired when the parse is complete
        ///  
        internal event EventHandler ParseCompleted;

        /// 
        /// Callback in when a new record has been created from the parse 
        /// Builder can either immediately use the record "[....] mode"
        /// or false can be returned to indicate that the record was not 
        /// processed and should be written to BAML. 
        /// 
        /// bamlRecord to process 
        /// line number in associated xaml file
        /// offset from left margin in associated xaml file
        /// true if record was handled
        internal bool BamlRecordWriterSyncUpdate( 
            BamlRecord bamlRecord,
            int        lineNumber, 
            int        linePosition) 
        {
            bool bamlRecordHandled = true; 

            // !!!! this code relies on the XamlParser sitting on the UIThread
            // until we get a root. Therefore XamlParser can't go async until
            // after it has finished parsing the root. 

            // !!! Todo: This code needs to be reworked when get async binding support 
            // since in async we wouldn't need to sit in a loop to build the root. 

            if (XamlParseMode != XamlParseMode.Asynchronous || GetRoot() == null) 
            {

                Debug.Assert(false == RecordReader.EndOfDocument); // shouldn't be called after end
 
                // call read passing in the bamlRecord
                RecordReader.Read(bamlRecord, lineNumber, linePosition); 
 
                // if found the endOfDocument record then mark as complete.
                // !!Review, what if we never get an EndOfDocument. 
                if (RecordReader.EndOfDocument)
                {
                    TreeBuildComplete();
                } 
                else
                { 
                    // if got a root we are going to ignore the rest of the [....] calls 
                    // if we are in async mode so post a work item
                    if (GetRoot() != null && XamlParseMode == XamlParseMode.Asynchronous 
                        && false == RecordReader.EndOfDocument)
                    {
                        // !! first post post the priority as normal so
                        // don't always get a single record. 
                        Post(DispatcherPriority.Normal);
                    } 
                } 
            }
            else 
            {
                // we want to handle this async
                bamlRecordHandled = false;
            } 

            return bamlRecordHandled; 
 
        }
 

        // common call for Building From Xaml after the XamlParser class
        // has been created.
        void Initialize(ParserContext parserContext,XamlParser parser) 
        {
            Debug.Assert(null != parserContext,"ParserContext cannot be null"); 
            Debug.Assert(null != parser,"parser paramater is null"); 

            _xamlParser = parser; 

            // setup StreamManager, don't set our property since the StreamManager
            // property is only intended for Async BAML.
            ReadWriteStreamManager streamManager = new ReadWriteStreamManager(); 

            // since RecordReader alters the context make a copy to pass into the Reader. 
            ParserContext readerParserContext = new ParserContext(parserContext); 

            _bamlWriter = new XamlTreeBuilderBamlRecordWriter(this,streamManager.WriterStream, 
                                                     parserContext, false /*isSerializer*/ );

            RecordReader = new BamlRecordReader(streamManager.ReaderStream,readerParserContext,false /* loadMapTable */);
 
            // give Writer to the Parser.
            _xamlParser.BamlRecordWriter = _bamlWriter; 
            _xamlParser.StreamManager = streamManager; 
        }
 

#endregion Methods

#region Properties 

        ///  
        /// Indicates if Multiple top-level roots are allowed 
        /// 
        internal bool MultipleRoots 
        {
            get { return false; }
        }
 
        /// 
        ///  XamlParser that has the main parse loop and writer overrides 
        ///  
        internal XamlParser Parser
        { 
            get { return _xamlParser; }
            set { _xamlParser = value; }
        }
 
        /// 
        ///  Writer of baml records, either to a stream or to buffer. 
        ///  
        internal BamlRecordWriter RecordWriter
        { 
            get { return _bamlWriter; }
            set { _bamlWriter = value; }
        }
 
#endregion Properties
 
#region Data 

        // XamlParser that is being used for Parsing the XAML 
        XamlParser _xamlParser;

        // BamlWriter to use if writing out BAML
        BamlRecordWriter _bamlWriter; 

#endregion Data 
    } 

 
}

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