/// <summary>
        /// Creates a <see cref="ODataServiceDocumentElement"/>.
        /// </summary>
        /// <param name="kind">Property values for the "kind" property.</param>
        /// <returns>A <see cref="ODataServiceDocumentElement"/> instance.</returns>
        private static ODataServiceDocumentElement CreateServiceDocumentElement(string[] kind)
        {
            // If not specified its an entity set.
            if (kind[0] == null)
            {
                return(new ODataEntitySetInfo());
            }

            ODataServiceDocumentElement serviceDocumentElement = null;

            if (kind[0].Equals(JsonLightConstants.ServiceDocumentEntitySetKindName, StringComparison.Ordinal))
            {
                serviceDocumentElement = new ODataEntitySetInfo();
            }
            else if (kind[0].Equals(JsonLightConstants.ServiceDocumentFunctionImportKindName, StringComparison.Ordinal))
            {
                serviceDocumentElement = new ODataFunctionImportInfo();
            }
            else if (kind[0].Equals(JsonLightConstants.ServiceDocumentSingletonKindName, StringComparison.Ordinal))
            {
                serviceDocumentElement = new ODataSingletonInfo();
            }

            return(serviceDocumentElement);
        }
Example #2
0
        private static ODataFunctionImportInfo GetODataFunctionImportInfo(string name)
        {
            ODataFunctionImportInfo info = new ODataFunctionImportInfo
            {
                Name = name,
                Url  = new Uri(name, UriKind.Relative) // Relative to the OData root
            };

            return(info);
        }
        private static ODataFunctionImportInfo GetODataFunctionImportInfo(string name)
        {
            ODataFunctionImportInfo info = new ODataFunctionImportInfo
            {
                Name = name,
                Url = new Uri(name, UriKind.Relative) // Relative to the OData root
            };

            return info;
        }
Example #4
0
        /// <summary>
        /// Reads a workspace of a service document.
        /// </summary>
        /// <returns>An <see cref="ODataServiceDocument"/> representing the workspace of a service document.</returns>
        /// <remarks>
        /// Pre-Condition:  Any    - the next node after the service element.
        /// Post-Condition: Any    - The next node after the workspace element.
        /// </remarks>
        private ODataServiceDocument ReadWorkspace()
        {
            Debug.Assert(this.XmlReader != null, "this.XmlReader != null");

            bool enableAtomMetadataReading = this.AtomInputContext.MessageReaderSettings.EnableAtomMetadataReading;

            // skip anything which is not in the ATOM publishing namespace.
            this.SkipToElementInAtomPublishingNamespace();

            this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.EndElement);

            // if we already found an EndElement, it means that there is no serviceDocument.
            if (this.XmlReader.NodeType == XmlNodeType.EndElement)
            {
                return(null);
            }

            this.AssertXmlCondition(XmlNodeType.Element);
            Debug.Assert(this.XmlReader.NamespaceEquals(this.AtomPublishingNamespace), "The current element should have been in the Atom publishing namespace.");

            if (!this.XmlReader.LocalNameEquals(this.AtomPublishingWorkspaceElementName))
            {
                throw new ODataException(Strings.ODataAtomServiceDocumentDeserializer_UnexpectedElementInServiceDocument(this.XmlReader.LocalName));
            }

            List <ODataEntitySetInfo>      collections         = new List <ODataEntitySetInfo>();
            List <ODataFunctionImportInfo> functionImportInfos = new List <ODataFunctionImportInfo>();
            List <ODataSingletonInfo>      singletons          = new List <ODataSingletonInfo>();
            AtomWorkspaceMetadata          workspaceMetadata   = null;

            if (enableAtomMetadataReading)
            {
                workspaceMetadata = new AtomWorkspaceMetadata();
            }

            if (!this.XmlReader.IsEmptyElement)
            {
                // read over the 'serviceDocument' element.
                this.XmlReader.ReadStartElement();

                do
                {
                    this.XmlReader.SkipInsignificantNodes();

                    switch (this.XmlReader.NodeType)
                    {
                    case XmlNodeType.Element:
                        if (this.XmlReader.NamespaceEquals(this.AtomPublishingNamespace))
                        {
                            if (this.XmlReader.LocalNameEquals(this.AtomPublishingCollectionElementName))
                            {
                                ODataEntitySetInfo collection = this.ReadEntitySet();
                                Debug.Assert(collection != null, "collection != null");
                                collections.Add(collection);
                            }
                            else
                            {
                                // Throw error if we find anything other then a 'collection' element in the Atom publishing namespace.
                                throw new ODataException(Strings.ODataAtomServiceDocumentDeserializer_UnexpectedElementInWorkspace(this.XmlReader.LocalName));
                            }
                        }
                        else if (this.XmlReader.NamespaceEquals(this.ODataMetadataNamespace))
                        {
                            if (this.XmlReader.LocalNameEquals(this.ODataFunctionImportElementName))
                            {
                                ODataFunctionImportInfo functionImportInfo = this.ReadFunctionImportInfo();
                                Debug.Assert(functionImportInfo != null, "functionImportInfo != null");
                                functionImportInfos.Add(functionImportInfo);
                            }
                            else if (this.XmlReader.LocalNameEquals(this.ODataSingletonElementName))
                            {
                                ODataSingletonInfo singletonInfo = this.ReadSingletonInfo();
                                Debug.Assert(singletonInfo != null, "singletonInfo != null");
                                singletons.Add(singletonInfo);
                            }
                            else
                            {
                                // Throw error if we find anything other then a 'function-import' or 'singleton' element in the odata metadata namespace.
                                throw new ODataException(Strings.ODataAtomServiceDocumentDeserializer_UnexpectedODataElementInWorkspace(this.XmlReader.LocalName));
                            }
                        }
                        else if (enableAtomMetadataReading && this.XmlReader.NamespaceEquals(this.AtomNamespace))
                        {
                            if (this.XmlReader.LocalNameEquals(this.AtomTitleElementName))
                            {
                                this.ServiceDocumentMetadataDeserializer.ReadTitleElementInWorkspace(workspaceMetadata);
                            }
                            else
                            {
                                this.XmlReader.Skip();
                            }
                        }
                        else
                        {
                            // skip all other elements
                            this.XmlReader.Skip();
                        }

                        break;

                    case XmlNodeType.EndElement:
                        // end of 'serviceDocument' element.
                        break;

                    default:
                        // ignore all other nodes.
                        this.XmlReader.Skip();
                        break;
                    }
                }while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            } // if (!this.XmlReader.IsEmptyElement)

            // read over the end tag of the serviceDocument element or the start tag if the serviceDocument element is empty.
            this.XmlReader.Read();

            ODataServiceDocument serviceDocument = new ODataServiceDocument
            {
                EntitySets      = new ReadOnlyEnumerable <ODataEntitySetInfo>(collections),
                FunctionImports = new ReadOnlyCollection <ODataFunctionImportInfo>(functionImportInfos),
                Singletons      = new ReadOnlyCollection <ODataSingletonInfo>(singletons)
            };

            if (enableAtomMetadataReading)
            {
                serviceDocument.SetAnnotation <AtomWorkspaceMetadata>(workspaceMetadata);
            }

            return(serviceDocument);
        }
        /// <summary>
        /// Reads a resource collection within a service document.
        /// </summary>
        /// <param name="propertyAndAnnotationCollector">The <see cref="PropertyAndAnnotationCollector"/> to use for parsing annotations within the service document element object.</param>
        /// <returns>A <see cref="ODataEntitySetInfo"/> representing the read resource collection.</returns>
        /// <remarks>
        /// Pre-Condition:  JsonNodeType.StartObject:     The beginning of the JSON object representing the service document element.
        ///                 other:                        Will throw with an appropriate message on any other node type encountered.
        /// Post-Condition: JsonNodeType.StartObject:     The beginning of the next resource collection in the array.
        ///                 JsonNodeType.EndArray:        The end of the array.
        ///                 other:                        Any other node type occuring after the end object of the current service document element. (Would be invalid).
        /// </remarks>
        private ODataServiceDocumentElement ReadServiceDocumentElement(PropertyAndAnnotationCollector propertyAndAnnotationCollector)
        {
            this.JsonReader.ReadStartObject();
            string[] name  = { null };
            string[] url   = { null };
            string[] kind  = { null };
            string[] title = { null };

            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                // OData property annotations are not supported in service document element objects.
                Func <string, object> propertyAnnotationValueReader = annotationName => { throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_PropertyAnnotationInServiceDocumentElement(annotationName)); };

                this.ProcessProperty(
                    propertyAndAnnotationCollector,
                    propertyAnnotationValueReader,
                    (propertyParsingResult, propertyName) =>
                {
                    if (this.JsonReader.NodeType == JsonNodeType.Property)
                    {
                        // Read over property name
                        this.JsonReader.Read();
                    }

                    switch (propertyParsingResult)
                    {
                    case PropertyParsingResult.ODataInstanceAnnotation:
                        throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_InstanceAnnotationInServiceDocumentElement(propertyName));

                    case PropertyParsingResult.CustomInstanceAnnotation:
                        this.JsonReader.SkipValue();
                        break;

                    case PropertyParsingResult.PropertyWithoutValue:
                        throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_PropertyAnnotationWithoutProperty(propertyName));

                    case PropertyParsingResult.MetadataReferenceProperty:
                        throw new ODataException(Strings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedMetadataReferenceProperty(propertyName));

                    case PropertyParsingResult.PropertyWithValue:
                        if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementName, propertyName) == 0)
                        {
                            if (name[0] != null)
                            {
                                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementName));
                            }

                            name[0] = this.JsonReader.ReadStringValue();
                        }
                        else if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementUrlName, propertyName) == 0)
                        {
                            if (url[0] != null)
                            {
                                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementUrlName));
                            }

                            url[0] = this.JsonReader.ReadStringValue();
                            ValidationUtils.ValidateServiceDocumentElementUrl(url[0]);
                        }
                        else if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementKind, propertyName) == 0)
                        {
                            if (kind[0] != null)
                            {
                                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementKind));
                            }

                            kind[0] = this.JsonReader.ReadStringValue();
                        }
                        else if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementTitle, propertyName) == 0)
                        {
                            if (title[0] != null)
                            {
                                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementTitle));
                            }

                            title[0] = this.JsonReader.ReadStringValue();
                        }
                        else
                        {
                            throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_UnexpectedPropertyInServiceDocumentElement(propertyName, JsonLightConstants.ODataServiceDocumentElementName, JsonLightConstants.ODataServiceDocumentElementUrlName));
                        }

                        break;
                    }
                });
            }

            // URL and Name are mandatory
            if (string.IsNullOrEmpty(name[0]))
            {
                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_MissingRequiredPropertyInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementName));
            }

            if (string.IsNullOrEmpty(url[0]))
            {
                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_MissingRequiredPropertyInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementUrlName));
            }

            ODataServiceDocumentElement serviceDocumentElement = null;

            if (kind[0] != null)
            {
                if (kind[0].Equals(JsonLightConstants.ServiceDocumentEntitySetKindName, StringComparison.Ordinal))
                {
                    serviceDocumentElement = new ODataEntitySetInfo();
                }
                else if (kind[0].Equals(JsonLightConstants.ServiceDocumentFunctionImportKindName, StringComparison.Ordinal))
                {
                    serviceDocumentElement = new ODataFunctionImportInfo();
                }
                else if (kind[0].Equals(JsonLightConstants.ServiceDocumentSingletonKindName, StringComparison.Ordinal))
                {
                    serviceDocumentElement = new ODataSingletonInfo();
                }
            }
            else
            {
                // if not specified its an entity set.
                serviceDocumentElement = new ODataEntitySetInfo();
            }

            if (serviceDocumentElement != null)
            {
                serviceDocumentElement.Url   = this.ProcessUriFromPayload(url[0]);
                serviceDocumentElement.Name  = name[0];
                serviceDocumentElement.Title = title[0];
            }

            this.JsonReader.ReadEndObject();

            return(serviceDocumentElement);
        }
 /// <summary>
 /// Writes a function import resource in service document.
 /// </summary>
 /// <param name="functionInfo">The function import resource to write.</param>
 private void WriteFunctionImportInfo(ODataFunctionImportInfo functionInfo)
 {
     WriteNonEntitySetInfoElement(functionInfo, AtomConstants.AtomServiceDocumentFunctionImportElementName);
 }
        /// <summary>
        /// Reads a resource collection within a service document.
        /// </summary>
        /// <param name="duplicatePropertyNamesChecker">The <see cref="DuplicatePropertyNamesChecker"/> to use for parsing annotations within the service document element object.</param>
        /// <returns>A <see cref="ODataEntitySetInfo"/> representing the read resource collection.</returns>
        /// <remarks>
        /// Pre-Condition:  JsonNodeType.StartObject:     The beginning of the JSON object representing the service document element.
        ///                 other:                        Will throw with an appropriate message on any other node type encountered.
        /// Post-Condition: JsonNodeType.StartObject:     The beginning of the next resource collection in the array.
        ///                 JsonNodeType.EndArray:        The end of the array.
        ///                 other:                        Any other node type occuring after the end object of the current service document element. (Would be invalid).
        /// </remarks>
        private ODataServiceDocumentElement ReadServiceDocumentElement(DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            this.JsonReader.ReadStartObject();
            string[] name = { null };
            string[] url = { null };
            string[] kind = { null };
            string[] title = { null };

            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                // OData property annotations are not supported in service document element objects.
                Func<string, object> propertyAnnotationValueReader = annotationName => { throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_PropertyAnnotationInServiceDocumentElement(annotationName)); };

                this.ProcessProperty(
                    duplicatePropertyNamesChecker,
                    propertyAnnotationValueReader,
                    (propertyParsingResult, propertyName) =>
                    {
                        switch (propertyParsingResult)
                        {
                            case PropertyParsingResult.ODataInstanceAnnotation:
                                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_InstanceAnnotationInServiceDocumentElement(propertyName));

                            case PropertyParsingResult.CustomInstanceAnnotation:
                                this.JsonReader.SkipValue();
                                break;

                            case PropertyParsingResult.PropertyWithoutValue:
                                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_PropertyAnnotationWithoutProperty(propertyName));

                            case PropertyParsingResult.MetadataReferenceProperty:
                                throw new ODataException(Strings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedMetadataReferenceProperty(propertyName));

                            case PropertyParsingResult.PropertyWithValue:
                                if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementName, propertyName) == 0)
                                {
                                    if (name[0] != null)
                                    {
                                        throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementName));
                                    }

                                    name[0] = this.JsonReader.ReadStringValue();
                                }
                                else if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementUrlName, propertyName) == 0)
                                {
                                    if (url[0] != null)
                                    {
                                        throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementUrlName));
                                    }

                                    url[0] = this.JsonReader.ReadStringValue();
                                    ValidationUtils.ValidateServiceDocumentElementUrl(url[0]);
                                }
                                else if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementKind, propertyName) == 0)
                                {
                                    if (kind[0] != null)
                                    {
                                        throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementKind));
                                    }

                                    kind[0] = this.JsonReader.ReadStringValue();
                                }
                                else if (string.CompareOrdinal(JsonLightConstants.ODataServiceDocumentElementTitle, propertyName) == 0)
                                {
                                    if (title[0] != null)
                                    {
                                        throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_DuplicatePropertiesInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementTitle));
                                    }

                                    title[0] = this.JsonReader.ReadStringValue();
                                }
                                else
                                {
                                    throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_UnexpectedPropertyInServiceDocumentElement(propertyName, JsonLightConstants.ODataServiceDocumentElementName, JsonLightConstants.ODataServiceDocumentElementUrlName));
                                }

                                break;
                        }
                    });
            }

            // URL and Name are mandatory
            if (string.IsNullOrEmpty(name[0]))
            {
                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_MissingRequiredPropertyInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementName));
            }

            if (string.IsNullOrEmpty(url[0]))
            {
                throw new ODataException(Strings.ODataJsonLightServiceDocumentDeserializer_MissingRequiredPropertyInServiceDocumentElement(JsonLightConstants.ODataServiceDocumentElementUrlName));
            }

            ODataServiceDocumentElement serviceDocumentElement = null;
            if (kind[0] != null)
            {
                if (kind[0].Equals(JsonLightConstants.ServiceDocumentEntitySetKindName, StringComparison.Ordinal))
                {
                    serviceDocumentElement = new ODataEntitySetInfo();
                }
                else if (kind[0].Equals(JsonLightConstants.ServiceDocumentFunctionImportKindName, StringComparison.Ordinal))
                {
                    serviceDocumentElement = new ODataFunctionImportInfo();
                }
                else if (kind[0].Equals(JsonLightConstants.ServiceDocumentSingletonKindName, StringComparison.Ordinal))
                {
                    serviceDocumentElement = new ODataSingletonInfo();
                }
            }
            else
            {
                // if not specified its an entity set.
                serviceDocumentElement = new ODataEntitySetInfo();
            }

            if (serviceDocumentElement != null)
            {
                serviceDocumentElement.Url = this.ProcessUriFromPayload(url[0]);
                serviceDocumentElement.Name = name[0];
                serviceDocumentElement.Title = title[0];
            }

            this.JsonReader.ReadEndObject();

            return serviceDocumentElement;
        }
 /// <summary>
 /// Writes a function import resource in service document.
 /// </summary>
 /// <param name="functionInfo">The function import resource to write.</param>
 private void WriteFunctionImportInfo(ODataFunctionImportInfo functionInfo)
 {
     WriteNonEntitySetInfoElement(functionInfo, AtomConstants.AtomServiceDocumentFunctionImportElementName);
 }