예제 #1
0
        public static void Transform(XamlReader xamlReader, XamlWriter xamlWriter, bool closeWriter)
        {
            if (xamlReader == null)
            {
                throw new ArgumentNullException("xamlReader");
            }
            if (xamlWriter == null)
            {
                throw new ArgumentNullException("xamlWriter");
            }
            IXamlLineInfo         info     = xamlReader as IXamlLineInfo;
            IXamlLineInfoConsumer consumer = xamlWriter as IXamlLineInfoConsumer;
            bool flag = false;

            if (((info != null) && info.HasLineInfo) && ((consumer != null) && consumer.ShouldProvideLineInfo))
            {
                flag = true;
            }
            while (xamlReader.Read())
            {
                if (flag && (info.LineNumber != 0))
                {
                    consumer.SetLineInfo(info.LineNumber, info.LinePosition);
                }
                xamlWriter.WriteNode(xamlReader);
            }
            if (closeWriter)
            {
                xamlWriter.Close();
            }
        }
예제 #2
0
        public static void PropagateLineInfo(XamlWriter targetWriter, int lineNumber, int linePosition)
        {
            IXamlLineInfoConsumer consumer = targetWriter as IXamlLineInfoConsumer;

            Fx.Assert(consumer != null && consumer.ShouldProvideLineInfo, "Should only call this function to write into a XamlNodeQueue.Writer, which is always IXamlLineInfoConsumer");
            consumer.SetLineInfo(lineNumber, linePosition);
        }
예제 #3
0
        private void InterruptableTransform(XamlReader reader, XamlWriter writer, bool closeWriter)
        {
            IXamlLineInfo         info     = reader as IXamlLineInfo;
            IXamlLineInfoConsumer consumer = writer as IXamlLineInfoConsumer;
            bool flag = false;

            if (((info != null) && info.HasLineInfo) && ((consumer != null) && consumer.ShouldProvideLineInfo))
            {
                flag = true;
            }
            while (reader.Read())
            {
                if (base.IsDisposed)
                {
                    break;
                }
                if (flag && (info.LineNumber != 0))
                {
                    consumer.SetLineInfo(info.LineNumber, info.LinePosition);
                }
                writer.WriteNode(reader);
            }
            if (closeWriter)
            {
                writer.Close();
            }
        }
예제 #4
0
        // This method is a workaround for TFS bug #788190, since XamlReader.ReadSubtree() should (but doesn't) preserve IXamlLineInfo on the subreader
        public static void Transform(XamlReader reader, XamlWriter writer, IXamlLineInfo readerLineInfo, bool closeWriter)
        {
            IXamlLineInfoConsumer consumer = writer as IXamlLineInfoConsumer;

            Fx.Assert(consumer != null && consumer.ShouldProvideLineInfo, "Should only call this function to write into a XamlNodeQueue.Writer, which is always IXamlLineInfoConsumer");
            bool shouldPassLineNumberInfo = false;

            if (readerLineInfo != null)
            {
                shouldPassLineNumberInfo = true;
            }

            while (reader.Read())
            {
                if (shouldPassLineNumberInfo)
                {
                    consumer.SetLineInfo(readerLineInfo.LineNumber, readerLineInfo.LinePosition);
                }
                writer.WriteNode(reader);
            }

            if (closeWriter)
            {
                writer.Close();
            }
        }
예제 #5
0
        // This method reads ViewStateManager nodes from the xaml nodestream and outputs that in the
        // viewStateInfo dictionary. The input reader is positioned at the begining of the workflow definition.
        // The method returns a reader positioned at the begining of the workflow definition with the ViewStateManager
        // nodes removed.
        static XamlReader StripViewStateElement(XamlReader inputReader, out Dictionary <string, XamlNodeList> viewStateInfo, out Dictionary <string, SourceLocation> viewStateSourceLocationMap)
        {
            viewStateSourceLocationMap = null;
            XamlNodeList strippedNodeList = new XamlNodeList(inputReader.SchemaContext);
            XamlMember   viewStateManager = new XamlMember(ViewStateManager, GetViewStateManager, SetViewStateManager, inputReader.SchemaContext);

            using (XamlWriter strippedWriter = strippedNodeList.Writer)
            {
                IXamlLineInfo         lineInfo         = inputReader as IXamlLineInfo;
                IXamlLineInfoConsumer lineInfoComsumer = strippedWriter as IXamlLineInfoConsumer;
                bool shouldPassLineInfo = lineInfo != null && lineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

                viewStateInfo = null;
                while (inputReader.Read())
                {
                    if (inputReader.NodeType == XamlNodeType.StartMember && inputReader.Member.Equals(viewStateManager))
                    {
                        ReadViewStateInfo(inputReader.ReadSubtree(), out viewStateInfo, out viewStateSourceLocationMap);
                    }

                    if (shouldPassLineInfo)
                    {
                        lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                    }

                    strippedWriter.WriteNode(inputReader);
                }
            }

            return(strippedNodeList.GetReader());
        }
        private void InterruptableTransform(XamlReader reader, XamlWriter writer, bool closeWriter)
        {
            IXamlLineInfo         xamlLineInfo         = reader as IXamlLineInfo;
            IXamlLineInfoConsumer xamlLineInfoConsumer = writer as IXamlLineInfoConsumer;
            bool shouldPassLineNumberInfo = false;

            if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) &&
                (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo))
            {
                shouldPassLineNumberInfo = true;
            }
            while (reader.Read())
            {
                if (IsDisposed)
                {
                    break;
                }
                if (shouldPassLineNumberInfo)
                {
                    if (xamlLineInfo.LineNumber != 0)
                    {
                        xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition);
                    }
                }
                writer.WriteNode(reader);
            }

            if (closeWriter)
            {
                writer.Close();
            }
        }
예제 #7
0
 private void Initialize()
 {
     IndentUnit     = " ";
     FromMemberText = "Retrieved";
     UnknownText    = "Unknown";
     ImplicitText   = "Implicit";
     _stack         = new SimpleWriterStack();
     _wrappedWriterLineInfoConsumer = _wrappedWriter as IXamlLineInfoConsumer;
 }
예제 #8
0
        public DiagnosticWriter(XamlSchemaContext schemaContext)
        {
            _schemaContext = schemaContext;
            _nodeText      = String.Empty;
            _indent        = 0;

            _stringbuilder = null;
            _wrappedWriter = null;
            _wrappedWriterLineInfoConsumer = null;
        }
예제 #9
0
 private void StartDeferredList()
 {
     // the list may have been created already by SetLineInfo
     if (_deferredList == null)
     {
         _deferredList             = new XamlNodeList(_context.SchemaContext);
         _deferredWriter           = _deferredList.Writer;
         _deferredLineInfoConsumer = _deferredWriter as IXamlLineInfoConsumer;
         _deferredTreeDepth        = 0;
     }
 }
        // Copy the root namespaces from a reader to a writer.
        // DesignTimeXamlWriter follows proper XAML convention by omitting the assembly name from
        // clr-namespaces in the local assembly. However, VB Expressions aren't local-assembly-aware,
        // and require an assembly name. So for every clr-namespace with no assembly name, we add an
        // additional namespace record with an assembly name, to support VB.
        // We only do this at the root level, since the designer only writes out namespaces at the root level.
        internal void CopyNamespacesAndAddLocalAssembly(System.Xaml.XamlReader activityBuilderReader, System.Xaml.XamlWriter objectWriter)
        {
            // Designer loads alwas provide line info
            IXamlLineInfo               lineInfo           = (IXamlLineInfo)activityBuilderReader;
            IXamlLineInfoConsumer       lineInfoConsumer   = (IXamlLineInfoConsumer)objectWriter;
            HashSet <string>            definedPrefixes    = new HashSet <string>();
            List <NamespaceDeclaration> localAsmNamespaces = null;

            while (activityBuilderReader.Read())
            {
                lineInfoConsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);

                if (activityBuilderReader.NodeType == XamlNodeType.NamespaceDeclaration)
                {
                    definedPrefixes.Add(activityBuilderReader.Namespace.Prefix);
                    if (this.XamlSchemaContext.IsClrNamespaceWithNoAssembly(activityBuilderReader.Namespace.Namespace))
                    {
                        if (localAsmNamespaces == null)
                        {
                            localAsmNamespaces = new List <NamespaceDeclaration>();
                        }

                        localAsmNamespaces.Add(activityBuilderReader.Namespace);
                    }

                    objectWriter.WriteNode(activityBuilderReader);
                }
                else
                {
                    if (localAsmNamespaces != null)
                    {
                        foreach (NamespaceDeclaration ns in localAsmNamespaces)
                        {
                            string prefix = null;
                            int    i      = 0;
                            do
                            {
                                i++;
                                prefix = ns.Prefix + i.ToString(CultureInfo.InvariantCulture);
                            }while (definedPrefixes.Contains(prefix));
                            string fullNs = this.XamlSchemaContext.AddLocalAssembly(ns.Namespace);
                            objectWriter.WriteNamespace(new NamespaceDeclaration(fullNs, prefix));
                            definedPrefixes.Add(prefix);
                        }
                    }

                    objectWriter.WriteNode(activityBuilderReader);
                    return;
                }
            }
        }
예제 #11
0
 protected override void Dispose(bool disposing)
 {
     try
     {
         if (disposing && !IsDisposed)
         {
             if (_deferredWriter != null)
             {
                 _deferredWriter.Close();
                 _deferredWriter           = null;
                 _deferredLineInfoConsumer = null;
             }
         }
     }
     finally
     {
         base.Dispose(disposing);
     }
 }
예제 #12
0
        public static void Transform(XamlReader reader, XamlWriter writer, IXamlLineInfo readerLineInfo, bool closeWriter)
        {
            IXamlLineInfoConsumer consumer = writer as IXamlLineInfoConsumer;
            bool flag = false;

            if (readerLineInfo != null)
            {
                flag = true;
            }
            while (reader.Read())
            {
                if (flag)
                {
                    consumer.SetLineInfo(readerLineInfo.LineNumber, readerLineInfo.LinePosition);
                }
                writer.WriteNode(reader);
            }
            if (closeWriter)
            {
                writer.Close();
            }
        }
예제 #13
0
        public static void Transform(XamlReader xamlReader, XamlWriter xamlWriter, bool closeWriter)
        {
            if (xamlReader == null)
            {
                throw new ArgumentNullException(nameof(xamlReader));
            }

            if (xamlWriter == null)
            {
                throw new ArgumentNullException(nameof(xamlWriter));
            }

            IXamlLineInfo         xamlLineInfo         = xamlReader as IXamlLineInfo;
            IXamlLineInfoConsumer xamlLineInfoConsumer = xamlWriter as IXamlLineInfoConsumer;
            bool shouldPassLineNumberInfo = false;

            if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) &&
                (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo))
            {
                shouldPassLineNumberInfo = true;
            }

            while (xamlReader.Read())
            {
                if (shouldPassLineNumberInfo)
                {
                    if (xamlLineInfo.LineNumber != 0)
                    {
                        xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition);
                    }
                }
                xamlWriter.WriteNode(xamlReader);
            }

            if (closeWriter)
            {
                xamlWriter.Close();
            }
        }
예제 #14
0
        // Token: 0x0600226B RID: 8811 RVA: 0x000AAF38 File Offset: 0x000A9138
        internal static void TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, bool onlyLoadOneNode, bool skipJournaledProperties, bool shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack <WpfXamlFrame> stack, IStyleConnector styleConnector)
        {
            while (xamlReader.Read())
            {
                if (shouldPassLineNumberInfo && xamlLineInfo.LineNumber != 0)
                {
                    xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition);
                }
                switch (xamlReader.NodeType)
                {
                case XamlNodeType.StartObject:
                    WpfXamlLoader.WriteStartObject(xamlReader, xamlWriter, stack);
                    break;

                case XamlNodeType.GetObject:
                    xamlWriter.WriteNode(xamlReader);
                    if (stack.CurrentFrame.Type != null)
                    {
                        stack.PushScope();
                    }
                    stack.CurrentFrame.Type = stack.PreviousFrame.Property.Type;
                    break;

                case XamlNodeType.EndObject:
                {
                    xamlWriter.WriteNode(xamlReader);
                    if (stack.CurrentFrame.FreezeFreezable)
                    {
                        Freezable freezable = xamlWriter.Result as Freezable;
                        if (freezable != null && freezable.CanFreeze)
                        {
                            freezable.Freeze();
                        }
                    }
                    DependencyObject dependencyObject = xamlWriter.Result as DependencyObject;
                    if (dependencyObject != null && stack.CurrentFrame.XmlSpace != null)
                    {
                        XmlAttributeProperties.SetXmlSpace(dependencyObject, stack.CurrentFrame.XmlSpace.Value ? "default" : "preserve");
                    }
                    stack.PopScope();
                    break;
                }

                case XamlNodeType.StartMember:
                    if ((!xamlReader.Member.IsDirective || !(xamlReader.Member == XamlReaderHelper.Freeze)) && xamlReader.Member != WpfXamlLoader.XmlSpace.Value && xamlReader.Member != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader);
                    }
                    stack.CurrentFrame.Property = xamlReader.Member;
                    if (skipJournaledProperties && !stack.CurrentFrame.Property.IsDirective)
                    {
                        WpfXamlMember wpfXamlMember = stack.CurrentFrame.Property as WpfXamlMember;
                        if (wpfXamlMember != null)
                        {
                            DependencyProperty dependencyProperty = wpfXamlMember.DependencyProperty;
                            if (dependencyProperty != null)
                            {
                                FrameworkPropertyMetadata frameworkPropertyMetadata = dependencyProperty.GetMetadata(stack.CurrentFrame.Type.UnderlyingType) as FrameworkPropertyMetadata;
                                if (frameworkPropertyMetadata != null && frameworkPropertyMetadata.Journal)
                                {
                                    int num = 1;
                                    while (xamlReader.Read())
                                    {
                                        switch (xamlReader.NodeType)
                                        {
                                        case XamlNodeType.StartObject:
                                        {
                                            XamlType type      = xamlReader.Type;
                                            XamlType xamlType  = type.SchemaContext.GetXamlType(typeof(BindingBase));
                                            XamlType xamlType2 = type.SchemaContext.GetXamlType(typeof(DynamicResourceExtension));
                                            if (num == 1 && (type.CanAssignTo(xamlType) || type.CanAssignTo(xamlType2)))
                                            {
                                                num = 0;
                                                WpfXamlLoader.WriteStartObject(xamlReader, xamlWriter, stack);
                                            }
                                            break;
                                        }

                                        case XamlNodeType.StartMember:
                                            num++;
                                            break;

                                        case XamlNodeType.EndMember:
                                            num--;
                                            if (num == 0)
                                            {
                                                xamlWriter.WriteNode(xamlReader);
                                                stack.CurrentFrame.Property = null;
                                            }
                                            break;

                                        case XamlNodeType.Value:
                                        {
                                            DynamicResourceExtension dynamicResourceExtension = xamlReader.Value as DynamicResourceExtension;
                                            if (dynamicResourceExtension != null)
                                            {
                                                WpfXamlLoader.WriteValue(xamlReader, xamlWriter, stack, styleConnector);
                                            }
                                            break;
                                        }
                                        }
                                        if (num == 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;

                case XamlNodeType.EndMember:
                {
                    WpfXamlFrame currentFrame = stack.CurrentFrame;
                    XamlMember   property     = currentFrame.Property;
                    if ((!property.IsDirective || !(property == XamlReaderHelper.Freeze)) && property != WpfXamlLoader.XmlSpace.Value && property != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader);
                    }
                    currentFrame.Property = null;
                    break;
                }

                case XamlNodeType.Value:
                    WpfXamlLoader.WriteValue(xamlReader, xamlWriter, stack, styleConnector);
                    break;

                case XamlNodeType.NamespaceDeclaration:
                    xamlWriter.WriteNode(xamlReader);
                    if (stack.Depth == 0 || stack.CurrentFrame.Type != null)
                    {
                        stack.PushScope();
                        for (WpfXamlFrame wpfXamlFrame = stack.CurrentFrame; wpfXamlFrame != null; wpfXamlFrame = (WpfXamlFrame)wpfXamlFrame.Previous)
                        {
                            if (wpfXamlFrame.XmlnsDictionary != null)
                            {
                                stack.CurrentFrame.XmlnsDictionary = new XmlnsDictionary(wpfXamlFrame.XmlnsDictionary);
                                break;
                            }
                        }
                        if (stack.CurrentFrame.XmlnsDictionary == null)
                        {
                            stack.CurrentFrame.XmlnsDictionary = new XmlnsDictionary();
                        }
                    }
                    stack.CurrentFrame.XmlnsDictionary.Add(xamlReader.Namespace.Prefix, xamlReader.Namespace.Namespace);
                    break;

                default:
                    xamlWriter.WriteNode(xamlReader);
                    break;
                }
                if (onlyLoadOneNode)
                {
                    return;
                }
            }
        }
예제 #15
0
        /// <summary>
        /// called when in async mode when get a time slice to read and load the Tree
        /// </summary>
        internal virtual void HandleAsyncQueueItem()
        {
            try
            {
                int startTickCount = MS.Win32.SafeNativeMethods.GetTickCount();
                //bool moreData = true;

                // for debugging, can set the Maximum Async records to
                // read via markup
                // x:AsyncRecords="3" would loop three times
                // Todo: This should either be removed at some point
                int maxRecords = _maxAsynxRecords;

                System.Xaml.XamlReader xamlReader = _textReader;

                IXamlLineInfo         xamlLineInfo         = xamlReader as IXamlLineInfo;
                IXamlLineInfoConsumer xamlLineInfoConsumer = _objectWriter as IXamlLineInfoConsumer;
                bool shouldPassLineNumberInfo = false;
                if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) &&
                    (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo))
                {
                    shouldPassLineNumberInfo = true;
                }

                XamlMember synchronousRecordProperty = _textReader.SchemaContext.GetXamlDirective(XamlLanguage.Xaml2006Namespace, "AsyncRecords");

                while (!xamlReader.IsEof && !_parseCancelled)
                {
                    WpfXamlLoader.TransformNodes(xamlReader, _objectWriter, true /*onlyLoadOneNode*/, _skipJournaledProperties, shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer, _stack, _styleConnector);

                    if (xamlReader.NodeType == System.Xaml.XamlNodeType.Value && _stack.CurrentFrame.Property == synchronousRecordProperty)
                    {
                        if (xamlReader.Value is int)
                        {
                            _maxAsynxRecords = (int)xamlReader.Value;
                        }
                        else if (xamlReader.Value is String)
                        {
                            _maxAsynxRecords = Int32.Parse(xamlReader.Value as String, TypeConverterHelper.InvariantEnglishUS);
                        }
                        maxRecords = _maxAsynxRecords;
                    }

                    //Debug.Assert (1 >= RootList.Count, "Multiple roots not supported in async mode");

                    // check the timeout
                    int elapsed = MS.Win32.SafeNativeMethods.GetTickCount() - startTickCount;

                    // check for rollover
                    if (elapsed < 0)
                    {
                        startTickCount = 0; // reset to 0,
                    }
                    else if (elapsed > AsyncLoopTimeout)
                    {
                        break;
                    }

                    // decrement and compare with zero so the unitialized -1  and zero case
                    // doesn't break the loop.
                    if (--maxRecords == 0)
                    {
                        break;
                    }
                }
            }
            catch (XamlParseException e)
            {
                _parseException = e;
            }
            catch (Exception e)
            {
                if (CriticalExceptions.IsCriticalException(e) || !XamlReader.ShouldReWrapException(e, _baseUri))
                {
                    _parseException = e;
                }
                else
                {
                    _parseException = XamlReader.WrapException(e, null, _baseUri);
                }
            }
            finally
            {
                if (_parseException != null || _parseCancelled)
                {
                    TreeBuildComplete();
                }
                else
                {
                    // if not at the EndOfDocument then post another work item
                    if (false == _textReader.IsEof)
                    {
                        Post();
                    }
                    else
                    {
                        // Building of the Tree is complete.
                        TreeBuildComplete();
                    }
                }
            }
        }
예제 #16
0
        private object LoadAsync(XmlReader reader, ParserContext parserContext)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (parserContext == null)
            {
                parserContext = new ParserContext();
            }

            _xmlReader = reader;
            object rootObject = null;

            if (parserContext.BaseUri == null ||
                String.IsNullOrEmpty(parserContext.BaseUri.ToString()))
            {
                if (reader.BaseURI == null ||
                    String.IsNullOrEmpty(reader.BaseURI.ToString()))
                {
                    parserContext.BaseUri = BaseUriHelper.PackAppBaseUri;
                }
                else
                {
                    parserContext.BaseUri = new Uri(reader.BaseURI);
                }
            }
            _baseUri = parserContext.BaseUri;
            System.Xaml.XamlXmlReaderSettings settings = new System.Xaml.XamlXmlReaderSettings();
            settings.IgnoreUidsOnPropertyElements = true;
            settings.BaseUri         = parserContext.BaseUri;
            settings.ProvideLineInfo = true;
            XamlSchemaContext schemaContext = parserContext.XamlTypeMapper != null ?
                                              parserContext.XamlTypeMapper.SchemaContext : GetWpfSchemaContext();

            try
            {
                _textReader = new System.Xaml.XamlXmlReader(reader, schemaContext, settings);

                _stack = new XamlContextStack <WpfXamlFrame>(() => new WpfXamlFrame());

                System.Xaml.XamlObjectWriterSettings objectSettings = XamlReader.CreateObjectWriterSettings();
                objectSettings.AfterBeginInitHandler = delegate(object sender, System.Xaml.XamlObjectEventArgs args)
                {
                    if (rootObject == null)
                    {
                        rootObject      = args.Instance;
                        _styleConnector = rootObject as IStyleConnector;
                    }

                    UIElement uiElement = args.Instance as UIElement;
                    if (uiElement != null)
                    {
                        uiElement.SetPersistId(_persistId++);
                    }

                    DependencyObject dObject = args.Instance as DependencyObject;
                    if (dObject != null && _stack.CurrentFrame.XmlnsDictionary != null)
                    {
                        XmlnsDictionary dictionary = _stack.CurrentFrame.XmlnsDictionary;
                        dictionary.Seal();

                        XmlAttributeProperties.SetXmlnsDictionary(dObject, dictionary);
                    }
                };

                _objectWriter            = new System.Xaml.XamlObjectWriter(_textReader.SchemaContext, objectSettings);
                _parseCancelled          = false;
                _skipJournaledProperties = parserContext.SkipJournaledProperties;

                XamlMember synchronousModeProperty   = _textReader.SchemaContext.GetXamlDirective("http://schemas.microsoft.com/winfx/2006/xaml", "SynchronousMode");
                XamlMember synchronousRecordProperty = _textReader.SchemaContext.GetXamlDirective("http://schemas.microsoft.com/winfx/2006/xaml", "AsyncRecords");

                System.Xaml.XamlReader xamlReader = _textReader;

                IXamlLineInfo         xamlLineInfo         = xamlReader as IXamlLineInfo;
                IXamlLineInfoConsumer xamlLineInfoConsumer = _objectWriter as IXamlLineInfoConsumer;
                bool shouldPassLineNumberInfo = false;
                if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) &&
                    (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo))
                {
                    shouldPassLineNumberInfo = true;
                }

                bool async = false;
                bool lastPropWasSyncMode    = false;
                bool lastPropWasSyncRecords = false;

                while (!_textReader.IsEof)
                {
                    WpfXamlLoader.TransformNodes(xamlReader, _objectWriter, true /*onlyLoadOneNode*/, _skipJournaledProperties, shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer, _stack, _styleConnector);

                    if (xamlReader.NodeType == System.Xaml.XamlNodeType.StartMember)
                    {
                        if (xamlReader.Member == synchronousModeProperty)
                        {
                            lastPropWasSyncMode = true;
                        }
                        else if (xamlReader.Member == synchronousRecordProperty)
                        {
                            lastPropWasSyncRecords = true;
                        }
                    }
                    else if (xamlReader.NodeType == System.Xaml.XamlNodeType.Value)
                    {
                        if (lastPropWasSyncMode == true)
                        {
                            if (xamlReader.Value as String == "Async")
                            {
                                async = true;
                            }
                        }
                        else if (lastPropWasSyncRecords == true)
                        {
                            if (xamlReader.Value is int)
                            {
                                _maxAsynxRecords = (int)xamlReader.Value;
                            }
                            else if (xamlReader.Value is String)
                            {
                                _maxAsynxRecords = Int32.Parse(xamlReader.Value as String, TypeConverterHelper.InvariantEnglishUS);
                            }
                        }
                    }
                    else if (xamlReader.NodeType == System.Xaml.XamlNodeType.EndMember)
                    {
                        lastPropWasSyncMode    = false;
                        lastPropWasSyncRecords = false;
                    }

                    if (async && rootObject != null)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                // Don't wrap critical exceptions or already-wrapped exceptions.
                if (MS.Internal.CriticalExceptions.IsCriticalException(e) || !ShouldReWrapException(e, parserContext.BaseUri))
                {
                    throw;
                }
                RewrapException(e, parserContext.BaseUri);
            }

            if (!_textReader.IsEof)
            {
                Post();
                //ThreadStart threadStart = new ThreadStart(ReadXamlAsync);
                //Thread thread = new Thread(threadStart);
                //thread.Start();
            }
            else
            {
                TreeBuildComplete();
            }

            if (rootObject is DependencyObject)
            {
                if (parserContext.BaseUri != null && !String.IsNullOrEmpty(parserContext.BaseUri.ToString()))
                {
                    (rootObject as DependencyObject).SetValue(BaseUriHelper.BaseUriProperty, parserContext.BaseUri);
                }
                //else
                //    (rootObject as DependencyObject).SetValue(BaseUriHelper.BaseUriProperty, BaseUriHelper.PackAppBaseUri);
                WpfXamlLoader.EnsureXmlNamespaceMaps(rootObject, schemaContext);
            }

            Application app = rootObject as Application;

            if (app != null)
            {
                app.ApplicationMarkupBaseUri = GetBaseUri(settings.BaseUri);
            }

            return(rootObject);
        }
        private static object Load(System.Xaml.XamlReader xamlReader, IXamlObjectWriterFactory writerFactory,
                                   bool skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
        {
            XamlObjectWriter xamlWriter           = null;
            XamlContextStack <WpfXamlFrame> stack = new XamlContextStack <WpfXamlFrame>(() => new WpfXamlFrame());
            int persistId = 1;

            settings.AfterBeginInitHandler = delegate(object sender, System.Xaml.XamlObjectEventArgs args)
            {
                if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose))
                {
                    IXamlLineInfo ixli = xamlReader as IXamlLineInfo;

                    int lineNumber   = -1;
                    int linePosition = -1;

                    if (ixli != null && ixli.HasLineInfo)
                    {
                        lineNumber   = ixli.LineNumber;
                        linePosition = ixli.LinePosition;
                    }

                    EventTrace.EventProvider.TraceEvent(
                        EventTrace.Event.WClientParseXamlBamlInfo,
                        EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Verbose,
                        args.Instance == null ? 0 : PerfService.GetPerfElementID(args.Instance),
                        lineNumber,
                        linePosition);
                }

                UIElement uiElement = args.Instance as UIElement;
                if (uiElement != null)
                {
                    uiElement.SetPersistId(persistId++);
                }

                XamlSourceInfoHelper.SetXamlSourceInfo(args.Instance, args, baseUri);

                DependencyObject dObject = args.Instance as DependencyObject;
                if (dObject != null && stack.CurrentFrame.XmlnsDictionary != null)
                {
                    XmlnsDictionary dictionary = stack.CurrentFrame.XmlnsDictionary;
                    dictionary.Seal();

                    XmlAttributeProperties.SetXmlnsDictionary(dObject, dictionary);
                }

                stack.CurrentFrame.Instance = args.Instance;
            };
            if (writerFactory != null)
            {
                xamlWriter = writerFactory.GetXamlObjectWriter(settings);
            }
            else
            {
                xamlWriter = new System.Xaml.XamlObjectWriter(xamlReader.SchemaContext, settings);
            }

            IXamlLineInfo xamlLineInfo = null;

            try
            {
                //Handle Line Numbers
                xamlLineInfo = xamlReader as IXamlLineInfo;
                IXamlLineInfoConsumer xamlLineInfoConsumer = xamlWriter as IXamlLineInfoConsumer;
                bool shouldPassLineNumberInfo = false;
                if ((xamlLineInfo != null && xamlLineInfo.HasLineInfo) &&
                    (xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo))
                {
                    shouldPassLineNumberInfo = true;
                }

                IStyleConnector styleConnector = rootObject as IStyleConnector;
                TransformNodes(xamlReader, xamlWriter,
                               false /*onlyLoadOneNode*/,
                               skipJournaledProperties,
                               shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer,
                               stack, styleConnector);
                xamlWriter.Close();
                return(xamlWriter.Result);
            }
            catch (Exception e)
            {
                // Don't wrap critical exceptions or already-wrapped exceptions.
                if (MS.Internal.CriticalExceptions.IsCriticalException(e) || !XamlReader.ShouldReWrapException(e, baseUri))
                {
                    throw;
                }
                XamlReader.RewrapException(e, xamlLineInfo, baseUri);
                return(null);    // this should never be executed
            }
        }
        internal static void TransformNodes(System.Xaml.XamlReader xamlReader, System.Xaml.XamlObjectWriter xamlWriter,
                                            bool onlyLoadOneNode,
                                            bool skipJournaledProperties,
                                            bool shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer,
                                            XamlContextStack <WpfXamlFrame> stack,
                                            IStyleConnector styleConnector)
        {
            while (xamlReader.Read())
            {
                if (shouldPassLineNumberInfo)
                {
                    if (xamlLineInfo.LineNumber != 0)
                    {
                        xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition);
                    }
                }

                switch (xamlReader.NodeType)
                {
                case System.Xaml.XamlNodeType.NamespaceDeclaration:
                    xamlWriter.WriteNode(xamlReader);
                    if (stack.Depth == 0 || stack.CurrentFrame.Type != null)
                    {
                        stack.PushScope();
                        // Need to create an XmlnsDictionary.
                        // Look up stack to see if we have one earlier
                        //  If so, use that.  Otherwise new a xmlnsDictionary
                        WpfXamlFrame iteratorFrame = stack.CurrentFrame;
                        while (iteratorFrame != null)
                        {
                            if (iteratorFrame.XmlnsDictionary != null)
                            {
                                stack.CurrentFrame.XmlnsDictionary =
                                    new XmlnsDictionary(iteratorFrame.XmlnsDictionary);
                                break;
                            }
                            iteratorFrame = (WpfXamlFrame)iteratorFrame.Previous;
                        }
                        if (stack.CurrentFrame.XmlnsDictionary == null)
                        {
                            stack.CurrentFrame.XmlnsDictionary =
                                new XmlnsDictionary();
                        }
                    }
                    stack.CurrentFrame.XmlnsDictionary.Add(xamlReader.Namespace.Prefix, xamlReader.Namespace.Namespace);
                    break;

                case System.Xaml.XamlNodeType.StartObject:
                    WriteStartObject(xamlReader, xamlWriter, stack);
                    break;

                case System.Xaml.XamlNodeType.GetObject:
                    xamlWriter.WriteNode(xamlReader);
                    // If there wasn't a namespace node before this get object, need to pushScope.
                    if (stack.CurrentFrame.Type != null)
                    {
                        stack.PushScope();
                    }
                    stack.CurrentFrame.Type = stack.PreviousFrame.Property.Type;
                    break;

                case System.Xaml.XamlNodeType.EndObject:
                    xamlWriter.WriteNode(xamlReader);
                    // Freeze if required
                    if (stack.CurrentFrame.FreezeFreezable)
                    {
                        Freezable freezable = xamlWriter.Result as Freezable;
                        if (freezable != null && freezable.CanFreeze)
                        {
                            freezable.Freeze();
                        }
                    }
                    DependencyObject dependencyObject = xamlWriter.Result as DependencyObject;
                    if (dependencyObject != null && stack.CurrentFrame.XmlSpace.HasValue)
                    {
                        XmlAttributeProperties.SetXmlSpace(dependencyObject, stack.CurrentFrame.XmlSpace.Value ? "default" : "preserve");
                    }
                    stack.PopScope();
                    break;

                case System.Xaml.XamlNodeType.StartMember:
                    // ObjectWriter should NOT process PresentationOptions:Freeze directive since it is Unknown
                    // The space directive node stream should not be written because it induces object instantiation,
                    // and the Baml2006Reader can produce space directives prematurely.
                    if (!(xamlReader.Member.IsDirective && xamlReader.Member == XamlReaderHelper.Freeze) &&
                        xamlReader.Member != XmlSpace.Value &&
                        xamlReader.Member != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader);
                    }

                    stack.CurrentFrame.Property = xamlReader.Member;
                    if (skipJournaledProperties)
                    {
                        if (!stack.CurrentFrame.Property.IsDirective)
                        {
                            System.Windows.Baml2006.WpfXamlMember wpfMember = stack.CurrentFrame.Property as System.Windows.Baml2006.WpfXamlMember;
                            if (wpfMember != null)
                            {
                                DependencyProperty prop = wpfMember.DependencyProperty;

                                if (prop != null)
                                {
                                    FrameworkPropertyMetadata metadata = prop.GetMetadata(stack.CurrentFrame.Type.UnderlyingType) as FrameworkPropertyMetadata;
                                    if (metadata != null && metadata.Journal == true)
                                    {
                                        // Ignore the BAML for this member, unless it declares a value that wasn't journaled - namely a binding or a dynamic resource
                                        int count = 1;
                                        while (xamlReader.Read())
                                        {
                                            switch (xamlReader.NodeType)
                                            {
                                            case System.Xaml.XamlNodeType.StartMember:
                                                count++;
                                                break;

                                            case System.Xaml.XamlNodeType.StartObject:
                                                XamlType xamlType            = xamlReader.Type;
                                                XamlType bindingBaseType     = xamlType.SchemaContext.GetXamlType(typeof(BindingBase));
                                                XamlType dynamicResourceType = xamlType.SchemaContext.GetXamlType(typeof(DynamicResourceExtension));
                                                if (count == 1 && (xamlType.CanAssignTo(bindingBaseType) || xamlType.CanAssignTo(dynamicResourceType)))
                                                {
                                                    count = 0;
                                                    WriteStartObject(xamlReader, xamlWriter, stack);
                                                }
                                                break;

                                            case System.Xaml.XamlNodeType.EndMember:
                                                count--;
                                                if (count == 0)
                                                {
                                                    xamlWriter.WriteNode(xamlReader);
                                                    stack.CurrentFrame.Property = null;
                                                }
                                                break;

                                            case System.Xaml.XamlNodeType.Value:
                                                DynamicResourceExtension value = xamlReader.Value as DynamicResourceExtension;
                                                if (value != null)
                                                {
                                                    WriteValue(xamlReader, xamlWriter, stack, styleConnector);
                                                }
                                                break;
                                            }
                                            if (count == 0)
                                            {
                                                break;
                                            }
                                        }

                                        System.Diagnostics.Debug.Assert(count == 0, "Mismatch StartMember/EndMember");
                                    }
                                }
                            }
                        }
                    }
                    break;

                case System.Xaml.XamlNodeType.EndMember:
                    WpfXamlFrame currentFrame    = stack.CurrentFrame;
                    XamlMember   currentProperty = currentFrame.Property;
                    // ObjectWriter should not process PresentationOptions:Freeze directive nodes since it is unknown
                    // The space directive node stream should not be written because it induces object instantiation,
                    // and the Baml2006Reader can produce space directives prematurely.
                    if (!(currentProperty.IsDirective && currentProperty == XamlReaderHelper.Freeze) &&
                        currentProperty != XmlSpace.Value &&
                        currentProperty != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader);
                    }
                    currentFrame.Property = null;
                    break;

                case System.Xaml.XamlNodeType.Value:
                    WriteValue(xamlReader, xamlWriter, stack, styleConnector);
                    break;

                default:
                    xamlWriter.WriteNode(xamlReader);
                    break;
                }

                //Only do this loop for one node if loadAsync
                if (onlyLoadOneNode)
                {
                    return;
                }
            }
        }
예제 #19
0
        // This method converts view state information stored within the ViewStateManager node back as
        // attached properties on corresponding activity nodes.
        // It is called when workflow definition is being deserialized from a string.
        // inputReader - Nodestream that may have all view state information in the ViewStateManager node at the end of workflow definition.
        //               The reader is positioned at the begining of the workflow definition.
        // idManager   - This component issues running sequence numbers for IdRef.
        // viewStateManager - (output) ViewStateManager object instance deserialized from the workflow definition.
        // Result      - Node stream positioned at the begining of the workflow definition with view state related information
        //               appearing as attached properties on activities. The ViewStateManager nodes are removed from the stream.
        // Implementation logic:
        // 1. Scan the input nodestream for ViewStateManager node.
        // 2. If ViewStateManager node is found, store Id and corresponding attached property nodes
        //    in viewStateInfo dictionary. Otherwise return early.
        // 3. Walk activity nodes in the workflow definition and apply viewstate related attached properties (from
        //    viewStateInfo dictionary) to each node.
        // 4. If multiple activities have same IdRef values then corresponding viewstate related attached properties
        //    (from viewStateInfo dictionary) are applied to the first of those activities. The other activities with duplicate
        //    IdRef values do not get view state information.
        public static XamlReader ConvertViewStateToAttachedProperties(XamlReader inputReader, ViewStateIdManager idManager, out Dictionary <string, SourceLocation> viewStateSourceLocationMap)
        {
            int  idRefLineNumber           = 0;
            int  idRefLinePosition         = 0;
            bool shouldWriteIdRefEndMember = false;

            XamlReader retVal = null;

            // Xaml member definition for IdRef. Used to identify existing IdRef properties in the input nodestream.
            XamlMember idRefMember = new XamlMember(IdRef, GetIdRef, SetIdRef, inputReader.SchemaContext);

            // Dictionary containing Ids and corresponding viewstate related
            // attached property nodes. Populated by StripViewStateElement method.
            Dictionary <string, XamlNodeList> viewStateInfo = null;
            XamlReader workflowDefinition = StripViewStateElement(inputReader, out viewStateInfo, out viewStateSourceLocationMap);

            // This is used to keep track of duplicate IdRefs in the workflow definition.
            HashSet <string> idRefsSeen = new HashSet <string>();

            // If the inputReader did not have a ViewStateManager node (4.0 format)
            // return early.
            if (viewStateInfo == null)
            {
                retVal = workflowDefinition;
            }
            else
            {
                // Stack to track StartObject/GetObject and EndObject nodes.
                Stack <Frame> stack = new Stack <Frame>();

                // Output node list.
                XamlNodeList mergedNodeList = new XamlNodeList(workflowDefinition.SchemaContext);
                bool         inIdRefMember  = false;

                using (XamlWriter mergedNodeWriter = mergedNodeList.Writer)
                {
                    IXamlLineInfo         lineInfo         = workflowDefinition as IXamlLineInfo;
                    IXamlLineInfoConsumer lineInfoComsumer = mergedNodeWriter as IXamlLineInfoConsumer;
                    bool shouldPassLineInfo = lineInfo != null && lineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

                    while (workflowDefinition.Read())
                    {
                        bool skipWritingWorkflowDefinition = false;

                        switch (workflowDefinition.NodeType)
                        {
                        case XamlNodeType.StartObject:
                            stack.Push(new Frame {
                                Type = workflowDefinition.Type
                            });
                            break;

                        case XamlNodeType.GetObject:
                            stack.Push(new Frame {
                                Type = null
                            });
                            break;

                        case XamlNodeType.StartMember:
                            // Track when the reader enters IdRef. Skip writing the start
                            // node to the output nodelist until we check for duplicates.
                            if (workflowDefinition.Member.Equals(idRefMember))
                            {
                                inIdRefMember = true;
                                skipWritingWorkflowDefinition = true;

                                if (shouldPassLineInfo)
                                {
                                    idRefLineNumber   = lineInfo.LineNumber;
                                    idRefLinePosition = lineInfo.LinePosition;
                                }
                            }
                            break;

                        case XamlNodeType.Value:
                            if (inIdRefMember)
                            {
                                string idRef = workflowDefinition.Value as string;
                                if (!string.IsNullOrWhiteSpace(idRef))
                                {
                                    // If IdRef value is a duplicate then do not associate it with
                                    // the stack frame (top of stack == activity node with IdRef member on it).
                                    if (idRefsSeen.Contains(idRef))
                                    {
                                        stack.Peek().IdRef = null;
                                    }
                                    // If the IdRef value is unique then associate it with the
                                    // stack frame and also write its value into the output nodestream.
                                    else
                                    {
                                        stack.Peek().IdRef = idRef;
                                        idManager.UpdateMap(idRef);
                                        idRefsSeen.Add(idRef);

                                        if (shouldPassLineInfo)
                                        {
                                            lineInfoComsumer.SetLineInfo(idRefLineNumber, idRefLinePosition);
                                        }

                                        mergedNodeWriter.WriteStartMember(idRefMember);

                                        if (shouldPassLineInfo)
                                        {
                                            lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                                        }

                                        mergedNodeWriter.WriteValue(idRef);

                                        shouldWriteIdRefEndMember = true;
                                    }
                                }
                                // Don't need to write IdRef value into the output
                                // nodestream. If the value was valid, it would have been written above.
                                skipWritingWorkflowDefinition = true;
                            }
                            break;

                        case XamlNodeType.EndMember:
                            // Exit IdRef node. Skip writing the EndMember node, we would have done
                            // it as part of reading the IdRef value.
                            if (inIdRefMember)
                            {
                                inIdRefMember = false;
                                skipWritingWorkflowDefinition = true;

                                if (shouldWriteIdRefEndMember)
                                {
                                    shouldWriteIdRefEndMember = false;

                                    if (shouldPassLineInfo)
                                    {
                                        lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                                    }

                                    mergedNodeWriter.WriteEndMember();
                                }
                            }
                            break;

                        case XamlNodeType.EndObject:
                            Frame frameObject = stack.Pop();
                            // Before we exit the end of an object, check if it had IdRef
                            // associated with it. If it did, look-up viewStateInfo for viewstate
                            // related attached property nodes and add them to the output nodelist.
                            if (!string.IsNullOrWhiteSpace(frameObject.IdRef))
                            {
                                XamlNodeList viewStateNodeList;
                                if (viewStateInfo.TryGetValue(frameObject.IdRef, out viewStateNodeList))
                                {
                                    XamlReader viewStateReader = viewStateNodeList.GetReader();

                                    IXamlLineInfo viewStateLineInfo           = viewStateReader as IXamlLineInfo;
                                    bool          viewStateShouldPassLineInfo = viewStateLineInfo != null && viewStateLineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

                                    while (viewStateReader.Read())
                                    {
                                        if (viewStateShouldPassLineInfo)
                                        {
                                            lineInfoComsumer.SetLineInfo(viewStateLineInfo.LineNumber, viewStateLineInfo.LinePosition);
                                        }

                                        mergedNodeWriter.WriteNode(viewStateReader);
                                    }
                                }
                            }
                            break;
                        }
                        if (!skipWritingWorkflowDefinition)
                        {
                            if (shouldPassLineInfo)
                            {
                                lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                            }

                            mergedNodeWriter.WriteNode(workflowDefinition);
                        }
                    }
                }

                retVal = mergedNodeList.GetReader();
            }

            return(retVal);
        }
예제 #20
0
        internal static void TransformNodes(System.Xaml.XamlReader xamlReader, System.Xaml.XamlObjectWriter xamlWriter,
                                         bool onlyLoadOneNode, 
                                         bool skipJournaledProperties,
                                         bool shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, 
                                         XamlContextStack<WpfXamlFrame> stack, 
                                         IStyleConnector styleConnector)
        { 
            while (xamlReader.Read())
            {
                if (shouldPassLineNumberInfo)
                { 
                    if (xamlLineInfo.LineNumber != 0)
                    { 
                        xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition); 
                    }
                } 

                switch (xamlReader.NodeType)
                {
                case System.Xaml.XamlNodeType.NamespaceDeclaration: 
                    xamlWriter.WriteNode(xamlReader);
                    if (stack.Depth == 0 || stack.CurrentFrame.Type != null) 
                    { 
                        stack.PushScope();
                        // Need to create an XmlnsDictionary. 
                        // Look up stack to see if we have one earlier
                        //  If so, use that.  Otherwise new a xmlnsDictionary
                        WpfXamlFrame iteratorFrame = stack.CurrentFrame;
                        while (iteratorFrame != null) 
                        {
                            if (iteratorFrame.XmlnsDictionary != null) 
                            { 
                                stack.CurrentFrame.XmlnsDictionary =
                                    new XmlnsDictionary(iteratorFrame.XmlnsDictionary); 
                                break;
                            }
                            iteratorFrame = (WpfXamlFrame)iteratorFrame.Previous;
                        } 
                        if (stack.CurrentFrame.XmlnsDictionary == null)
                        { 
                            stack.CurrentFrame.XmlnsDictionary = 
                                     new XmlnsDictionary();
                        } 
                    }
                    stack.CurrentFrame.XmlnsDictionary.Add(xamlReader.Namespace.Prefix, xamlReader.Namespace.Namespace);
                    break;
                case System.Xaml.XamlNodeType.StartObject: 
                    xamlWriter.WriteNode(xamlReader);
                    // If there's a frame but no Type, that means there 
                    // was a namespace. Just set the Type 
                    if (stack.Depth != 0 && stack.CurrentFrame.Type == null)
                    { 
                        stack.CurrentFrame.Type = xamlReader.Type;
                    }
                    else
                    { 
                        // Propagate the FreezeFreezable property from the current stack frame
                        stack.PushScope(); 
                        stack.CurrentFrame.Type = xamlReader.Type; 
                        if (stack.PreviousFrame.FreezeFreezable)
                        { 
                            stack.CurrentFrame.FreezeFreezable = true;
                        }
                    }
                    break; 
                case System.Xaml.XamlNodeType.GetObject:
                    xamlWriter.WriteNode(xamlReader); 
                    // If there wasn't a namespace node before this get object, need to pushScope. 
                    if (stack.CurrentFrame.Type != null)
                    { 
                        stack.PushScope();
                    }
                    stack.CurrentFrame.Type = stack.PreviousFrame.Property.Type;
                    break; 
                case System.Xaml.XamlNodeType.EndObject:
                    xamlWriter.WriteNode(xamlReader); 
                    // Freeze if required 
                    if (stack.CurrentFrame.FreezeFreezable)
                    { 
                        Freezable freezable = xamlWriter.Result as Freezable;
                        if (freezable != null && freezable.CanFreeze)
                        {
                            freezable.Freeze(); 
                        }
                    } 
                    DependencyObject dependencyObject = xamlWriter.Result as DependencyObject; 
                    if (dependencyObject != null && stack.CurrentFrame.XmlSpace.HasValue)
                    { 
                        XmlAttributeProperties.SetXmlSpace(dependencyObject, stack.CurrentFrame.XmlSpace.Value ? "default" : "preserve");
                    }
                    stack.PopScope();
                    break; 
                case System.Xaml.XamlNodeType.StartMember:
                    // ObjectWriter should NOT process PresentationOptions:Freeze directive since it is Unknown 
                    // The space directive node stream should not be written because it induces object instantiation, 
                    // and the Baml2006Reader can produce space directives prematurely.
                    if (!(xamlReader.Member.IsDirective && xamlReader.Member == XamlReaderHelper.Freeze) && 
                        xamlReader.Member != XmlSpace.Value &&
                        xamlReader.Member != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader); 
                    }
 
                    stack.CurrentFrame.Property = xamlReader.Member; 
                    if (skipJournaledProperties)
                    { 
                        if (!stack.CurrentFrame.Property.IsDirective)
                        {
                            System.Windows.Baml2006.WpfXamlMember wpfMember = stack.CurrentFrame.Property as System.Windows.Baml2006.WpfXamlMember;
                            if (wpfMember != null) 
                            {
                                DependencyProperty prop = wpfMember.DependencyProperty; 
 
                                if (prop != null)
                                { 
                                    FrameworkPropertyMetadata metadata = prop.GetMetadata(stack.CurrentFrame.Type.UnderlyingType) as FrameworkPropertyMetadata;
                                    if (metadata != null && metadata.Journal == true)
                                    {
                                        // 
                                        int count = 1;
                                        while (xamlReader.Read()) 
                                        { 
                                            switch (xamlReader.NodeType)
                                            { 
                                            case System.Xaml.XamlNodeType.StartMember:
                                                count++;
                                                break;
                                            case System.Xaml.XamlNodeType.EndMember: 
                                                count--;
                                                if (count == 0) 
                                                { 
                                                    xamlWriter.WriteNode(xamlReader);
                                                } 
                                                break;
                                            }
                                            if (count == 0)
                                                break; 
                                        }
                                        // shouldn't this have been a XamlReader.Skip()? 
                                        System.Diagnostics.Debug.Assert(count == 0, "Mismatch StartMember/EndMember"); 
                                    }
                                } 
                            }
                        }
                    }
                    break; 
                case System.Xaml.XamlNodeType.EndMember:
                    WpfXamlFrame currentFrame = stack.CurrentFrame; 
                    XamlMember currentProperty = currentFrame.Property; 
                    // ObjectWriter should not process PresentationOptions:Freeze directive nodes since it is unknown
                    // The space directive node stream should not be written because it induces object instantiation, 
                    // and the Baml2006Reader can produce space directives prematurely.
                    if (!(currentProperty.IsDirective && currentProperty == XamlReaderHelper.Freeze) &&
                        currentProperty != XmlSpace.Value &&
                        currentProperty != XamlLanguage.Space) 
                    {
                        xamlWriter.WriteNode(xamlReader); 
                    } 
                    currentFrame.Property = null;
                    break; 
                case System.Xaml.XamlNodeType.Value:
                    if (stack.CurrentFrame.Property.IsDirective && stack.CurrentFrame.Property == XamlLanguage.Shared)
                    {
                        bool isShared; 
                        if (bool.TryParse(xamlReader.Value as string, out isShared))
                        { 
                            if (!isShared) 
                            {
                                if (!(xamlReader is Baml2006Reader)) 
                                {
                                    throw new XamlParseException(SR.Get(SRID.SharedAttributeInLooseXaml));
                                }
                            } 
                        }
                    } 
                    // ObjectWriter should not process PresentationOptions:Freeze directive nodes since it is unknown 
                    if (stack.CurrentFrame.Property.IsDirective && stack.CurrentFrame.Property == XamlReaderHelper.Freeze)
                    { 
                        bool freeze = Convert.ToBoolean(xamlReader.Value, TypeConverterHelper.InvariantEnglishUS);
                        stack.CurrentFrame.FreezeFreezable = freeze;
                        var bamlReader = xamlReader as System.Windows.Baml2006.Baml2006Reader;
                        if (bamlReader != null) 
                        {
                            bamlReader.FreezeFreezables = freeze; 
                        } 
                    }
                    // The space directive node stream should not be written because it induces object instantiation, 
                    // and the Baml2006Reader can produce space directives prematurely.
                    else if (stack.CurrentFrame.Property == XmlSpace.Value || stack.CurrentFrame.Property == XamlLanguage.Space)
                    {
                        if (typeof(DependencyObject).IsAssignableFrom(stack.CurrentFrame.Type.UnderlyingType)) 
                        {
                            System.Diagnostics.Debug.Assert(xamlReader.Value is string, "XmlAttributeProperties.XmlSpaceProperty has the type string."); 
                            stack.CurrentFrame.XmlSpace = (string)xamlReader.Value == "default"; 
                        }
                    } 
                    else
                    {
                        // Ideally we should check if we're inside FrameworkTemplate's Content and not register those.
                        // However, checking if the instance is null accomplishes the same with a much smaller perf impact. 
                        if (styleConnector != null &&
                            stack.CurrentFrame.Instance != null && 
                            stack.CurrentFrame.Property == XamlLanguage.ConnectionId && 
                            typeof(Style).IsAssignableFrom(stack.CurrentFrame.Type.UnderlyingType))
                        { 
                            styleConnector.Connect((int)xamlReader.Value, stack.CurrentFrame.Instance);
                        }

                        xamlWriter.WriteNode(xamlReader); 
                    }
                    break; 
                default: 
                    xamlWriter.WriteNode(xamlReader);
                    break; 
                }

                //Only do this loop for one node if loadAsync
                if (onlyLoadOneNode) 
                {
                    return; 
                } 
            }
        } 
예제 #21
0
 public DiagnosticWriter(StringBuilder stringbuilder, XamlWriter wrappedWriter, XamlSchemaContext xamlSchemaContext)
     : this(stringbuilder, xamlSchemaContext)
 {
     _wrappedWriter = wrappedWriter;
     _wrappedWriterLineInfoConsumer = _wrappedWriter as IXamlLineInfoConsumer;
 }
예제 #22
0
파일: WpfXamlLoader.cs 프로젝트: ash2005/z
        internal static void TransformNodes(System.Xaml.XamlReader xamlReader, System.Xaml.XamlObjectWriter xamlWriter,
                                            bool onlyLoadOneNode,
                                            bool skipJournaledProperties,
                                            bool shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer,
                                            XamlContextStack <WpfXamlFrame> stack,
                                            IStyleConnector styleConnector)
        {
            while (xamlReader.Read())
            {
                if (shouldPassLineNumberInfo)
                {
                    if (xamlLineInfo.LineNumber != 0)
                    {
                        xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition);
                    }
                }

                switch (xamlReader.NodeType)
                {
                case System.Xaml.XamlNodeType.NamespaceDeclaration:
                    xamlWriter.WriteNode(xamlReader);
                    if (stack.Depth == 0 || stack.CurrentFrame.Type != null)
                    {
                        stack.PushScope();
                        // Need to create an XmlnsDictionary.
                        // Look up stack to see if we have one earlier
                        //  If so, use that.  Otherwise new a xmlnsDictionary
                        WpfXamlFrame iteratorFrame = stack.CurrentFrame;
                        while (iteratorFrame != null)
                        {
                            if (iteratorFrame.XmlnsDictionary != null)
                            {
                                stack.CurrentFrame.XmlnsDictionary =
                                    new XmlnsDictionary(iteratorFrame.XmlnsDictionary);
                                break;
                            }
                            iteratorFrame = (WpfXamlFrame)iteratorFrame.Previous;
                        }
                        if (stack.CurrentFrame.XmlnsDictionary == null)
                        {
                            stack.CurrentFrame.XmlnsDictionary =
                                new XmlnsDictionary();
                        }
                    }
                    stack.CurrentFrame.XmlnsDictionary.Add(xamlReader.Namespace.Prefix, xamlReader.Namespace.Namespace);
                    break;

                case System.Xaml.XamlNodeType.StartObject:
                    xamlWriter.WriteNode(xamlReader);
                    // If there's a frame but no Type, that means there
                    // was a namespace. Just set the Type
                    if (stack.Depth != 0 && stack.CurrentFrame.Type == null)
                    {
                        stack.CurrentFrame.Type = xamlReader.Type;
                    }
                    else
                    {
                        // Propagate the FreezeFreezable property from the current stack frame
                        stack.PushScope();
                        stack.CurrentFrame.Type = xamlReader.Type;
                        if (stack.PreviousFrame.FreezeFreezable)
                        {
                            stack.CurrentFrame.FreezeFreezable = true;
                        }
                    }
                    break;

                case System.Xaml.XamlNodeType.GetObject:
                    xamlWriter.WriteNode(xamlReader);
                    // If there wasn't a namespace node before this get object, need to pushScope.
                    if (stack.CurrentFrame.Type != null)
                    {
                        stack.PushScope();
                    }
                    stack.CurrentFrame.Type = stack.PreviousFrame.Property.Type;
                    break;

                case System.Xaml.XamlNodeType.EndObject:
                    xamlWriter.WriteNode(xamlReader);
                    // Freeze if required
                    if (stack.CurrentFrame.FreezeFreezable)
                    {
                        Freezable freezable = xamlWriter.Result as Freezable;
                        if (freezable != null && freezable.CanFreeze)
                        {
                            freezable.Freeze();
                        }
                    }
                    DependencyObject dependencyObject = xamlWriter.Result as DependencyObject;
                    if (dependencyObject != null && stack.CurrentFrame.XmlSpace.HasValue)
                    {
                        XmlAttributeProperties.SetXmlSpace(dependencyObject, stack.CurrentFrame.XmlSpace.Value ? "default" : "preserve");
                    }
                    stack.PopScope();
                    break;

                case System.Xaml.XamlNodeType.StartMember:
                    // ObjectWriter should NOT process PresentationOptions:Freeze directive since it is Unknown
                    // The space directive node stream should not be written because it induces object instantiation,
                    // and the Baml2006Reader can produce space directives prematurely.
                    if (!(xamlReader.Member.IsDirective && xamlReader.Member == XamlReaderHelper.Freeze) &&
                        xamlReader.Member != XmlSpace.Value &&
                        xamlReader.Member != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader);
                    }

                    stack.CurrentFrame.Property = xamlReader.Member;
                    if (skipJournaledProperties)
                    {
                        if (!stack.CurrentFrame.Property.IsDirective)
                        {
                            System.Windows.Baml2006.WpfXamlMember wpfMember = stack.CurrentFrame.Property as System.Windows.Baml2006.WpfXamlMember;
                            if (wpfMember != null)
                            {
                                DependencyProperty prop = wpfMember.DependencyProperty;

                                if (prop != null)
                                {
                                    FrameworkPropertyMetadata metadata = prop.GetMetadata(stack.CurrentFrame.Type.UnderlyingType) as FrameworkPropertyMetadata;
                                    if (metadata != null && metadata.Journal == true)
                                    {
                                        //
                                        int count = 1;
                                        while (xamlReader.Read())
                                        {
                                            switch (xamlReader.NodeType)
                                            {
                                            case System.Xaml.XamlNodeType.StartMember:
                                                count++;
                                                break;

                                            case System.Xaml.XamlNodeType.EndMember:
                                                count--;
                                                if (count == 0)
                                                {
                                                    xamlWriter.WriteNode(xamlReader);
                                                }
                                                break;
                                            }
                                            if (count == 0)
                                            {
                                                break;
                                            }
                                        }
                                        // shouldn't this have been a XamlReader.Skip()?
                                        System.Diagnostics.Debug.Assert(count == 0, "Mismatch StartMember/EndMember");
                                    }
                                }
                            }
                        }
                    }
                    break;

                case System.Xaml.XamlNodeType.EndMember:
                    WpfXamlFrame currentFrame    = stack.CurrentFrame;
                    XamlMember   currentProperty = currentFrame.Property;
                    // ObjectWriter should not process PresentationOptions:Freeze directive nodes since it is unknown
                    // The space directive node stream should not be written because it induces object instantiation,
                    // and the Baml2006Reader can produce space directives prematurely.
                    if (!(currentProperty.IsDirective && currentProperty == XamlReaderHelper.Freeze) &&
                        currentProperty != XmlSpace.Value &&
                        currentProperty != XamlLanguage.Space)
                    {
                        xamlWriter.WriteNode(xamlReader);
                    }
                    currentFrame.Property = null;
                    break;

                case System.Xaml.XamlNodeType.Value:
                    if (stack.CurrentFrame.Property.IsDirective && stack.CurrentFrame.Property == XamlLanguage.Shared)
                    {
                        bool isShared;
                        if (bool.TryParse(xamlReader.Value as string, out isShared))
                        {
                            if (!isShared)
                            {
                                if (!(xamlReader is Baml2006Reader))
                                {
                                    throw new XamlParseException(SR.Get(SRID.SharedAttributeInLooseXaml));
                                }
                            }
                        }
                    }
                    // ObjectWriter should not process PresentationOptions:Freeze directive nodes since it is unknown
                    if (stack.CurrentFrame.Property.IsDirective && stack.CurrentFrame.Property == XamlReaderHelper.Freeze)
                    {
                        bool freeze = Convert.ToBoolean(xamlReader.Value, TypeConverterHelper.InvariantEnglishUS);
                        stack.CurrentFrame.FreezeFreezable = freeze;
                        var bamlReader = xamlReader as System.Windows.Baml2006.Baml2006Reader;
                        if (bamlReader != null)
                        {
                            bamlReader.FreezeFreezables = freeze;
                        }
                    }
                    // The space directive node stream should not be written because it induces object instantiation,
                    // and the Baml2006Reader can produce space directives prematurely.
                    else if (stack.CurrentFrame.Property == XmlSpace.Value || stack.CurrentFrame.Property == XamlLanguage.Space)
                    {
                        if (typeof(DependencyObject).IsAssignableFrom(stack.CurrentFrame.Type.UnderlyingType))
                        {
                            System.Diagnostics.Debug.Assert(xamlReader.Value is string, "XmlAttributeProperties.XmlSpaceProperty has the type string.");
                            stack.CurrentFrame.XmlSpace = (string)xamlReader.Value == "default";
                        }
                    }
                    else
                    {
                        // Ideally we should check if we're inside FrameworkTemplate's Content and not register those.
                        // However, checking if the instance is null accomplishes the same with a much smaller perf impact.
                        if (styleConnector != null &&
                            stack.CurrentFrame.Instance != null &&
                            stack.CurrentFrame.Property == XamlLanguage.ConnectionId &&
                            typeof(Style).IsAssignableFrom(stack.CurrentFrame.Type.UnderlyingType))
                        {
                            styleConnector.Connect((int)xamlReader.Value, stack.CurrentFrame.Instance);
                        }

                        xamlWriter.WriteNode(xamlReader);
                    }
                    break;

                default:
                    xamlWriter.WriteNode(xamlReader);
                    break;
                }

                //Only do this loop for one node if loadAsync
                if (onlyLoadOneNode)
                {
                    return;
                }
            }
        }
예제 #23
0
        // Token: 0x0600226A RID: 8810 RVA: 0x000AAE10 File Offset: 0x000A9010
        private static object Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
        {
            XamlContextStack <WpfXamlFrame> stack = new XamlContextStack <WpfXamlFrame>(() => new WpfXamlFrame());
            int persistId = 1;

            settings.AfterBeginInitHandler = delegate(object sender, XamlObjectEventArgs args)
            {
                if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordPerf | EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose))
                {
                    IXamlLineInfo xamlLineInfo2 = xamlReader as IXamlLineInfo;
                    int           num           = -1;
                    int           num2          = -1;
                    if (xamlLineInfo2 != null && xamlLineInfo2.HasLineInfo)
                    {
                        num  = xamlLineInfo2.LineNumber;
                        num2 = xamlLineInfo2.LinePosition;
                    }
                    EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientParseXamlBamlInfo, EventTrace.Keyword.KeywordPerf | EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, new object[]
                    {
                        (args.Instance == null) ? 0L : PerfService.GetPerfElementID(args.Instance),
                        num,
                        num2
                    });
                }
                UIElement uielement = args.Instance as UIElement;
                if (uielement != null)
                {
                    UIElement uielement2 = uielement;
                    int       persistId  = persistId;
                    persistId++;
                    uielement2.SetPersistId(persistId);
                }
                XamlSourceInfoHelper.SetXamlSourceInfo(args.Instance, args, baseUri);
                DependencyObject dependencyObject = args.Instance as DependencyObject;
                if (dependencyObject != null && stack.CurrentFrame.XmlnsDictionary != null)
                {
                    XmlnsDictionary xmlnsDictionary = stack.CurrentFrame.XmlnsDictionary;
                    xmlnsDictionary.Seal();
                    XmlAttributeProperties.SetXmlnsDictionary(dependencyObject, xmlnsDictionary);
                }
                stack.CurrentFrame.Instance = args.Instance;
            };
            XamlObjectWriter xamlObjectWriter;

            if (writerFactory != null)
            {
                xamlObjectWriter = writerFactory.GetXamlObjectWriter(settings);
            }
            else
            {
                xamlObjectWriter = new XamlObjectWriter(xamlReader.SchemaContext, settings);
            }
            IXamlLineInfo xamlLineInfo = null;
            object        result;

            try
            {
                xamlLineInfo = (xamlReader as IXamlLineInfo);
                IXamlLineInfoConsumer xamlLineInfoConsumer = xamlObjectWriter;
                bool shouldPassLineNumberInfo = false;
                if (xamlLineInfo != null && xamlLineInfo.HasLineInfo && xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo)
                {
                    shouldPassLineNumberInfo = true;
                }
                IStyleConnector styleConnector = rootObject as IStyleConnector;
                WpfXamlLoader.TransformNodes(xamlReader, xamlObjectWriter, false, skipJournaledProperties, shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer, stack, styleConnector);
                xamlObjectWriter.Close();
                result = xamlObjectWriter.Result;
            }
            catch (Exception ex)
            {
                if (CriticalExceptions.IsCriticalException(ex) || !XamlReader.ShouldReWrapException(ex, baseUri))
                {
                    throw;
                }
                XamlReader.RewrapException(ex, xamlLineInfo, baseUri);
                result = null;
            }
            return(result);
        }
예제 #24
0
        // This method reads a ViewStateData node from the xaml nodestream. It outputs the Id property into viewStateId
        // and the attached viewstate related properties in viewStateNodes. The input reader is positioned on a
        // ViewStateData node within ViewStateManager.
        static void ReadViewState(XamlType viewStateType, XamlReader xamlReader, out string viewStateId, out XamlNodeList viewStateNodes, out SourceLocation sourceLocation)
        {
            int  globalMemberLevel = 0;
            bool skippingUnexpectedAttachedProperty      = false;
            int  skippingUnexpectedAttachedPropertyLevel = 0;

            viewStateId    = null;
            viewStateNodes = new XamlNodeList(viewStateType.SchemaContext);
            sourceLocation = null;

            Stack <Frame> objectNodes = new Stack <Frame>();
            XamlMember    idMember    = new XamlMember(typeof(ViewStateData).GetProperty("Id"), xamlReader.SchemaContext);

            int[] viewStateDataSourceLocation = new int[4];
            int   sourceLocationIndex         = -1;

            IXamlLineInfo         lineInfo         = xamlReader as IXamlLineInfo;
            IXamlLineInfoConsumer lineInfoComsumer = viewStateNodes.Writer as IXamlLineInfoConsumer;
            bool shouldPassLineInfo = lineInfo != null && lineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

            while (xamlReader.Read())
            {
                bool skipWritingToNodeList = false;
                switch (xamlReader.NodeType)
                {
                case XamlNodeType.StartObject:
                    if (xamlReader.Type.Equals(viewStateType))
                    {
                        skipWritingToNodeList = true;
                    }
                    objectNodes.Push(new Frame {
                        Type = xamlReader.Type
                    });
                    break;

                case XamlNodeType.GetObject:
                    objectNodes.Push(new Frame {
                        Type = null
                    });
                    break;

                case XamlNodeType.StartMember:
                    globalMemberLevel++;
                    if (xamlReader.Member.Equals(idMember))
                    {
                        XamlReader idNode = xamlReader.ReadSubtree();
                        while (idNode.Read())
                        {
                            if (idNode.NodeType == XamlNodeType.Value)
                            {
                                viewStateId = idNode.Value as string;
                            }
                        }
                    }
                    // The xamlReader.ReadSubtree and subsequent while loop to get the Id member
                    // has moved the xamlReader forward to the next member. We need to check to see
                    // if it is an Attached Property that we care about. If it isn't then we need to
                    // skip it and not put it in the resulting XamlNodeList.
                    if (globalMemberLevel == 1 && !IsAttachablePropertyForConvert(xamlReader))
                    {
                        skippingUnexpectedAttachedProperty = true;
                    }
                    if (skippingUnexpectedAttachedProperty)
                    {
                        skippingUnexpectedAttachedPropertyLevel++;
                    }

                    sourceLocationIndex = GetViewStateDataSourceLocationIndexFromCurrentReader(xamlReader);
                    break;

                case XamlNodeType.EndMember:
                    globalMemberLevel--;
                    if (skippingUnexpectedAttachedProperty)
                    {
                        skippingUnexpectedAttachedPropertyLevel--;
                    }
                    break;

                case XamlNodeType.Value:
                    if (xamlReader.Value is int &&
                        sourceLocationIndex >= 0 &&
                        sourceLocationIndex < viewStateDataSourceLocation.Length)
                    {
                        viewStateDataSourceLocation[sourceLocationIndex] = (int)xamlReader.Value;
                    }

                    break;

                case XamlNodeType.EndObject:
                    Frame objectNode = objectNodes.Pop();
                    if (objectNode.Type != null && objectNode.Type.Equals(viewStateType))
                    {
                        skipWritingToNodeList = true;
                        // The ViewStateData's source location should be valid, because
                        // before each EndObject, its SourceLocation is injected.
                        // If not, an exception will be thrown from constructor
                        // of SourceLocation.
                        sourceLocation = new SourceLocation(null,
                                                            viewStateDataSourceLocation[0],
                                                            viewStateDataSourceLocation[1],
                                                            viewStateDataSourceLocation[2],
                                                            viewStateDataSourceLocation[3]
                                                            );
                    }

                    Array.Clear(viewStateDataSourceLocation, 0, viewStateDataSourceLocation.Length);
                    break;
                }
                ;

                if (!skipWritingToNodeList && !skippingUnexpectedAttachedProperty)
                {
                    if (shouldPassLineInfo)
                    {
                        lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                    }

                    viewStateNodes.Writer.WriteNode(xamlReader);
                }

                if (skippingUnexpectedAttachedPropertyLevel == 0)
                {
                    skippingUnexpectedAttachedProperty = false;
                }
            }
            viewStateNodes.Writer.Close();
        }
예제 #25
0
        // This method converts view state information stored within the ViewStateManager node back as
        // attached properties on corresponding activity nodes.
        // It is called when workflow definition is being deserialized from a string.
        // inputReader - Nodestream that may have all view state information in the ViewStateManager node at the end of workflow definition.
        //               The reader is positioned at the begining of the workflow definition.
        // idManager   - This component issues running sequence numbers for IdRef.
        // viewStateManager - (output) ViewStateManager object instance deserialized from the workflow definition.
        // Result      - Node stream positioned at the begining of the workflow definition with view state related information
        //               appearing as attached properties on activities. The ViewStateManager nodes are removed from the stream.
        // Implementation logic:
        // 1. Scan the input nodestream for ViewStateManager node.
        // 2. If ViewStateManager node is found, store Id and corresponding attached property nodes
        //    in viewStateInfo dictionary. Otherwise return early.
        // 3. Walk activity nodes in the workflow definition and apply viewstate related attached properties (from
        //    viewStateInfo dictionary) to each node.
        // 4. If multiple activities have same IdRef values then corresponding viewstate related attached properties
        //    (from viewStateInfo dictionary) are applied to the first of those activities. The other activities with duplicate
        //    IdRef values do not get view state information.
        public static XamlReader ConvertViewStateToAttachedProperties(XamlReader inputReader, ViewStateIdManager idManager, out Dictionary <string, SourceLocation> viewStateSourceLocationMap)
        {
            int  idRefLineNumber           = 0;
            int  idRefLinePosition         = 0;
            bool shouldWriteIdRefEndMember = false;

            XamlReader retVal = null;

            // Xaml member definition for IdRef. Used to identify existing IdRef properties in the input nodestream.
            XamlMember idRefMember = new XamlMember(IdRef, GetIdRef, SetIdRef, inputReader.SchemaContext);

            // These are used to ignore the IdRef members that are inside a DynamicUpdateInfo.OriginalDefinition/OriginalActivityBuilder attached property.
            // We need to ignore these because if we don't, the IdRef values for the objects in the actual workflow defintion will be ignored because of the
            // duplicate IdRef value. This causes problems with activity designers that depend on the ViewStateManager data to correctly display the workflow
            // on the WorkflowDesigner canvas.
            XamlMember originalDefinitionMember      = new XamlMember(DynamicUpdateOriginalDefinitionMemberName, GetOriginalDefinition, SetOriginalDefinition, inputReader.SchemaContext);
            XamlMember originalActivityBuilderMember = new XamlMember(DynamicUpdateOriginalActivityBuilderMemberName, GetOriginalActivityBuilder, SetOriginalActivityBuilder, inputReader.SchemaContext);

            // insideOriginalDefintion gets set to true when we find a "StartMember" node for either of the above two attached properties.
            // originalDefintionMemberCount gets incremented if we find any "StartMember" and insideOriginalDefinition is true.
            // originalDefintionMemberCount gets decremented if we find any "EndMember" and insideOriginalDefintion is true.
            // insideOriginalDefintion gets set to false when we find an "EndMember" and originalDefinitionMemberCount gets decremented to 0.
            // If insideOriginalDefintion is true when we find an "IdRef" member, we do NOT add that IdRef to the idRefsSeen HashSet to avoid
            // duplicates being defined by the IdRefs inside of the OriginalDefinition attached properties.
            bool insideOriginalDefinition      = false;
            int  originalDefinitionMemberCount = 0;

            // Dictionary containing Ids and corresponding viewstate related
            // attached property nodes. Populated by StripViewStateElement method.
            Dictionary <string, XamlNodeList> viewStateInfo = null;
            XamlReader workflowDefinition = StripViewStateElement(inputReader, out viewStateInfo, out viewStateSourceLocationMap);

            // This is used to keep track of duplicate IdRefs in the workflow definition.
            HashSet <string> idRefsSeen = new HashSet <string>();

            // If the inputReader did not have a ViewStateManager node (4.0 format)
            // return early.
            if (viewStateInfo == null)
            {
                retVal = workflowDefinition;
            }
            else
            {
                // Stack to track StartObject/GetObject and EndObject nodes.
                Stack <Frame> stack = new Stack <Frame>();

                // Output node list.
                XamlNodeList mergedNodeList = new XamlNodeList(workflowDefinition.SchemaContext);
                bool         inIdRefMember  = false;

                using (XamlWriter mergedNodeWriter = mergedNodeList.Writer)
                {
                    IXamlLineInfo         lineInfo         = workflowDefinition as IXamlLineInfo;
                    IXamlLineInfoConsumer lineInfoComsumer = mergedNodeWriter as IXamlLineInfoConsumer;
                    bool shouldPassLineInfo = lineInfo != null && lineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

                    while (workflowDefinition.Read())
                    {
                        bool skipWritingWorkflowDefinition = false;

                        switch (workflowDefinition.NodeType)
                        {
                        case XamlNodeType.StartObject:
                            stack.Push(new Frame {
                                Type = workflowDefinition.Type
                            });
                            break;

                        case XamlNodeType.GetObject:
                            stack.Push(new Frame {
                                Type = null
                            });
                            break;

                        case XamlNodeType.StartMember:
                            // If we find a StartMember for DynamicUpdateInfo.OriginalDefinition or OriginalActivityBuilder, remember that we are
                            // inside one of those. We don't want to "remember" IdRef values in the idRefsSeen HashSet while inside these attached properties.
                            if (workflowDefinition.Member.Equals(originalDefinitionMember) || workflowDefinition.Member.Equals(originalActivityBuilderMember))
                            {
                                insideOriginalDefinition = true;
                            }

                            if (insideOriginalDefinition)
                            {
                                originalDefinitionMemberCount++;
                            }

                            // Track when the reader enters IdRef. Skip writing the start
                            // node to the output nodelist until we check for duplicates.
                            else if (workflowDefinition.Member.Equals(idRefMember))
                            {
                                inIdRefMember = true;
                                skipWritingWorkflowDefinition = true;

                                if (shouldPassLineInfo)
                                {
                                    idRefLineNumber   = lineInfo.LineNumber;
                                    idRefLinePosition = lineInfo.LinePosition;
                                }
                            }
                            break;

                        case XamlNodeType.Value:
                            if (inIdRefMember)
                            {
                                // We don't want to deal with the IdRef if we are inside a DynamicUpdateInfo.OriginalDefinition/OriginalActivityBuilder
                                // attached property.
                                if (!insideOriginalDefinition)
                                {
                                    string idRef = workflowDefinition.Value as string;
                                    if (!string.IsNullOrWhiteSpace(idRef))
                                    {
                                        // If IdRef value is a duplicate then do not associate it with
                                        // the stack frame (top of stack == activity node with IdRef member on it).
                                        if (idRefsSeen.Contains(idRef))
                                        {
                                            stack.Peek().IdRef = null;
                                        }
                                        // If the IdRef value is unique then associate it with the
                                        // stack frame and also write its value into the output nodestream.
                                        else
                                        {
                                            stack.Peek().IdRef = idRef;
                                            idManager.UpdateMap(idRef);
                                            idRefsSeen.Add(idRef);

                                            if (shouldPassLineInfo)
                                            {
                                                lineInfoComsumer.SetLineInfo(idRefLineNumber, idRefLinePosition);
                                            }

                                            mergedNodeWriter.WriteStartMember(idRefMember);

                                            if (shouldPassLineInfo)
                                            {
                                                lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                                            }

                                            mergedNodeWriter.WriteValue(idRef);

                                            shouldWriteIdRefEndMember = true;
                                        }
                                    }
                                }
                                // Don't need to write IdRef value into the output
                                // nodestream. If the value was valid, it would have been written above.
                                skipWritingWorkflowDefinition = true;
                            }
                            break;

                        case XamlNodeType.EndMember:
                            // If we are inside an OriginalDefinition/OriginalActivityBuilder attached property,
                            // decrement the count and if it goes to zero, set insideOriginalDefintion to false
                            // because we just encountered the EndMember for it.
                            if (insideOriginalDefinition)
                            {
                                originalDefinitionMemberCount--;
                                if (originalDefinitionMemberCount == 0)
                                {
                                    insideOriginalDefinition = false;
                                }
                            }

                            // Exit IdRef node. Skip writing the EndMember node, we would have done
                            // it as part of reading the IdRef value.
                            if (inIdRefMember && !insideOriginalDefinition)
                            {
                                inIdRefMember = false;
                                skipWritingWorkflowDefinition = true;

                                if (shouldWriteIdRefEndMember)
                                {
                                    shouldWriteIdRefEndMember = false;

                                    if (shouldPassLineInfo)
                                    {
                                        lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                                    }

                                    mergedNodeWriter.WriteEndMember();
                                }
                            }

                            break;

                        case XamlNodeType.EndObject:
                            Frame frameObject = stack.Pop();
                            // Before we exit the end of an object, check if it had IdRef
                            // associated with it. If it did, look-up viewStateInfo for viewstate
                            // related attached property nodes and add them to the output nodelist.
                            if (!string.IsNullOrWhiteSpace(frameObject.IdRef))
                            {
                                XamlNodeList viewStateNodeList;
                                if (viewStateInfo.TryGetValue(frameObject.IdRef, out viewStateNodeList))
                                {
                                    XamlReader viewStateReader = viewStateNodeList.GetReader();

                                    IXamlLineInfo viewStateLineInfo           = viewStateReader as IXamlLineInfo;
                                    bool          viewStateShouldPassLineInfo = viewStateLineInfo != null && viewStateLineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

                                    while (viewStateReader.Read())
                                    {
                                        if (viewStateShouldPassLineInfo)
                                        {
                                            lineInfoComsumer.SetLineInfo(viewStateLineInfo.LineNumber, viewStateLineInfo.LinePosition);
                                        }

                                        mergedNodeWriter.WriteNode(viewStateReader);
                                    }
                                }
                            }
                            break;
                        }
                        if (!skipWritingWorkflowDefinition)
                        {
                            if (shouldPassLineInfo)
                            {
                                lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                            }

                            mergedNodeWriter.WriteNode(workflowDefinition);
                        }
                    }
                }

                retVal = mergedNodeList.GetReader();
            }

            return(retVal);
        }