/// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        protected ODataAtomDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            Debug.Assert(atomInputContext != null, "atomInputContext != null");

            this.atomInputContext = atomInputContext;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomMetadataDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
     XmlNameTable nameTable = this.XmlReader.NameTable;
     this.EmptyNamespace = nameTable.Add(string.Empty);
     this.AtomNamespace = nameTable.Add(AtomConstants.AtomNamespace);
 }
Exemple #3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        protected ODataAtomDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            Debug.Assert(atomInputContext != null, "atomInputContext != null");

            this.atomInputContext = atomInputContext;
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        /// <param name="inSourceElement">Whether this deserializer is reading feed metadata for a source element (true) or a feed element (false).</param>
        internal ODataAtomFeedMetadataDeserializer(ODataAtomInputContext atomInputContext, bool inSourceElement)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;
            this.EmptyNamespace = nameTable.Add(string.Empty);

            this.InSourceElement = inSourceElement;
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The input to read the payload from.</param>
        /// <param name="expectedItemTypeReference">The expected type reference for the items in the collection.</param>
        internal ODataAtomCollectionReader(ODataAtomInputContext atomInputContext, IEdmTypeReference expectedItemTypeReference)
            : base(atomInputContext, expectedItemTypeReference, null /*listener*/)
        {
            Debug.Assert(atomInputContext != null, "atomInputContext != null");

            this.atomInputContext           = atomInputContext;
            this.atomCollectionDeserializer = new ODataAtomCollectionDeserializer(atomInputContext);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The input to read the payload from.</param>
        /// <param name="expectedItemTypeReference">The expected type reference for the items in the collection.</param>
        internal ODataAtomCollectionReader(ODataAtomInputContext atomInputContext, IEdmTypeReference expectedItemTypeReference)
            : base(atomInputContext, expectedItemTypeReference, null /*listener*/)
        {
            Debug.Assert(atomInputContext != null, "atomInputContext != null");

            this.atomInputContext = atomInputContext;
            this.atomCollectionDeserializer = new ODataAtomCollectionDeserializer(atomInputContext);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        internal ODataAtomEntryMetadataDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;

            this.EmptyNamespace = nameTable.Add(string.Empty);
            this.AtomNamespace  = nameTable.Add(AtomConstants.AtomNamespace);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomPropertyAndValueDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
     XmlNameTable nameTable = this.XmlReader.NameTable;
     this.EmptyNamespace = nameTable.Add(string.Empty);
     this.ODataNullAttributeName = nameTable.Add(AtomConstants.ODataNullAttributeName);
     this.ODataCollectionItemElementName = nameTable.Add(AtomConstants.ODataCollectionItemElementName);
     this.AtomTypeAttributeName = nameTable.Add(AtomConstants.AtomTypeAttributeName);
 }
Exemple #9
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        /// <param name="inSourceElement">Whether this deserializer is reading feed metadata for a source element (true) or a feed element (false).</param>
        internal ODataAtomFeedMetadataDeserializer(ODataAtomInputContext atomInputContext, bool inSourceElement)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;

            this.EmptyNamespace = nameTable.Add(string.Empty);

            this.InSourceElement = inSourceElement;
        }
 private static ODataProperty ReadStringPropertyUnderServerKnob(string payload)
 {
     MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(payload));
     ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
     settings.EnableODataServerBehavior();
     ODataAtomInputContext context = new ODataAtomInputContext(ODataFormat.Atom, memoryStream, Encoding.UTF8, settings, false /*readingResponse*/, true /*sync*/, EdmModel, null);
     var deserializer = new ODataAtomPropertyAndValueDeserializer(context);
     return deserializer.ReadTopLevelProperty(StringProperty, StringProperty.Type);
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomEntityReferenceLinkDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
     XmlNameTable nameTable = this.XmlReader.NameTable;
     this.ODataFeedElementName = nameTable.Add(AtomConstants.AtomFeedElementName);
     this.ODataCountElementName = nameTable.Add(AtomConstants.ODataCountElementName);
     this.ODataNextElementName = nameTable.Add(AtomConstants.ODataNextLinkElementName);
     this.ODataRefElementName = nameTable.Add(AtomConstants.ODataRefElementName);
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        internal ODataAtomEntityReferenceLinkDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;

            this.ODataFeedElementName  = nameTable.Add(AtomConstants.AtomFeedElementName);
            this.ODataCountElementName = nameTable.Add(AtomConstants.ODataCountElementName);
            this.ODataNextElementName  = nameTable.Add(AtomConstants.ODataNextLinkElementName);
            this.ODataRefElementName   = nameTable.Add(AtomConstants.ODataRefElementName);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        internal ODataAtomPropertyAndValueDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;

            this.EmptyNamespace                 = nameTable.Add(string.Empty);
            this.ODataNullAttributeName         = nameTable.Add(AtomConstants.ODataNullAttributeName);
            this.ODataCollectionItemElementName = nameTable.Add(AtomConstants.ODataCollectionItemElementName);
            this.AtomTypeAttributeName          = nameTable.Add(AtomConstants.AtomTypeAttributeName);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomServiceDocumentMetadataDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
     XmlNameTable nameTable = this.XmlReader.NameTable;
     this.AtomNamespace = nameTable.Add(AtomConstants.AtomNamespace);
     this.AtomCategoryElementName = nameTable.Add(AtomConstants.AtomCategoryElementName);
     this.AtomHRefAttributeName = nameTable.Add(AtomConstants.AtomHRefAttributeName);
     this.AtomPublishingFixedAttributeName = nameTable.Add(AtomConstants.AtomPublishingFixedAttributeName);
     this.AtomCategorySchemeAttributeName = nameTable.Add(AtomConstants.AtomCategorySchemeAttributeName);
     this.AtomCategoryTermAttributeName = nameTable.Add(AtomConstants.AtomCategoryTermAttributeName);
     this.AtomCategoryLabelAttributeName = nameTable.Add(AtomConstants.AtomCategoryLabelAttributeName);
     this.EmptyNamespace = nameTable.Add(string.Empty);
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        internal ODataAtomServiceDocumentMetadataDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;

            this.AtomNamespace                    = nameTable.Add(AtomConstants.AtomNamespace);
            this.AtomCategoryElementName          = nameTable.Add(AtomConstants.AtomCategoryElementName);
            this.AtomHRefAttributeName            = nameTable.Add(AtomConstants.AtomHRefAttributeName);
            this.AtomPublishingFixedAttributeName = nameTable.Add(AtomConstants.AtomPublishingFixedAttributeName);
            this.AtomCategorySchemeAttributeName  = nameTable.Add(AtomConstants.AtomCategorySchemeAttributeName);
            this.AtomCategoryTermAttributeName    = nameTable.Add(AtomConstants.AtomCategoryTermAttributeName);
            this.AtomCategoryLabelAttributeName   = nameTable.Add(AtomConstants.AtomCategoryLabelAttributeName);
            this.EmptyNamespace                   = nameTable.Add(string.Empty);
        }
Exemple #16
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The input to read the payload from.</param>
        /// <param name="navigationSource">The navigation source we are going to read entities for.</param>
        /// <param name="expectedEntityType">The expected entity type for the entry to be read (in case of entry reader) or entries in the feed to be read (in case of feed reader).</param>
        /// <param name="readingFeed">true if the reader is created for reading a feed; false when it is created for reading an entry.</param>
        internal ODataAtomReader(
            ODataAtomInputContext atomInputContext, 
            IEdmNavigationSource navigationSource, 
            IEdmEntityType expectedEntityType, 
            bool readingFeed)
            : base(atomInputContext, readingFeed, false /*readingDelta*/, null /*listener*/)
        {
            Debug.Assert(atomInputContext != null, "atomInputContext != null");
            Debug.Assert(
                expectedEntityType == null || atomInputContext.Model.IsUserModel(),
                "If the expected type is specified we need model as well. We should have verified that by now.");

            this.atomInputContext = atomInputContext;
            this.atomEntryAndFeedDeserializer = new ODataAtomEntryAndFeedDeserializer(atomInputContext);

            this.EnterScope(new Scope(ODataReaderState.Start, /*item*/ null, navigationSource, expectedEntityType, /*contextUri*/null));
        }
Exemple #17
0
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
 private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     bool synchronous,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
                this,
                messageStream,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                readingResponse,
                synchronous,
                detectionInfo.Model,
                /*urlResolver*/ null))
     {
         return(inputContext.DetectPayloadKind(detectionInfo));
     }
 }
        /// <summary>
        /// Creates a new ATOM annotation parser.
        /// </summary>
        /// <param name="inputContext">The input context this annotation reader should use to read annotation elements.</param>
        /// <param name="propertyAndValueDeserializer">The property and value deserializer to use to read the value of an annotation element.</param>
        internal ODataAtomAnnotationReader(ODataAtomInputContext inputContext, ODataAtomPropertyAndValueDeserializer propertyAndValueDeserializer)
        {
            this.inputContext = inputContext;
            this.propertyAndValueDeserializer = propertyAndValueDeserializer;
            BufferingXmlReader xmlReader = this.inputContext.XmlReader;

            Debug.Assert(xmlReader != null, "xmlReader != null");
            Debug.Assert(xmlReader.NameTable != null, "xmlReader.NameTable != null");
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationTargetAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationTermAttribute);
            xmlReader.NameTable.Add(AtomConstants.AtomTypeAttributeName);
            xmlReader.NameTable.Add(AtomConstants.ODataNullAttributeName);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationStringAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationBoolAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationDecimalAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationIntAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationFloatAttribute);
            this.odataMetadataNamespace = xmlReader.NameTable.Add(AtomConstants.ODataMetadataNamespace);
            this.attributeElementName = xmlReader.NameTable.Add(AtomConstants.ODataAnnotationElementName);
        }
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
 private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     bool synchronous,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
                this,
                messageStream,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                ODataVersion.V4, // NOTE: we don't rely on the version for payload kind detection; taking the latest.
                readingResponse,
                synchronous,
                detectionInfo.Model,
                /*urlResolver*/ null))
     {
         return(inputContext.DetectPayloadKind(detectionInfo));
     }
 }
Exemple #20
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        internal ODataAtomServiceDocumentDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;

            this.AtomPublishingServiceElementName    = nameTable.Add(AtomConstants.AtomPublishingServiceElementName);
            this.AtomPublishingWorkspaceElementName  = nameTable.Add(AtomConstants.AtomPublishingWorkspaceElementName);
            this.AtomPublishingCollectionElementName = nameTable.Add(AtomConstants.AtomPublishingCollectionElementName);
            this.AtomPublishingAcceptElementName     = nameTable.Add(AtomConstants.AtomPublishingAcceptElementName);
            this.AtomPublishingCategoriesElementName = nameTable.Add(AtomConstants.AtomPublishingCategoriesElementName);
            this.AtomHRefAttributeName          = nameTable.Add(AtomConstants.AtomHRefAttributeName);
            this.AtomPublishingNamespace        = nameTable.Add(AtomConstants.AtomPublishingNamespace);
            this.AtomNamespace                  = nameTable.Add(AtomConstants.AtomNamespace);
            this.AtomTitleElementName           = nameTable.Add(AtomConstants.AtomTitleElementName);
            this.EmptyNamespace                 = nameTable.Add(string.Empty);
            this.ODataMetadataNamespace         = nameTable.Add(AtomConstants.ODataMetadataNamespace);
            this.ODataFunctionImportElementName = nameTable.Add(AtomConstants.AtomServiceDocumentFunctionImportElementName);
            this.ODataSingletonElementName      = nameTable.Add(AtomConstants.AtomServiceDocumentSingletonElementName);
            this.ODataNameAttribute             = nameTable.Add(AtomConstants.ODataNameAttribute);
        }
Exemple #21
0
        /// <summary>
        /// Creates a new ATOM annotation parser.
        /// </summary>
        /// <param name="inputContext">The input context this annotation reader should use to read annotation elements.</param>
        /// <param name="propertyAndValueDeserializer">The property and value deserializer to use to read the value of an annotation element.</param>
        internal ODataAtomAnnotationReader(ODataAtomInputContext inputContext, ODataAtomPropertyAndValueDeserializer propertyAndValueDeserializer)
        {
            this.inputContext = inputContext;
            this.propertyAndValueDeserializer = propertyAndValueDeserializer;
            BufferingXmlReader xmlReader = this.inputContext.XmlReader;

            Debug.Assert(xmlReader != null, "xmlReader != null");
            Debug.Assert(xmlReader.NameTable != null, "xmlReader.NameTable != null");
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationTargetAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationTermAttribute);
            xmlReader.NameTable.Add(AtomConstants.AtomTypeAttributeName);
            xmlReader.NameTable.Add(AtomConstants.ODataNullAttributeName);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationStringAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationBoolAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationDecimalAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationIntAttribute);
            xmlReader.NameTable.Add(AtomConstants.ODataAnnotationFloatAttribute);
            this.odataMetadataNamespace = xmlReader.NameTable.Add(AtomConstants.ODataMetadataNamespace);
            this.attributeElementName   = xmlReader.NameTable.Add(AtomConstants.ODataAnnotationElementName);
        }
        private void VerifyTypeCollectionRoundtrip(ODataCollectionValue value, string propertyName, ODataFeedAndEntrySerializationInfo info)
        {
            var properties = new[] { new ODataProperty { Name = propertyName, Value = value } };
            var entry = new ODataEntry() { TypeName = "NS.Student", Properties = properties, SerializationInfo = info};
            MemoryStream stream = new MemoryStream();
            using (ODataAtomOutputContext outputContext = new ODataAtomOutputContext(
                ODataFormat.Atom,
                new NonDisposingStream(stream),
                Encoding.UTF8,
                new ODataMessageWriterSettings() { Version = ODataVersion.V4 },
                /*writingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                outputContext.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);
                var atomWriter = new ODataAtomWriter(outputContext, /*entitySet*/ null, /*entityType*/ null, /*writingFeed*/ false);
                atomWriter.WriteStart(entry);
                atomWriter.WriteEnd();

            }

            stream.Position = 0;
            object actualValue = null;

            using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
                ODataFormat.Atom,
                stream,
                Encoding.UTF8,
                new ODataMessageReaderSettings(),
                /*readingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                var atomReader = new ODataAtomReader(inputContext, /*entitySet*/ null, /*entityType*/ null, /*writingFeed*/ false);
                while (atomReader.Read())
                {
                    if (atomReader.State == ODataReaderState.EntryEnd)
                    {
                        ODataEntry entryOut = atomReader.Item as ODataEntry;
                        actualValue = entryOut.Properties.Single(p => p.Name == propertyName).ODataValue;
                    }
                }
            }

            TestUtils.AssertODataValueAreEqual(actualValue as ODataValue, value);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomErrorDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomErrorDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="atomInputContext">The ATOM input context to read from.</param>
        internal ODataAtomEntryAndFeedDeserializer(ODataAtomInputContext atomInputContext)
            : base(atomInputContext)
        {
            XmlNameTable nameTable = this.XmlReader.NameTable;
            this.AtomNamespace = nameTable.Add(AtomConstants.AtomNamespace);
            this.AtomEntryElementName = nameTable.Add(AtomConstants.AtomEntryElementName);
            this.AtomCategoryElementName = nameTable.Add(AtomConstants.AtomCategoryElementName);
            this.AtomCategoryTermAttributeName = nameTable.Add(AtomConstants.AtomCategoryTermAttributeName);
            this.AtomCategorySchemeAttributeName = nameTable.Add(AtomConstants.AtomCategorySchemeAttributeName);
            this.AtomContentElementName = nameTable.Add(AtomConstants.AtomContentElementName);
            this.AtomLinkElementName = nameTable.Add(AtomConstants.AtomLinkElementName);
            this.AtomPropertiesElementName = nameTable.Add(AtomConstants.AtomPropertiesElementName);
            this.AtomFeedElementName = nameTable.Add(AtomConstants.AtomFeedElementName);
            this.AtomIdElementName = nameTable.Add(AtomConstants.AtomIdElementName);
            this.AtomLinkRelationAttributeName = nameTable.Add(AtomConstants.AtomLinkRelationAttributeName);
            this.AtomLinkHrefAttributeName = nameTable.Add(AtomConstants.AtomLinkHrefAttributeName);
            this.MediaLinkEntryContentSourceAttributeName = nameTable.Add(AtomConstants.MediaLinkEntryContentSourceAttributeName);
            this.ODataETagAttributeName = nameTable.Add(AtomConstants.ODataETagAttributeName);
            this.ODataCountElementName = nameTable.Add(AtomConstants.ODataCountElementName);
            this.ODataInlineElementName = nameTable.Add(AtomConstants.ODataInlineElementName);
            this.ODataActionElementName = nameTable.Add(AtomConstants.ODataActionElementName);
            this.ODataFunctionElementName = nameTable.Add(AtomConstants.ODataFunctionElementName);
            this.ODataOperationMetadataAttribute = nameTable.Add(AtomConstants.ODataOperationMetadataAttribute);
            this.ODataOperationTitleAttribute = nameTable.Add(AtomConstants.ODataOperationTitleAttribute);
            this.ODataOperationTargetAttribute = nameTable.Add(AtomConstants.ODataOperationTargetAttribute);

            this.atomAnnotationReader = new ODataAtomAnnotationReader(this.AtomInputContext, this);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomPayloadKindDetectionDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
 }
        private void VerifyPrimitiveValueRoundtrips(object clrValue, string edmTypeName, ODataVersion version, string description)
        {
            IEdmModel model = new EdmModel();
            IEdmPrimitiveTypeReference typeReference = new EdmPrimitiveTypeReference((IEdmPrimitiveType)model.FindType(edmTypeName), true);

            MemoryStream stream = new MemoryStream();
            using (ODataAtomOutputContext outputContext = new ODataAtomOutputContext(
                ODataFormat.Atom,
                new NonDisposingStream(stream),
                Encoding.UTF8,
                new ODataMessageWriterSettings() { Version = version },
                /*writingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                ODataAtomPropertyAndValueSerializer serializer = new ODataAtomPropertyAndValueSerializer(outputContext);
                serializer.XmlWriter.WriteStartElement("ValueElement");
                serializer.WritePrimitiveValue(
                    clrValue,
                    /*collectionValidator*/ null,
                    typeReference,
                    /*serializationTypeNameAnnotation*/ null);
                serializer.XmlWriter.WriteEndElement();
            }

            stream.Position = 0;

            object actualValue;
            using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
                ODataFormat.Atom,
                stream,
                Encoding.UTF8,
                new ODataMessageReaderSettings(),
                /*readingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                ODataAtomPropertyAndValueDeserializer deserializer = new ODataAtomPropertyAndValueDeserializer(inputContext);
                deserializer.XmlReader.MoveToContent();
                actualValue = deserializer.ReadNonEntityValue(
                    typeReference,
                    /*duplicatePropertyNamesChecker*/ null,
                    /*collectionValidator*/ null,
                    /*validateNullValue*/ true);
            }

            if (clrValue is byte[])
            {
                ((byte[])actualValue).Should().Equal((byte[])clrValue, description);
            }
            else
            {
                actualValue.Should().Be(clrValue, description);
            }
        }
        /// <summary>
        /// Creates a new instance of this class by consuming xml from the given input context.
        /// </summary>
        /// <param name="inputContext">The input context to use to create the annotation.</param>
        /// <param name="propertyAndValueDeserializer">The property and value deserializer to use when reading values in the annotation element content.</param>
        /// <returns>The <see cref="AtomInstanceAnnotation"/> populated with the information from the 'm:annotation' XML element, as long as the value is a string. Returns null otherwise.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element    - The annotation element to read.
        /// Post-Condition:  XmlNodeType.Any        - The node after the end of the annotation element, or the same element as in the pre-condition if the annotation was skipped.
        /// </remarks>
        internal static AtomInstanceAnnotation CreateFrom(ODataAtomInputContext inputContext, ODataAtomPropertyAndValueDeserializer propertyAndValueDeserializer)
        {
            var xmlReader = inputContext.XmlReader;
            Debug.Assert(xmlReader != null, "xmlReader != null");
            Debug.Assert(xmlReader.NodeType == XmlNodeType.Element, "xmlReader must be positioned on an Element");
            Debug.Assert(xmlReader.NameTable != null, "xmlReader.NameTable != null");
            Debug.Assert(xmlReader.LocalName == "annotation", "Must be positioned on an annotation element");

            string termAttributeValue = null;
            string targetAttributeValue = null;
            string typeAttributeValue = null;
            bool nullAttributePresentAndTrue = false;
            bool sawMultipleAttributeValueNotations = false;

            // Notes on "attribute value notation":
            // Empty elements may have the annotation value specified via an attribute on the annotation element.
            // Exactly one of the following attributes must be present if this notation is being used: "string", "int", "bool", "float", "decimal".
            // The value of the annotation is the value of this value-specifying attribute.
            string attributeValueNotationAttributeName = null;
            string attributeValueNotationAttributeValue = null;
            IEdmPrimitiveTypeReference attributeValueNotationTypeReference = null;
            
            XmlNameTable xmlNameTable = xmlReader.NameTable;
            string metadataNamespace = xmlNameTable.Get(AtomConstants.ODataMetadataNamespace);
            string nullAttributeName = xmlNameTable.Get(AtomConstants.ODataNullAttributeName);
            string typeAttributeName = xmlNameTable.Get(AtomConstants.AtomTypeAttributeName);
            string emptyNamespace = xmlNameTable.Get(string.Empty);
            string termAttributeName = xmlNameTable.Get(AtomConstants.ODataAnnotationTermAttribute);
            string targetAttributeName = xmlNameTable.Get(AtomConstants.ODataAnnotationTargetAttribute);

            // Loop through all the attributes and remember the ones specific to annotations.
            while (xmlReader.MoveToNextAttribute())
            {
                if (xmlReader.NamespaceEquals(metadataNamespace))
                {
                    if (xmlReader.LocalNameEquals(typeAttributeName))
                    {
                        typeAttributeValue = xmlReader.Value;
                    }
                    else if (xmlReader.LocalNameEquals(nullAttributeName))
                    {
                        nullAttributePresentAndTrue = ODataAtomReaderUtils.ReadMetadataNullAttributeValue(xmlReader.Value);
                    }

                    // Ignore all other attributes in the metadata namespace.
                    // In general, we only fail on reading if we can't make sense of the document any more. Reader should be loose.
                    // If we choose to start recognizing an additional attribute in the metadata namespace later, be careful not to
                    // fail if it doesn't parse correctly (so that we don't cause a breaking change).
                }
                else if (xmlReader.NamespaceEquals(emptyNamespace))
                {
                    if (xmlReader.LocalNameEquals(termAttributeName))
                    {
                        termAttributeValue = xmlReader.Value;

                        // Before doing any other validation or further reading, check whether or not to read this annotation according to the filter.
                        if (propertyAndValueDeserializer.MessageReaderSettings.ShouldSkipAnnotation(termAttributeValue))
                        {
                            xmlReader.MoveToElement();
                            return null;
                        }
                    }
                    else if (xmlReader.LocalNameEquals(targetAttributeName))
                    {
                        targetAttributeValue = xmlReader.Value;
                    }
                    else
                    {
                        // Check if this attribute is one used by attribute value notation.
                        IEdmPrimitiveTypeReference potentialTypeFromAttributeValueNotation = LookupEdmTypeByAttributeValueNotationName(xmlReader.LocalName);
                        if (potentialTypeFromAttributeValueNotation != null)
                        {
                            // If we've already seen an attribute used for attribute value notation, 
                            // throw since we don't know which type to use (even if the values are the same).
                            // But don't throw yet, because we might not have encountered the term name yet,
                            // and the annotation filter might say to ignore this annotation (and so we shouldn't throw).
                            if (attributeValueNotationTypeReference != null)
                            {
                                sawMultipleAttributeValueNotations = true;
                            }

                            attributeValueNotationTypeReference = potentialTypeFromAttributeValueNotation;
                            attributeValueNotationAttributeName = xmlReader.LocalName;
                            attributeValueNotationAttributeValue = xmlReader.Value;
                        }
                    }

                    // Ignore all other attributes in the empty namespace.
                }

                // Ignore all other attributes in all other namespaces.
            }

            xmlReader.MoveToElement();

            // The term attribute is required.
            if (termAttributeValue == null)
            {
                throw new ODataException(ODataErrorStrings.AtomInstanceAnnotation_MissingTermAttributeOnAnnotationElement);
            }

            if (sawMultipleAttributeValueNotations)
            {
                throw new ODataException(ODataErrorStrings.AtomInstanceAnnotation_MultipleAttributeValueNotationAttributes);
            }
            
            // If this term is defined in the model, look up its type. If the term is not in the model, this will be null.
            IEdmTypeReference expectedTypeReference = MetadataUtils.LookupTypeOfValueTerm(termAttributeValue, propertyAndValueDeserializer.Model);

            ODataValue annotationValue;
            if (nullAttributePresentAndTrue)
            {
                // The m:null attribute has precedence over the content of the element, thus if we find m:null='true' we ignore the content of the element.
                ReaderValidationUtils.ValidateNullValue(
                    propertyAndValueDeserializer.Model, 
                    expectedTypeReference, 
                    propertyAndValueDeserializer.MessageReaderSettings, 
                    /*validateNullValue*/ true,
                    termAttributeValue);
                annotationValue = new ODataNullValue();
            }
            else if (attributeValueNotationTypeReference != null)
            {
                annotationValue = GetValueFromAttributeValueNotation(
                    expectedTypeReference,
                    attributeValueNotationTypeReference,
                    attributeValueNotationAttributeName,
                    attributeValueNotationAttributeValue,
                    typeAttributeValue,
                    xmlReader.IsEmptyElement,
                    propertyAndValueDeserializer.Model,
                    propertyAndValueDeserializer.MessageReaderSettings);
            }
            else
            {
                annotationValue = ReadValueFromElementContent(propertyAndValueDeserializer, expectedTypeReference);
            }

            // Read the end tag (or the start tag if it was an empty element).
            xmlReader.Read();

            return new AtomInstanceAnnotation(
                targetAttributeValue,
                termAttributeValue,
                annotationValue);
        }
Exemple #29
0
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
 private IEnumerable<ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     bool synchronous,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
         this,
         messageStream,
         detectionInfo.GetEncoding(),
         detectionInfo.MessageReaderSettings,
         readingResponse,
         synchronous,
         detectionInfo.Model,
         /*urlResolver*/ null))
     {
         return inputContext.DetectPayloadKind(detectionInfo);
     }
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomPayloadKindDetectionDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomCollectionDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
     this.duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();
 }
        private void VerifyComplexTypeRoundtrip(ODataComplexValue value, string typeName)
        {
            var typeReference = new EdmComplexTypeReference((IEdmComplexType)model.FindType(typeName), true);
            MemoryStream stream = new MemoryStream();
            using (ODataAtomOutputContext outputContext = new ODataAtomOutputContext(
                ODataFormat.Atom,
                new NonDisposingStream(stream),
                Encoding.UTF8,
                new ODataMessageWriterSettings() { Version = ODataVersion.V4 },
                /*writingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                ODataAtomPropertyAndValueSerializer serializer = new ODataAtomPropertyAndValueSerializer(outputContext);
                serializer.XmlWriter.WriteStartElement("ValueElement");
                serializer.WriteComplexValue(
                    value, 
                    typeReference, 
                    /*isOpenPropertyType*/ false, 
                    /*isWritingCollection*/ false, 
                    /*beforeValueAction*/ null, 
                    /*afterValueAction*/ null, 
                    new DuplicatePropertyNamesChecker(false, false), 
                    /*collectionValidator*/ null, 
                    /*projectedProperties*/ null);
                serializer.XmlWriter.WriteEndElement();
            }

            stream.Position = 0;
            object actualValue;

            using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
                ODataFormat.Atom,
                stream,
                Encoding.UTF8,
                new ODataMessageReaderSettings(),
                /*readingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                ODataAtomPropertyAndValueDeserializer deserializer = new ODataAtomPropertyAndValueDeserializer(inputContext);
                deserializer.XmlReader.MoveToContent();
                actualValue = deserializer.ReadNonEntityValue(
                    typeReference, 
                    /*duplicatePropertyNamesChecker*/ null,
                    /*collectionValidator*/ null, 
                    /*validateNullValue*/ true);
            }

            TestUtils.AssertODataValueAreEqual(actualValue as ODataValue, value);
        }
        private ODataAtomAnnotationReader CreateODataAtomAnnotationReader(string annotationElementText)
        {
            // Create a dummy root node wrapping the annotation element in order to define the namespace prefix mappings.
            string xmlText = "<dummy xmlns:m=\"" + AtomConstants.ODataMetadataNamespace + "\" xmlns:d=\"" + AtomConstants.ODataNamespace + "\" xmlns=\"" + AtomConstants.AtomNamespace + "\">" + annotationElementText + "</dummy>";

            var inputContext = new ODataAtomInputContext(
                ODataFormat.Atom,
                new MemoryStream(Encoding.UTF8.GetBytes(xmlText)),
                Encoding.UTF8,
                new ODataMessageReaderSettings { ShouldIncludeAnnotation = this.shouldIncludeAnnotation },
                true,
                true,
                this.model,
                null);
            this.xmlReader = inputContext.XmlReader;

            var parser = new ODataAtomAnnotationReader(inputContext, new ODataAtomPropertyAndValueDeserializer(inputContext));

            // Position the xml reader on the dummy element.
            this.xmlReader.Read();

            // Read over the start element of the dummy element (and position the reader on the m:annotation start tag).
            this.xmlReader.Read();
            return parser;
        }
Exemple #34
0
        /// <summary>
        /// Creates a new instance of this class by consuming xml from the given input context.
        /// </summary>
        /// <param name="inputContext">The input context to use to create the annotation.</param>
        /// <param name="propertyAndValueDeserializer">The property and value deserializer to use when reading values in the annotation element content.</param>
        /// <returns>The <see cref="AtomInstanceAnnotation"/> populated with the information from the 'm:annotation' XML element, as long as the value is a string. Returns null otherwise.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element    - The annotation element to read.
        /// Post-Condition:  XmlNodeType.Any        - The node after the end of the annotation element, or the same element as in the pre-condition if the annotation was skipped.
        /// </remarks>
        internal static AtomInstanceAnnotation CreateFrom(ODataAtomInputContext inputContext, ODataAtomPropertyAndValueDeserializer propertyAndValueDeserializer)
        {
            var xmlReader = inputContext.XmlReader;

            Debug.Assert(xmlReader != null, "xmlReader != null");
            Debug.Assert(xmlReader.NodeType == XmlNodeType.Element, "xmlReader must be positioned on an Element");
            Debug.Assert(xmlReader.NameTable != null, "xmlReader.NameTable != null");
            Debug.Assert(xmlReader.LocalName == "annotation", "Must be positioned on an annotation element");

            string termAttributeValue                 = null;
            string targetAttributeValue               = null;
            string typeAttributeValue                 = null;
            bool   nullAttributePresentAndTrue        = false;
            bool   sawMultipleAttributeValueNotations = false;

            // Notes on "attribute value notation":
            // Empty elements may have the annotation value specified via an attribute on the annotation element.
            // Exactly one of the following attributes must be present if this notation is being used: "string", "int", "bool", "float", "decimal".
            // The value of the annotation is the value of this value-specifying attribute.
            string attributeValueNotationAttributeName  = null;
            string attributeValueNotationAttributeValue = null;
            IEdmPrimitiveTypeReference attributeValueNotationTypeReference = null;

            XmlNameTable xmlNameTable        = xmlReader.NameTable;
            string       metadataNamespace   = xmlNameTable.Get(AtomConstants.ODataMetadataNamespace);
            string       nullAttributeName   = xmlNameTable.Get(AtomConstants.ODataNullAttributeName);
            string       typeAttributeName   = xmlNameTable.Get(AtomConstants.AtomTypeAttributeName);
            string       emptyNamespace      = xmlNameTable.Get(string.Empty);
            string       termAttributeName   = xmlNameTable.Get(AtomConstants.ODataAnnotationTermAttribute);
            string       targetAttributeName = xmlNameTable.Get(AtomConstants.ODataAnnotationTargetAttribute);

            // Loop through all the attributes and remember the ones specific to annotations.
            while (xmlReader.MoveToNextAttribute())
            {
                if (xmlReader.NamespaceEquals(metadataNamespace))
                {
                    if (xmlReader.LocalNameEquals(typeAttributeName))
                    {
                        typeAttributeValue = xmlReader.Value;
                    }
                    else if (xmlReader.LocalNameEquals(nullAttributeName))
                    {
                        nullAttributePresentAndTrue = ODataAtomReaderUtils.ReadMetadataNullAttributeValue(xmlReader.Value);
                    }

                    // Ignore all other attributes in the metadata namespace.
                    // In general, we only fail on reading if we can't make sense of the document any more. Reader should be loose.
                    // If we choose to start recognizing an additional attribute in the metadata namespace later, be careful not to
                    // fail if it doesn't parse correctly (so that we don't cause a breaking change).
                }
                else if (xmlReader.NamespaceEquals(emptyNamespace))
                {
                    if (xmlReader.LocalNameEquals(termAttributeName))
                    {
                        termAttributeValue = xmlReader.Value;

                        // Before doing any other validation or further reading, check whether or not to read this annotation according to the filter.
                        if (propertyAndValueDeserializer.MessageReaderSettings.ShouldSkipAnnotation(termAttributeValue))
                        {
                            xmlReader.MoveToElement();
                            return(null);
                        }
                    }
                    else if (xmlReader.LocalNameEquals(targetAttributeName))
                    {
                        targetAttributeValue = xmlReader.Value;
                    }
                    else
                    {
                        // Check if this attribute is one used by attribute value notation.
                        IEdmPrimitiveTypeReference potentialTypeFromAttributeValueNotation = LookupEdmTypeByAttributeValueNotationName(xmlReader.LocalName);
                        if (potentialTypeFromAttributeValueNotation != null)
                        {
                            // If we've already seen an attribute used for attribute value notation,
                            // throw since we don't know which type to use (even if the values are the same).
                            // But don't throw yet, because we might not have encountered the term name yet,
                            // and the annotation filter might say to ignore this annotation (and so we shouldn't throw).
                            if (attributeValueNotationTypeReference != null)
                            {
                                sawMultipleAttributeValueNotations = true;
                            }

                            attributeValueNotationTypeReference  = potentialTypeFromAttributeValueNotation;
                            attributeValueNotationAttributeName  = xmlReader.LocalName;
                            attributeValueNotationAttributeValue = xmlReader.Value;
                        }
                    }

                    // Ignore all other attributes in the empty namespace.
                }

                // Ignore all other attributes in all other namespaces.
            }

            xmlReader.MoveToElement();

            // The term attribute is required.
            if (termAttributeValue == null)
            {
                throw new ODataException(ODataErrorStrings.AtomInstanceAnnotation_MissingTermAttributeOnAnnotationElement);
            }

            if (sawMultipleAttributeValueNotations)
            {
                throw new ODataException(ODataErrorStrings.AtomInstanceAnnotation_MultipleAttributeValueNotationAttributes);
            }

            // If this term is defined in the model, look up its type. If the term is not in the model, this will be null.
            IEdmTypeReference expectedTypeReference = MetadataUtils.LookupTypeOfValueTerm(termAttributeValue, propertyAndValueDeserializer.Model);

            ODataValue annotationValue;

            if (nullAttributePresentAndTrue)
            {
                // The m:null attribute has precedence over the content of the element, thus if we find m:null='true' we ignore the content of the element.
                ReaderValidationUtils.ValidateNullValue(
                    propertyAndValueDeserializer.Model,
                    expectedTypeReference,
                    propertyAndValueDeserializer.MessageReaderSettings,
                    /*validateNullValue*/ true,
                    termAttributeValue);
                annotationValue = new ODataNullValue();
            }
            else if (attributeValueNotationTypeReference != null)
            {
                annotationValue = GetValueFromAttributeValueNotation(
                    expectedTypeReference,
                    attributeValueNotationTypeReference,
                    attributeValueNotationAttributeName,
                    attributeValueNotationAttributeValue,
                    typeAttributeValue,
                    xmlReader.IsEmptyElement,
                    propertyAndValueDeserializer.Model,
                    propertyAndValueDeserializer.MessageReaderSettings);
            }
            else
            {
                annotationValue = ReadValueFromElementContent(propertyAndValueDeserializer, expectedTypeReference);
            }

            // Read the end tag (or the start tag if it was an empty element).
            xmlReader.Read();

            return(new AtomInstanceAnnotation(
                       targetAttributeValue,
                       termAttributeValue,
                       annotationValue));
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="atomInputContext">The ATOM input context to read from.</param>
 internal ODataAtomCollectionDeserializer(ODataAtomInputContext atomInputContext)
     : base(atomInputContext)
 {
     this.duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();
 }
 private ODataAtomServiceDocumentDeserializer CreateODataAtomServiceDocumentDeserializer(MemoryStream stream, bool enableAtomMetadataReading, IODataUrlResolver urlResolver = null)
 {
     ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
     settings.EnableAtomMetadataReading = enableAtomMetadataReading;
     ODataAtomInputContext inputContext = new ODataAtomInputContext(ODataFormat.Atom, stream, Encoding.UTF8, settings, true /*readingResponse*/, true /*sync*/, null /*edmModel*/, urlResolver);
     return new ODataAtomServiceDocumentDeserializer(inputContext);
 }