Ejemplo n.º 1
0
        /// <summary>
        /// Reads a property value and adds it as a text or a sub-property of 
        /// the specified <paramref name="property"/>.
        /// </summary>
        /// <param name="property">Property to read content into.</param>
        private void ReadPropertyValueIntoResult(AtomContentProperty property)
        {
            Debug.Assert(this.reader != null, "reader != null");
            Debug.Assert(property != null, "property != null");

            switch (this.reader.NodeType)
            {
                case XmlNodeType.CDATA:
                case XmlNodeType.SignificantWhitespace:
                case XmlNodeType.Text:
                    if (property.PrimitiveToken != null)
                    {
                        throw Error.InvalidOperation(Strings.Deserialize_MixedTextWithComment);
                    }

                    // this is a string token
                    property.PrimitiveToken = new TextPrimitiveParserToken(this.reader.Value);
                    break;
                case XmlNodeType.Comment:
                case XmlNodeType.Whitespace:
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.EndElement:
                    // Do nothing.
                    // ProcessingInstruction, Whitespace would have thrown before
                    break;
                case XmlNodeType.Element:
                    // We found an element while reading a property value. This should be
                    // a complex type.
                    if (property.PrimitiveToken != null)
                    {
                        throw Error.InvalidOperation(Strings.Deserialize_ExpectingSimpleValue);
                    }

                    // Complex types:
                    property.EnsureProperties();
                    AtomContentProperty prop = this.ReadPropertyValue();

                    if (prop != null)
                    {
                        property.Properties.Add(prop);
                    }

                    break;

                default:
                    throw Error.InvalidOperation(Strings.Deserialize_ExpectingSimpleValue);
            }
        }
Ejemplo n.º 2
0
        /// <summary>This method will read a string or a complex type.</summary>
        /// <returns>The property value read.</returns>
        /// <remarks>Always checks for null attribute.</remarks>
        private AtomContentProperty ReadPropertyValue()
        {
            Debug.Assert(this.reader != null, "reader != null");
            Debug.Assert(
                this.reader.NodeType == XmlNodeType.Element,
                "reader.NodeType == XmlNodeType.Element -- otherwise caller is confused as to where the reader is");

            if (!this.IsDataWebElement)
            {
                // we expect <d:PropertyName>...</d:PropertyName> only
                CommonUtil.SkipToEndAtDepth(this.reader, this.reader.Depth);
                return null;
            }

            AtomContentProperty result = new AtomContentProperty();
            result.Name = this.reader.LocalName;
            result.TypeName = this.reader.GetAttributeEx(XmlConstants.AtomTypeAttributeName, XmlConstants.DataWebMetadataNamespace);
            result.IsNull = Util.DoesNullAttributeSayTrue(this.reader);

            // simple optimization for empty and obviously null properties
            if (result.IsNull && this.reader.IsEmptyElement)
            {
                return result;
            }

            PrimitiveType type;
            if (result.TypeName != null && PrimitiveType.TryGetPrimitiveType(result.TypeName, out type))
            {
                // primitive type - tokenize it
                // DEVNOTE(pqian):
                // 1. If the typeName is null, it can be either a complex type or edm.string
                // We must drill into the element to find out
                // 2. We should throw if the Edm type is unrecognized, but this was not in V1/V2 
                // So we need to ignore unknown types
                result.PrimitiveToken = this.TokenizeFromXml(type);
            }
            else
            {
                // complex or collection type - recursive parse and store into result
                if (!this.reader.IsEmptyElement)
                {
                    int depth = this.reader.Depth;
                    while (this.reader.Read())
                    {
                        this.ReadPropertyValueIntoResult(result);
                        if (this.reader.Depth == depth)
                        {
                            break;
                        }
                    }
                }
            }

            if (result.PrimitiveToken == null && !result.IsNull)
            {
                // Empty String or actual null property can both cause PrimitiveToken to be null
                // NOTE: Ideally we should leave this null when parsing complex types or collection
                // But the V1/V2 behavior is to set them as Empty
                result.PrimitiveToken = TextPrimitiveParserToken.Empty;
            }

            return result;
        }
Ejemplo n.º 3
0
        private void HandleExpandedNavigationProperties(AtomEntry targetEntry, string propertyName, bool isFeed)
        {
            Debug.Assert(!this.reader.IsEmptyElement, "the current element has some child content");

            if (!ReadChildElement(this.reader, XmlConstants.AtomInlineElementName, XmlConstants.DataWebMetadataNamespace))
            {
                return;
            }

            bool emptyInlineCollection = this.reader.IsEmptyElement;
            object propertyValue = null;

            if (!emptyInlineCollection)
            {
                AtomFeed nestedFeed = null;
                AtomEntry nestedEntry = null;
                List<AtomEntry> feedEntries = null;

                Debug.Assert(this.reader is Xml.XmlWrappingReader, "reader must be a instance of XmlWrappingReader");
                Uri readerBaseUri = string.IsNullOrEmpty(this.reader.BaseURI) ? null : new Uri(this.reader.BaseURI, UriKind.Absolute);
                XmlReader nestedReader = Xml.XmlWrappingReader.CreateReader(readerBaseUri, this.reader.ReadSubtree());
                nestedReader.Read();
                Debug.Assert(nestedReader.LocalName == "inline", "nestedReader.LocalName == 'inline'");

                AtomParser nested = new AtomParser(nestedReader, this.entryCallback, this.typeScheme, this.currentDataNamespace, this.baseUriResolver, this.MaxProtocolVersion);
                while (nested.Read())
                {
                    switch (nested.DataKind)
                    {
                        case AtomDataKind.Feed:
                            feedEntries = new List<AtomEntry>();
                            nestedFeed = nested.CurrentFeed;
                            propertyValue = nestedFeed;
                            break;
                        case AtomDataKind.Entry:
                            nestedEntry = nested.CurrentEntry;
                            if (feedEntries != null)
                            {
                                feedEntries.Add(nestedEntry);
                            }
                            else
                            {
                                propertyValue = nestedEntry;
                            }

                            break;
                        case AtomDataKind.PagingLinks:
                            // Here the inner feed parser found a paging link, and stored it on nestedFeed.NextPageLink
                            // we are going to add it into a link table and associate
                            // with the collection at AtomMaterializer::Materialize()
                            // Do nothing for now.
                            break;
                        default:
                            throw new InvalidOperationException(Strings.AtomParser_UnexpectedContentUnderExpandedLink);
                    }
                }

                if (nestedFeed != null)
                {
                    Debug.Assert(
                        nestedFeed.Entries == null,
                        "nestedFeed.Entries == null -- otherwise someone initialized this for us");
                    nestedFeed.Entries = feedEntries;
                }
            }

            AtomContentProperty property = new AtomContentProperty();
            property.Name = propertyName;

            if (emptyInlineCollection || propertyValue == null)
            {
                property.IsNull = true;
                if (isFeed)
                {
                    property.Feed = new AtomFeed();
                    property.Feed.Entries = Enumerable.Empty<AtomEntry>();
                }
                else
                {
                    property.Entry = new AtomEntry(this.MaxProtocolVersion);
                    property.Entry.IsNull = true;
                }
            }
            else
            {
                property.Feed = propertyValue as AtomFeed;
                property.Entry = propertyValue as AtomEntry;
            }

            targetEntry.DataValues.Add(property);
        }