public void AddToSourceListShouldAddToTheSourceList()
 {
     ReadOnlyEnumerable<int> enumerable = new ReadOnlyEnumerable<int>();
     enumerable.Should().BeEmpty();
     enumerable.AddToSourceList(1);
     enumerable.Count().Should().Be(1);
     enumerable.Should().OnlyContain(i => i == 1);
 }
Example #2
0
        public void AddToSourceListShouldAddToTheSourceList()
        {
            ReadOnlyEnumerable <int> enumerable = new ReadOnlyEnumerable <int>();

            enumerable.Should().BeEmpty();
            enumerable.AddToSourceList(1);
            enumerable.Count().Should().Be(1);
            enumerable.Should().OnlyContain(i => i == 1);
        }
Example #3
0
        public void AddToSourceListShouldAddToTheSourceList()
        {
            ReadOnlyEnumerable <int> enumerable = new ReadOnlyEnumerable <int>();

            Assert.Empty(enumerable);
            enumerable.AddToSourceList(1);
            int value = Assert.Single(enumerable);

            Assert.Equal(1, value);
        }
Example #4
0
        /// <summary>
        /// Creates and adds a new property to the list of properties for an EPM.
        /// </summary>
        /// <param name="properties">The list of properties to add the property to.</param>
        /// <param name="propertyName">The name of the property to add.</param>
        /// <param name="propertyValue">The value of the property to add.</param>
        /// <param name="checkDuplicateEntryPropertyNames">true if the new property should be checked for duplicates against the entry properties; false otherwise.
        /// This should be true if the <paramref name="properties"/> is the list of properties for the entry, and false in all other cases.</param>
        private void AddEpmPropertyValue(ReadOnlyEnumerable <ODataProperty> properties, string propertyName, object propertyValue, bool checkDuplicateEntryPropertyNames)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "propertyName must not be null or empty.");

            // Create a new property object and add it.
            ODataProperty property = new ODataProperty
            {
                Name  = propertyName,
                Value = propertyValue
            };

            if (checkDuplicateEntryPropertyNames)
            {
                this.entryState.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
            }

            properties.AddToSourceList(property);
        }
        /// <summary>
        /// Reads the content of a properties in an element (complex value, m:properties, ...)
        /// </summary>
        /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param>
        /// <param name="properties">The list of properties to add properties to.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element    - The element to read properties from.
        /// Post-Condition: XmlNodeType.Element    - The element to read properties from if it is an empty element.
        ///                 XmlNodeType.EndElement - The end element of the element to read properties from.
        /// </remarks>
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, ReadOnlyEnumerable<ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            this.AssertXmlCondition(XmlNodeType.Element);

            // Empty values are valid - they have no properties
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the complex value element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                // WCF DS will skip over the rest of the complex value or entity properties if the first element in it is preceded with
                // a text node. Once the first element is found (no matter its namespace) then the non-element nodes
                // are ignored but skipped and the reading continues.
                // For ODataLib we should not do this and probably just ignore the text node even at the beginning (to be consistent).
                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                            {
                                // Found a property
                                IEdmProperty edmProperty = null;
                                bool isOpen = false;
                                bool ignoreProperty = false;

                                if (structuredType != null)
                                {
                                    // Lookup the property in metadata
                                    edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty);
                                    if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation)
                                    {
                                        throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType));
                                    }

                                    // If the property was not declared, it must be open.
                                    isOpen = edmProperty == null;
                                }

                                if (ignoreProperty)
                                {
                                    this.XmlReader.Skip();
                                }
                                else
                                {
                                    // EdmLib bridge marks all key properties as non-nullable, but Astoria allows them to be nullable.
                                    // If the property has an annotation to ignore null values, we need to omit the property in requests.
                                    ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null 
                                        ? ODataNullValueBehaviorKind.Default 
                                        : this.Model.NullValueReadBehaviorKind(edmProperty);
                                    ODataProperty property = this.ReadProperty(
                                        false,
                                        edmProperty == null ? null : edmProperty.Name,
                                        edmProperty == null ? null : edmProperty.Type, 
                                        nullValueReadBehaviorKind);
                                    Debug.Assert(
                                        property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue,
                                        "If we don't ignore null values the property must not be null.");

                                    if (property != null)
                                    {
                                        if (isOpen)
                                        {
                                            ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value);
                                        }

                                        duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                        properties.AddToSourceList(property);
                                    }
                                }
                            }
                            else
                            {
                                this.XmlReader.Skip();
                            }

                            break;

                        case XmlNodeType.EndElement:
                            // End of the complex value.
                            break;

                        default:
                            // Non-element so for example a text node, just ignore
                            this.XmlReader.Skip();
                            break;
                    }
                }
                while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }
        /// <summary>
        /// Reads the content of a properties in an element (complex value, m:properties, ...)
        /// </summary>
        /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param>
        /// <param name="properties">The list of properties to add properties to.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element    - The element to read properties from.
        /// Post-Condition: XmlNodeType.Element    - The element to read properties from if it is an empty element.
        ///                 XmlNodeType.EndElement - The end element of the element to read properties from.
        /// </remarks>
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, ReadOnlyEnumerable <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            this.AssertXmlCondition(XmlNodeType.Element);

            // Empty values are valid - they have no properties
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the complex value element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                // WCF DS will skip over the rest of the complex value or entity properties if the first element in it is preceded with
                // a text node. Once the first element is found (no matter its namespace) then the non-element nodes
                // are ignored but skipped and the reading continues.
                // For ODataLib we should not do this and probably just ignore the text node even at the beginning (to be consistent).
                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                        {
                            // Found a property
                            IEdmProperty edmProperty    = null;
                            bool         isOpen         = false;
                            bool         ignoreProperty = false;

                            if (structuredType != null)
                            {
                                // Lookup the property in metadata
                                edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty);
                                if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation)
                                {
                                    throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType));
                                }

                                // If the property was not declared, it must be open.
                                isOpen = edmProperty == null;
                            }

                            if (ignoreProperty)
                            {
                                this.XmlReader.Skip();
                            }
                            else
                            {
                                // EdmLib bridge marks all key properties as non-nullable, but Astoria allows them to be nullable.
                                // If the property has an annotation to ignore null values, we need to omit the property in requests.
                                ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null
                                        ? ODataNullValueBehaviorKind.Default
                                        : this.Model.NullValueReadBehaviorKind(edmProperty);
                                ODataProperty property = this.ReadProperty(
                                    false,
                                    edmProperty == null ? null : edmProperty.Name,
                                    edmProperty == null ? null : edmProperty.Type,
                                    nullValueReadBehaviorKind);
                                Debug.Assert(
                                    property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue,
                                    "If we don't ignore null values the property must not be null.");

                                if (property != null)
                                {
                                    if (isOpen)
                                    {
                                        ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value);
                                    }

                                    duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                    properties.AddToSourceList(property);
                                }
                            }
                        }
                        else
                        {
                            this.XmlReader.Skip();
                        }

                        break;

                    case XmlNodeType.EndElement:
                        // End of the complex value.
                        break;

                    default:
                        // Non-element so for example a text node, just ignore
                        this.XmlReader.Skip();
                        break;
                    }
                }while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }
        /// <summary>
        /// Reads the content of a properties in an element (complex value, m:properties, ...)
        /// </summary>
        /// <param name="structuredType">The type which should declare the properties to be read. Optional.</param>
        /// <param name="properties">The list of properties to add properties to.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        /// <param name="epmPresent">Whether any EPM mappings exist.</param>
        /// <remarks>
        /// Pre-Condition:  XmlNodeType.Element    - The element to read properties from.
        /// Post-Condition: XmlNodeType.Element    - The element to read properties from if it is an empty element.
        ///                 XmlNodeType.EndElement - The end element of the element to read properties from.
        /// </remarks>
        private void ReadPropertiesImplementation(IEdmStructuredType structuredType, ReadOnlyEnumerable <ODataProperty> properties, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker, bool epmPresent)
        {
            Debug.Assert(properties != null, "properties != null");
            Debug.Assert(duplicatePropertyNamesChecker != null, "duplicatePropertyNamesChecker != null");
            this.AssertXmlCondition(XmlNodeType.Element);

            // Empty values are valid - they have no properties
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the complex value element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                        {
                            // Found a property
                            IEdmProperty edmProperty    = null;
                            bool         isOpen         = false;
                            bool         ignoreProperty = false;

                            if (structuredType != null)
                            {
                                // Lookup the property in metadata
                                edmProperty = ReaderValidationUtils.ValidateValuePropertyDefined(this.XmlReader.LocalName, structuredType, this.MessageReaderSettings, out ignoreProperty);
                                if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Navigation)
                                {
                                    throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_NavigationPropertyInProperties(edmProperty.Name, structuredType));
                                }

                                // If the property was not declared, it must be open.
                                isOpen = edmProperty == null;
                            }

                            if (ignoreProperty)
                            {
                                this.XmlReader.Skip();
                            }
                            else
                            {
                                ODataNullValueBehaviorKind nullValueReadBehaviorKind = this.ReadingResponse || edmProperty == null
                                        ? ODataNullValueBehaviorKind.Default
                                        : this.Model.NullValueReadBehaviorKind(edmProperty);
                                ODataProperty property = this.ReadProperty(
                                    edmProperty == null ? null : edmProperty.Name,
                                    edmProperty == null ? null : edmProperty.Type,
                                    nullValueReadBehaviorKind,
                                    epmPresent);
                                Debug.Assert(
                                    property != null || nullValueReadBehaviorKind == ODataNullValueBehaviorKind.IgnoreValue,
                                    "If we don't ignore null values the property must not be null.");

                                if (property != null)
                                {
                                    if (isOpen)
                                    {
                                        ValidationUtils.ValidateOpenPropertyValue(property.Name, property.Value, this.MessageReaderSettings.UndeclaredPropertyBehaviorKinds);
                                    }

                                    duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
                                    properties.AddToSourceList(property);
                                }
                            }
                        }
                        else
                        {
                            this.XmlReader.Skip();
                        }

                        break;

                    case XmlNodeType.EndElement:
                        // End of the complex value.
                        break;

                    default:
                        // Non-element so for example a text node, just ignore
                        this.XmlReader.Skip();
                        break;
                    }
                }while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }
        }