/// <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); }
public void PropertySettersNullTest() { ODataEntitySetInfo entitySetInfo = new ODataEntitySetInfo(); entitySetInfo.Url = null; this.Assert.IsNull(entitySetInfo.Url, "Expected null value for property 'Url'."); }
private static ODataEntitySetInfo GetODataEntitySetInfo(string url, string name) { ODataEntitySetInfo info = new ODataEntitySetInfo { Name = name, // Required for JSON support Url = new Uri(url, UriKind.Relative) }; return(info); }
private static ODataEntitySetInfo GetODataEntitySetInfo(string url, string name) { ODataEntitySetInfo info = new ODataEntitySetInfo { Name = name, // Required for JSON support Url = new Uri(url, UriKind.Relative) }; return info; }
public void CategoryMetadataOnWorkspaceCollectionCategoriesWriterTest() { var testCases = this.CreateAtomCategoryTestCases(); // Convert test cases to test descriptions var testDescriptors = testCases.Select(testCase => { AtomResourceCollectionMetadata metadata = new AtomResourceCollectionMetadata { Categories = new AtomCategoriesMetadata { Categories = new[] { testCase.Category } } }; ODataEntitySetInfo collection = new ODataEntitySetInfo { Url = new Uri("http://odata.org/collection") }; collection.SetAnnotation(metadata); ODataServiceDocument serviceDocument = new ODataServiceDocument { EntitySets = new[] { collection } }; return(new PayloadWriterTestDescriptor <ODataServiceDocument>( this.Settings, serviceDocument, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, ExpectedException2 = testCase.ExpectedException, FragmentExtractor = result => result .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingWorkspaceElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCollectionElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCategoriesElementName) .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomCategoryElementName) })); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyTopLevelContent( testDescriptor, testConfiguration, (messageWriter) => messageWriter.WriteServiceDocument(testDescriptor.PayloadItems.Single()), this.Assert, baselineLogger: this.Logger); }); }
public void PropertyGettersAndSettersTest() { Uri url = new Uri("MyResourceCollection", UriKind.Relative); ODataEntitySetInfo entitySetInfo = new ODataEntitySetInfo() { Url = url }; this.Assert.AreSame(url, entitySetInfo.Url, "Expected reference equal values for property 'Url'."); }
/// <summary> /// Visits a resource collection. /// </summary> /// <param name="entitySetInfo">The resource collection to visit.</param> protected override ODataPayloadElement VisitResourceCollection(ODataEntitySetInfo entitySetInfo) { ExceptionUtilities.CheckArgumentNotNull(entitySetInfo, "entitySetInfo"); ResourceCollectionInstance collectionInstance = new ResourceCollectionInstance(); collectionInstance.Href = entitySetInfo.Url.OriginalString; collectionInstance.Name = entitySetInfo.Name; return(collectionInstance); }
private static ODataEntitySetInfo GetODataEntitySetInfo(string url, string name) { ODataEntitySetInfo info = new ODataEntitySetInfo { Name = name, // Required for JSON support Url = new Uri(url, UriKind.Relative) }; info.SetAnnotation<AtomResourceCollectionMetadata>(new AtomResourceCollectionMetadata { Title = name }); return info; }
public void PropertyGettersAndSettersTest() { ODataEntitySetInfo collection1 = new ODataEntitySetInfo(); ODataEntitySetInfo collection2 = new ODataEntitySetInfo(); ODataEntitySetInfo collection3 = new ODataEntitySetInfo(); ODataEntitySetInfo[] collections = new ODataEntitySetInfo[] { collection1, collection2, collection3 }; ODataServiceDocument serviceDocument = new ODataServiceDocument() { EntitySets = collections }; this.Assert.AreSame(collections, serviceDocument.EntitySets, "Expected reference equal values for property 'EntitySets'."); }
private static ODataEntitySetInfo GetODataEntitySetInfo(string url, string name) { ODataEntitySetInfo info = new ODataEntitySetInfo { Name = name, // Required for JSON support Url = new Uri(url, UriKind.Relative) }; info.SetAnnotation <AtomResourceCollectionMetadata>(new AtomResourceCollectionMetadata { Title = name }); return(info); }
/// <summary>Determines an extension method to get the <see cref="T:Microsoft.OData.Core.Atom.AtomResourceCollectionMetadata" /> for an entity set in service document.</summary> /// <returns>An <see cref="T:Microsoft.OData.Core.Atom.AtomResourceCollectionMetadata" /> instance or null if no annotation of that type exists.</returns> /// <param name="entitySet">The entity set in service document to get the annotation from.</param> public static AtomResourceCollectionMetadata Atom(this ODataEntitySetInfo entitySet) { ExceptionUtils.CheckArgumentNotNull(entitySet, "entitySet"); AtomResourceCollectionMetadata collectionMetadata = entitySet.GetAnnotation <AtomResourceCollectionMetadata>(); if (collectionMetadata == null) { collectionMetadata = new AtomResourceCollectionMetadata(); entitySet.SetAnnotation(collectionMetadata); } return(collectionMetadata); }
/// <summary>Writes the Service Document to the output stream.</summary> /// <param name="provider">DataServiceProviderWrapper instance.</param> internal void WriteServiceDocument(DataServiceProviderWrapper provider) { ODataServiceDocument serviceDocument = new ODataServiceDocument(); serviceDocument.EntitySets = provider.GetResourceSets().Select(rs => { ODataEntitySetInfo entitySetInfo = new ODataEntitySetInfo() { Url = new Uri(rs.Name, UriKind.RelativeOrAbsolute), Name = rs.Name }; return(entitySetInfo); }); this.writer.WriteServiceDocument(serviceDocument); }
/// <summary> /// Writes a entity set in service document. /// </summary> /// <param name="entitySetInfo">The entity set info to write.</param> private void WriteEntitySetInfo(ODataEntitySetInfo entitySetInfo) { // validate that the resource has a non-null url. #pragma warning disable 618 ValidationUtils.ValidateServiceDocumentElement(entitySetInfo, ODataFormat.Atom); #pragma warning restore 618 // <app:collection> this.XmlWriter.WriteStartElement(string.Empty, AtomConstants.AtomPublishingCollectionElementName, AtomConstants.AtomPublishingNamespace); // The name of the collection is the resource name; The href of the <app:collection> element must be the link for the entity set. // Since we model the collection as having a 'Name' (for JSON) we require a base Uri for Atom/Xml. this.XmlWriter.WriteAttributeString(AtomConstants.AtomHRefAttributeName, this.UriToUrlAttributeValue(entitySetInfo.Url)); this.atomServiceDocumentMetadataSerializer.WriteEntitySetInfoMetadata(entitySetInfo); // </app:collection> this.XmlWriter.WriteEndElement(); }
/// <summary>Writes the Service Document to the output stream.</summary> /// <param name="provider">DataServiceProviderWrapper instance.</param> internal void WriteServiceDocument(DataServiceProviderWrapper provider) { ODataServiceDocument serviceDocument = new ODataServiceDocument(); serviceDocument.EntitySets = provider.GetResourceSets().Select(rs => { ODataEntitySetInfo entitySetInfo = new ODataEntitySetInfo() { Url = new Uri(rs.Name, UriKind.RelativeOrAbsolute), Name = rs.Name }; entitySetInfo.SetAnnotation<AtomResourceCollectionMetadata>(new AtomResourceCollectionMetadata() { Title = new AtomTextConstruct { Text = rs.Name } }); return entitySetInfo; }); this.writer.WriteServiceDocument(serviceDocument); }
/// <summary> /// Visits a resource collection. /// </summary> /// <param name="entitySetInfo">The resource collection to visit.</param> protected override ODataPayloadElement VisitResourceCollection(ODataEntitySetInfo entitySetInfo) { ExceptionUtilities.CheckArgumentNotNull(entitySetInfo, "entitySetInfo"); ResourceCollectionInstance collectionInstance = (ResourceCollectionInstance)base.VisitResourceCollection(entitySetInfo); AtomResourceCollectionMetadata atomMetadata = entitySetInfo.GetAnnotation <AtomResourceCollectionMetadata>(); if (atomMetadata != null) { if (atomMetadata.Title != null) { collectionInstance.Title = atomMetadata.Title.Text; collectionInstance.AtomTitle(atomMetadata.Title.Text, ToString(atomMetadata.Title.Kind)); } if (atomMetadata.Accept != null) { collectionInstance.AppAccept(atomMetadata.Accept); } if (atomMetadata.Categories != null) { if (atomMetadata.Categories.Href != null) { collectionInstance.AppOutOfLineCategories(atomMetadata.Categories.Href.OriginalString); } else { collectionInstance.AppInlineCategories( atomMetadata.Categories.Fixed == null ? null : (atomMetadata.Categories.Fixed.Value ? TestAtomConstants.AtomPublishingFixedYesValue : TestAtomConstants.AtomPublishingFixedNoValue), atomMetadata.Categories.Scheme, atomMetadata.Categories.Categories == null ? new XmlTreeAnnotation[0] : atomMetadata.Categories.Categories.Select(category => AtomMetadataBuilder.AtomCategory(category.Term, category.Scheme, category.Label)).ToArray()); } } } return(collectionInstance); }
private static ODataServiceDocument CreateWorkspace(bool createMetadataFirst, string workspaceName = null, IEnumerable <CollectionInfo> incomingCollections = null, IEnumerable <SingletonInfo> incomingSingletons = null) { ODataServiceDocument serviceDocument = ObjectModelUtils.CreateDefaultWorkspace(); if (incomingCollections != null) { var collections = new List <ODataEntitySetInfo>(); foreach (var collectionInfo in incomingCollections) { var collection = new ODataEntitySetInfo() { Url = new Uri(collectionInfo.Url, UriKind.RelativeOrAbsolute), Name = collectionInfo.Name, Title = collectionInfo.TitleAnnotation }; collections.Add(collection); } serviceDocument.EntitySets = collections; } if (incomingSingletons != null) { var singletons = new List <ODataSingletonInfo>(); foreach (var singletonInfo in incomingSingletons) { var singleton = new ODataSingletonInfo() { Url = new Uri(singletonInfo.Url, UriKind.RelativeOrAbsolute), Name = singletonInfo.Name, Title = singletonInfo.TitleAnnotation }; singletons.Add(singleton); } serviceDocument.Singletons = singletons; } return(serviceDocument); }
/// <summary>Writes the Service Document to the output stream.</summary> /// <param name="provider">DataServiceProviderWrapper instance.</param> internal void WriteServiceDocument(DataServiceProviderWrapper provider) { ODataServiceDocument serviceDocument = new ODataServiceDocument(); serviceDocument.EntitySets = provider.GetResourceSets().Select(rs => { ODataEntitySetInfo entitySetInfo = new ODataEntitySetInfo() { Url = new Uri(rs.Name, UriKind.RelativeOrAbsolute), Name = rs.Name }; entitySetInfo.SetAnnotation <AtomResourceCollectionMetadata>(new AtomResourceCollectionMetadata() { Title = new AtomTextConstruct { Text = rs.Name } }); return(entitySetInfo); }); this.writer.WriteServiceDocument(serviceDocument); }
public void AtomCategoriesMetadataTest() { var testCases = new [] { // Empty categories new { CategoriesMetadata = new AtomCategoriesMetadata(), Xml = "<categories xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with href new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href") }, Xml = "<categories href='http://odata.org/href' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with href and non-null empty categories (null and empty collection should be treated the same) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Categories = new AtomCategoryMetadata[0] }, Xml = "<categories href='http://odata.org/href' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with fixed yes new { CategoriesMetadata = new AtomCategoriesMetadata() { Fixed = true }, Xml = "<categories fixed='yes' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with fixed no new { CategoriesMetadata = new AtomCategoriesMetadata() { Fixed = false }, Xml = "<categories fixed='no' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with scheme new { CategoriesMetadata = new AtomCategoriesMetadata() { Scheme = "http://odata.org/scheme" }, Xml = "<categories scheme='http://odata.org/scheme' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with scheme and fixed new { CategoriesMetadata = new AtomCategoriesMetadata() { Fixed = true, Scheme = "http://odata.org/scheme" }, Xml = "<categories fixed='yes' scheme='http://odata.org/scheme' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with single category new { CategoriesMetadata = new AtomCategoriesMetadata() { Categories = new [] { new AtomCategoryMetadata { Term = "myterm", Scheme = "http://odata.org/scheme" } } }, Xml = "<categories xmlns='http://www.w3.org/2007/app'><atom:category term='myterm' scheme='http://odata.org/scheme' xmlns:atom='http://www.w3.org/2005/Atom'/></categories>", ExpectedException = (ExpectedException)null }, // Categories with two categories new { CategoriesMetadata = new AtomCategoriesMetadata() { Categories = new [] { new AtomCategoryMetadata { Term = "myterm", Scheme = "http://odata.org/scheme" }, new AtomCategoryMetadata { Term = "second", Scheme = "http://odata.org/scheme2" } } }, Xml = "<categories xmlns='http://www.w3.org/2007/app'>" + "<atom:category term='myterm' scheme='http://odata.org/scheme' xmlns:atom='http://www.w3.org/2005/Atom'/>" + "<atom:category term='second' scheme='http://odata.org/scheme2' xmlns:atom='http://www.w3.org/2005/Atom'/>" + "</categories>", ExpectedException = (ExpectedException)null }, // Categories with href and fixed (error) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Fixed = true }, Xml = string.Empty, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues") }, // Categories with href and scheme (error) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Scheme = "http://odata.org/scheme" }, Xml = string.Empty, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues") }, // Categories with href and non-empty categories (error) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Categories = new [] { new AtomCategoryMetadata() } }, Xml = string.Empty, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues") }, }; var testDescriptors = testCases.Select(testCase => { ODataEntitySetInfo collection = new ODataEntitySetInfo { Url = new Uri("http://odata.org/url") }; AtomResourceCollectionMetadata metadata = new AtomResourceCollectionMetadata() { Categories = testCase.CategoriesMetadata }; collection.SetAnnotation(metadata); ODataServiceDocument serviceDocument = new ODataServiceDocument { EntitySets = new [] { collection } }; return new PayloadWriterTestDescriptor<ODataServiceDocument>( this.Settings, new [] { serviceDocument }, tc => { if (testCase.ExpectedException != null) { return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings) { ExpectedException2 = testCase.ExpectedException }; } else { return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, FragmentExtractor = result => result .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingWorkspaceElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCollectionElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCategoriesElementName) }; } }); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyTopLevelContent( testDescriptor, testConfiguration, (messageWriter) => messageWriter.WriteServiceDocument(testDescriptor.PayloadItems.Single()), this.Assert, baselineLogger: this.Logger); }); }
/// <summary> /// Visits a entity set. /// </summary> /// <param name="entitySetInfo">The entity set to visit.</param> protected override void VisitEntitySet(ODataEntitySetInfo entitySetInfo) { this.VisitAtomMetadata(entitySetInfo.GetAnnotation<AtomResourceCollectionMetadata>()); base.VisitEntitySet(entitySetInfo); }
public void AtomResourceCollectionMetadataTest() { var testCases = new[] { // No title specified - an empty one is used as it's required by the spec. new { CustomizeMetadata = (Action<ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); }), Xml = "<Collection><title xmlns='http://www.w3.org/2005/Atom'/></Collection>" }, // Simple title (other titles are tested in AtomTextConstructMetadataTests) new { CustomizeMetadata = (Action<ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = new AtomTextConstruct { Text = "collection title" }; }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title></Collection>" }, // With accept new { CustomizeMetadata = (Action<ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Accept = "mime/type"; }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><accept xmlns='http://www.w3.org/2007/app'>mime/type</accept></Collection>" }, // With empty accept new { CustomizeMetadata = (Action<ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Accept = string.Empty; }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><accept xmlns='http://www.w3.org/2007/app'></accept></Collection>" }, // With categories new { CustomizeMetadata = (Action<ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Categories = new AtomCategoriesMetadata(); }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><categories xmlns='http://www.w3.org/2007/app' /></Collection>" }, // With accept and categories new { CustomizeMetadata = (Action<ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Accept = "mime/type"; metadata.Categories = new AtomCategoriesMetadata(); }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><accept xmlns='http://www.w3.org/2007/app'>mime/type</accept><categories xmlns='http://www.w3.org/2007/app' /></Collection>" }, }; Func<ODataEntitySetInfo>[] collectionCreators = new Func<ODataEntitySetInfo>[] { () => new ODataEntitySetInfo { Url = new Uri("http://odata.org/url") }, () => { var collection = new ODataEntitySetInfo { Url = new Uri("http://odata.org/url") }; collection.SetAnnotation(new AtomResourceCollectionMetadata()); return collection; } }; var testDescriptors = testCases.SelectMany(testCase => collectionCreators.Select(collectionCreator => { ODataEntitySetInfo collection = collectionCreator(); testCase.CustomizeMetadata(collection); ODataServiceDocument serviceDocument = new ODataServiceDocument { EntitySets = new[] { collection } }; return new PayloadWriterTestDescriptor<ODataServiceDocument>( this.Settings, new[] { serviceDocument }, tc => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, FragmentExtractor = result => new XElement("Collection", result .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingWorkspaceElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCollectionElementName) .Elements()) }); })); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyTopLevelContent( testDescriptor, testConfiguration, (messageWriter) => messageWriter.WriteServiceDocument(testDescriptor.PayloadItems.Single()), this.Assert, baselineLogger: this.Logger); }); }
/// <summary> /// Visits a resource collection. /// </summary> /// <param name="entitySetInfo">The resource collection to visit.</param> protected virtual void VisitEntitySet(ODataEntitySetInfo entitySetInfo) { }
public void DefaultValuesTest() { ODataEntitySetInfo entitySetInfo = new ODataEntitySetInfo(); this.Assert.IsNull(entitySetInfo.Url, "Expected null default value for property 'Url'."); }
/// <summary> /// Visits an item in the object model. /// </summary> /// <param name="objectModelItem">The item to visit.</param> public virtual void Visit(object objectModelItem) { ODataFeed feed = objectModelItem as ODataFeed; if (feed != null) { this.VisitFeed(feed); return; } ODataEntry entry = objectModelItem as ODataEntry; if (entry != null) { this.VisitEntry(entry); return; } ODataProperty property = objectModelItem as ODataProperty; if (property != null) { this.VisitProperty(property); return; } ODataNavigationLink navigationLink = objectModelItem as ODataNavigationLink; if (navigationLink != null) { this.VisitNavigationLink(navigationLink); return; } ODataComplexValue complexValue = objectModelItem as ODataComplexValue; if (complexValue != null) { this.VisitComplexValue(complexValue); return; } ODataCollectionValue collectionValue = objectModelItem as ODataCollectionValue; if (collectionValue != null) { this.VisitCollectionValue(collectionValue); return; } ODataStreamReferenceValue streamReferenceValue = objectModelItem as ODataStreamReferenceValue; if (streamReferenceValue != null) { this.VisitStreamReferenceValue(streamReferenceValue); return; } ODataCollectionStart collectionStart = objectModelItem as ODataCollectionStart; if (collectionStart != null) { this.VisitCollectionStart(collectionStart); return; } ODataServiceDocument serviceDocument = objectModelItem as ODataServiceDocument; if (serviceDocument != null) { this.VisitServiceDocument(serviceDocument); return; } ODataEntitySetInfo entitySetInfo = objectModelItem as ODataEntitySetInfo; if (entitySetInfo != null) { this.VisitEntitySet(entitySetInfo); return; } ODataError error = objectModelItem as ODataError; if (error != null) { this.VisitError(error); return; } ODataInnerError innerError = objectModelItem as ODataInnerError; if (innerError != null) { this.VisitInnerError(innerError); return; } ODataEntityReferenceLinks entityReferenceLinks = objectModelItem as ODataEntityReferenceLinks; if (entityReferenceLinks != null) { this.VisitEntityReferenceLinks(entityReferenceLinks); return; } ODataEntityReferenceLink entityReferenceLink = objectModelItem as ODataEntityReferenceLink; if (entityReferenceLink != null) { this.VisitEntityReferenceLink(entityReferenceLink); return; } ODataAction action = objectModelItem as ODataAction; if (action != null) { this.VisitODataOperation(action); return; } ODataFunction function = objectModelItem as ODataFunction; if (function != null) { this.VisitODataOperation(function); return; } ODataParameters parameters = objectModelItem as ODataParameters; if (parameters != null) { this.VisitParameters(parameters); return; } ODataBatch batch = objectModelItem as ODataBatch; if (batch != null) { this.VisitBatch(batch); return; } ODataBatchChangeset batchChangeset = objectModelItem as ODataBatchChangeset; if (batchChangeset != null) { this.VisitBatchChangeset(batchChangeset); return; } ODataBatchRequestOperation batchRequestOperation = objectModelItem as ODataBatchRequestOperation; if (batchRequestOperation != null) { this.VisitBatchRequestOperation(batchRequestOperation); return; } ODataBatchResponseOperation batchResponseOperation = objectModelItem as ODataBatchResponseOperation; if (batchResponseOperation != null) { this.VisitBatchResponseOperation(batchResponseOperation); return; } if (objectModelItem == null || objectModelItem.GetType().IsValueType || objectModelItem is string || objectModelItem is byte[] || objectModelItem is ISpatial) { this.VisitPrimitiveValue(objectModelItem); return; } this.VisitUnsupportedValue(objectModelItem); }
/// <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> /// Visits a resource collection. /// </summary> /// <param name="entitySetInfo">The resource collection to visit.</param> protected abstract T VisitResourceCollection(ODataEntitySetInfo entitySetInfo);
private static ODataServiceDocument CreateWorkspace(bool createMetadataFirst, string workspaceName = null, IEnumerable <CollectionInfo> incomingCollections = null, IEnumerable <SingletonInfo> incomingSingletons = null) { ODataServiceDocument serviceDocument = ObjectModelUtils.CreateDefaultWorkspace(); if (createMetadataFirst) { serviceDocument.SetAnnotation(new AtomWorkspaceMetadata()); } if (workspaceName != null) { AtomWorkspaceMetadata metadata = serviceDocument.Atom(); metadata.Title = new AtomTextConstruct { Text = workspaceName }; } if (incomingCollections != null) { var collections = new List <ODataEntitySetInfo>(); foreach (var collectionInfo in incomingCollections) { var collection = new ODataEntitySetInfo() { Url = new Uri(collectionInfo.Url, UriKind.RelativeOrAbsolute), Name = collectionInfo.Name, Title = collectionInfo.TitleAnnotation }; if (createMetadataFirst) { collection.SetAnnotation(new AtomResourceCollectionMetadata()); } if (collectionInfo.TitleAnnotation != null) { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = new AtomTextConstruct { Text = collectionInfo.TitleAnnotation }; } collections.Add(collection); } serviceDocument.EntitySets = collections; } if (incomingSingletons != null) { var singletons = new List <ODataSingletonInfo>(); foreach (var singletonInfo in incomingSingletons) { var singleton = new ODataSingletonInfo() { Url = new Uri(singletonInfo.Url, UriKind.RelativeOrAbsolute), Name = singletonInfo.Name, Title = singletonInfo.TitleAnnotation }; if (createMetadataFirst) { singleton.SetAnnotation(new AtomResourceCollectionMetadata()); } singletons.Add(singleton); } serviceDocument.Singletons = singletons; } return(serviceDocument); }
/// <summary> /// Visits a entity set. /// </summary> /// <param name="entitySetInfo">The entity set to visit.</param> protected override void VisitEntitySet(ODataEntitySetInfo entitySetInfo) { this.VisitAtomMetadata(entitySetInfo.GetAnnotation <AtomResourceCollectionMetadata>()); base.VisitEntitySet(entitySetInfo); }
/// <summary> /// Writes the ATOM metadata for a single entity set element. /// </summary> /// <param name="entitySetInfo">The entity set element to get the metadata for and write it.</param> internal void WriteEntitySetInfoMetadata(ODataEntitySetInfo entitySetInfo) { Debug.Assert(entitySetInfo != null, "collection != null"); Debug.Assert(entitySetInfo.Url != null, "collection.Url should have been validated at this point"); AtomResourceCollectionMetadata metadata = entitySetInfo.GetAnnotation<AtomResourceCollectionMetadata>(); AtomTextConstruct title = null; if (metadata != null) { title = metadata.Title; } if (entitySetInfo.Name != null) { if (title == null) { title = new AtomTextConstruct { Text = entitySetInfo.Name }; } else if (string.CompareOrdinal(title.Text, entitySetInfo.Name) != 0) { throw new ODataException(ODataErrorStrings.ODataAtomServiceDocumentMetadataSerializer_ResourceCollectionNameAndTitleMismatch(entitySetInfo.Name, title.Text)); } } // The ATOMPUB specification requires a title. // <atom:title>title</atom:title> // Note that this will write an empty atom:title element even if the title is null. if (this.UseServerFormatBehavior && title.Kind == AtomTextConstructKind.Text) { // For WCF DS server we must not write the type attribute, just a simple <atom:title>title<atom:title> this.WriteElementWithTextContent( AtomConstants.NonEmptyAtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, title.Text); } else { this.WriteTextConstruct(AtomConstants.NonEmptyAtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, title); } if (metadata != null) { string accept = metadata.Accept; if (accept != null) { // <app:accept>accept</app:accept> this.WriteElementWithTextContent( string.Empty, AtomConstants.AtomPublishingAcceptElementName, AtomConstants.AtomPublishingNamespace, accept); } AtomCategoriesMetadata categories = metadata.Categories; if (categories != null) { // <app:categories> this.XmlWriter.WriteStartElement(string.Empty, AtomConstants.AtomPublishingCategoriesElementName, AtomConstants.AtomPublishingNamespace); Uri href = categories.Href; bool? fixedValue = categories.Fixed; string scheme = categories.Scheme; IEnumerable<AtomCategoryMetadata> categoriesCollection = categories.Categories; if (href != null) { // Out of line categories document if (fixedValue.HasValue || scheme != null || (categoriesCollection != null && categoriesCollection.Any())) { throw new ODataException(ODataErrorStrings.ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues); } this.XmlWriter.WriteAttributeString(AtomConstants.AtomHRefAttributeName, this.UriToUrlAttributeValue(href)); } else { // Inline categories document // fixed='yes|no' if (fixedValue.HasValue) { this.XmlWriter.WriteAttributeString( AtomConstants.AtomPublishingFixedAttributeName, fixedValue.Value ? AtomConstants.AtomPublishingFixedYesValue : AtomConstants.AtomPublishingFixedNoValue); } // scheme='scheme' if (scheme != null) { this.XmlWriter.WriteAttributeString(AtomConstants.AtomCategorySchemeAttributeName, scheme); } if (categoriesCollection != null) { foreach (AtomCategoryMetadata category in categoriesCollection) { // <atom:category/> this.WriteCategory(AtomConstants.NonEmptyAtomNamespacePrefix, category.Term, category.Scheme, category.Label); } } } // </app:categories> this.XmlWriter.WriteEndElement(); } } }
public void AtomResourceCollectionMetadataTest() { var testCases = new[] { // No title specified - an empty one is used as it's required by the spec. new { CustomizeMetadata = (Action <ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); }), Xml = "<Collection><title xmlns='http://www.w3.org/2005/Atom'/></Collection>" }, // Simple title (other titles are tested in AtomTextConstructMetadataTests) new { CustomizeMetadata = (Action <ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = new AtomTextConstruct { Text = "collection title" }; }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title></Collection>" }, // With accept new { CustomizeMetadata = (Action <ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Accept = "mime/type"; }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><accept xmlns='http://www.w3.org/2007/app'>mime/type</accept></Collection>" }, // With empty accept new { CustomizeMetadata = (Action <ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Accept = string.Empty; }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><accept xmlns='http://www.w3.org/2007/app'></accept></Collection>" }, // With categories new { CustomizeMetadata = (Action <ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Categories = new AtomCategoriesMetadata(); }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><categories xmlns='http://www.w3.org/2007/app' /></Collection>" }, // With accept and categories new { CustomizeMetadata = (Action <ODataEntitySetInfo>)(collection => { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = "collection title"; metadata.Accept = "mime/type"; metadata.Categories = new AtomCategoriesMetadata(); }), Xml = "<Collection><title type='text' xmlns='http://www.w3.org/2005/Atom'>collection title</title><accept xmlns='http://www.w3.org/2007/app'>mime/type</accept><categories xmlns='http://www.w3.org/2007/app' /></Collection>" }, }; Func <ODataEntitySetInfo>[] collectionCreators = new Func <ODataEntitySetInfo>[] { () => new ODataEntitySetInfo { Url = new Uri("http://odata.org/url") }, () => { var collection = new ODataEntitySetInfo { Url = new Uri("http://odata.org/url") }; collection.SetAnnotation(new AtomResourceCollectionMetadata()); return(collection); } }; var testDescriptors = testCases.SelectMany(testCase => collectionCreators.Select(collectionCreator => { ODataEntitySetInfo collection = collectionCreator(); testCase.CustomizeMetadata(collection); ODataServiceDocument serviceDocument = new ODataServiceDocument { EntitySets = new[] { collection } }; return(new PayloadWriterTestDescriptor <ODataServiceDocument>( this.Settings, new[] { serviceDocument }, tc => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, FragmentExtractor = result => new XElement("Collection", result .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingWorkspaceElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCollectionElementName) .Elements()) })); })); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyTopLevelContent( testDescriptor, testConfiguration, (messageWriter) => messageWriter.WriteServiceDocument(testDescriptor.PayloadItems.Single()), this.Assert, baselineLogger: this.Logger); }); }
/// <summary> /// Writes the ATOM metadata for a single entity set element. /// </summary> /// <param name="entitySetInfo">The entity set element to get the metadata for and write it.</param> internal void WriteEntitySetInfoMetadata(ODataEntitySetInfo entitySetInfo) { Debug.Assert(entitySetInfo != null, "collection != null"); Debug.Assert(entitySetInfo.Url != null, "collection.Url should have been validated at this point"); AtomResourceCollectionMetadata metadata = entitySetInfo.GetAnnotation <AtomResourceCollectionMetadata>(); AtomTextConstruct title = null; if (metadata != null) { title = metadata.Title; } if (entitySetInfo.Name != null) { if (title == null) { title = new AtomTextConstruct { Text = entitySetInfo.Name }; } else if (string.CompareOrdinal(title.Text, entitySetInfo.Name) != 0) { throw new ODataException(ODataErrorStrings.ODataAtomServiceDocumentMetadataSerializer_ResourceCollectionNameAndTitleMismatch(entitySetInfo.Name, title.Text)); } } // The ATOMPUB specification requires a title. // <atom:title>title</atom:title> // Note that this will write an empty atom:title element even if the title is null. if (this.UseServerFormatBehavior && title.Kind == AtomTextConstructKind.Text) { // For WCF DS server we must not write the type attribute, just a simple <atom:title>title<atom:title> this.WriteElementWithTextContent( AtomConstants.NonEmptyAtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, title.Text); } else { this.WriteTextConstruct(AtomConstants.NonEmptyAtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, title); } if (metadata != null) { string accept = metadata.Accept; if (accept != null) { // <app:accept>accept</app:accept> this.WriteElementWithTextContent( string.Empty, AtomConstants.AtomPublishingAcceptElementName, AtomConstants.AtomPublishingNamespace, accept); } AtomCategoriesMetadata categories = metadata.Categories; if (categories != null) { // <app:categories> this.XmlWriter.WriteStartElement(string.Empty, AtomConstants.AtomPublishingCategoriesElementName, AtomConstants.AtomPublishingNamespace); Uri href = categories.Href; bool? fixedValue = categories.Fixed; string scheme = categories.Scheme; IEnumerable <AtomCategoryMetadata> categoriesCollection = categories.Categories; if (href != null) { // Out of line categories document if (fixedValue.HasValue || scheme != null || (categoriesCollection != null && categoriesCollection.Any())) { throw new ODataException(ODataErrorStrings.ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues); } this.XmlWriter.WriteAttributeString(AtomConstants.AtomHRefAttributeName, this.UriToUrlAttributeValue(href)); } else { // Inline categories document // fixed='yes|no' if (fixedValue.HasValue) { this.XmlWriter.WriteAttributeString( AtomConstants.AtomPublishingFixedAttributeName, fixedValue.Value ? AtomConstants.AtomPublishingFixedYesValue : AtomConstants.AtomPublishingFixedNoValue); } // scheme='scheme' if (scheme != null) { this.XmlWriter.WriteAttributeString(AtomConstants.AtomCategorySchemeAttributeName, scheme); } if (categoriesCollection != null) { foreach (AtomCategoryMetadata category in categoriesCollection) { // <atom:category/> this.WriteCategory(AtomConstants.NonEmptyAtomNamespacePrefix, category.Term, category.Scheme, category.Label); } } } // </app:categories> this.XmlWriter.WriteEndElement(); } } }
private static ODataServiceDocument CreateWorkspace(bool createMetadataFirst, string workspaceName = null, IEnumerable<CollectionInfo> incomingCollections = null, IEnumerable<SingletonInfo> incomingSingletons = null) { ODataServiceDocument serviceDocument = ObjectModelUtils.CreateDefaultWorkspace(); if (createMetadataFirst) { serviceDocument.SetAnnotation(new AtomWorkspaceMetadata()); } if (workspaceName != null) { AtomWorkspaceMetadata metadata = serviceDocument.Atom(); metadata.Title = new AtomTextConstruct { Text = workspaceName }; } if (incomingCollections != null) { var collections = new List<ODataEntitySetInfo>(); foreach (var collectionInfo in incomingCollections) { var collection = new ODataEntitySetInfo() { Url = new Uri(collectionInfo.Url, UriKind.RelativeOrAbsolute), Name = collectionInfo.Name, Title = collectionInfo.TitleAnnotation}; if (createMetadataFirst) { collection.SetAnnotation(new AtomResourceCollectionMetadata()); } if (collectionInfo.TitleAnnotation != null) { AtomResourceCollectionMetadata metadata = collection.Atom(); metadata.Title = new AtomTextConstruct { Text = collectionInfo.TitleAnnotation }; } collections.Add(collection); } serviceDocument.EntitySets = collections; } if (incomingSingletons != null) { var singletons = new List<ODataSingletonInfo>(); foreach (var singletonInfo in incomingSingletons) { var singleton = new ODataSingletonInfo() { Url = new Uri(singletonInfo.Url, UriKind.RelativeOrAbsolute), Name = singletonInfo.Name, Title = singletonInfo.TitleAnnotation }; if (createMetadataFirst) { singleton.SetAnnotation(new AtomResourceCollectionMetadata()); } singletons.Add(singleton); } serviceDocument.Singletons = singletons; } return serviceDocument; }
/// <summary> /// Visits a resource collection. /// </summary> /// <param name="entitySetInfo">The resource collection to visit.</param> protected override ODataPayloadElement VisitResourceCollection(ODataEntitySetInfo entitySetInfo) { ExceptionUtilities.CheckArgumentNotNull(entitySetInfo, "entitySetInfo"); ResourceCollectionInstance collectionInstance = (ResourceCollectionInstance)base.VisitResourceCollection(entitySetInfo); AtomResourceCollectionMetadata atomMetadata = entitySetInfo.GetAnnotation<AtomResourceCollectionMetadata>(); if (atomMetadata != null) { if (atomMetadata.Title != null) { collectionInstance.Title = atomMetadata.Title.Text; collectionInstance.AtomTitle(atomMetadata.Title.Text, ToString(atomMetadata.Title.Kind)); } if (atomMetadata.Accept != null) { collectionInstance.AppAccept(atomMetadata.Accept); } if (atomMetadata.Categories != null) { if (atomMetadata.Categories.Href != null) { collectionInstance.AppOutOfLineCategories(atomMetadata.Categories.Href.OriginalString); } else { collectionInstance.AppInlineCategories( atomMetadata.Categories.Fixed == null ? null : (atomMetadata.Categories.Fixed.Value ? TestAtomConstants.AtomPublishingFixedYesValue : TestAtomConstants.AtomPublishingFixedNoValue), atomMetadata.Categories.Scheme, atomMetadata.Categories.Categories == null ? new XmlTreeAnnotation[0] : atomMetadata.Categories.Categories.Select(category => AtomMetadataBuilder.AtomCategory(category.Term, category.Scheme, category.Label)).ToArray()); } } } return collectionInstance; }
/// <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); }
public void CategoryMetadataOnWorkspaceCollectionCategoriesWriterTest() { var testCases = this.CreateAtomCategoryTestCases(); // Convert test cases to test descriptions var testDescriptors = testCases.Select(testCase => { AtomResourceCollectionMetadata metadata = new AtomResourceCollectionMetadata { Categories = new AtomCategoriesMetadata { Categories = new[] { testCase.Category } } }; ODataEntitySetInfo collection = new ODataEntitySetInfo { Url = new Uri("http://odata.org/collection") }; collection.SetAnnotation(metadata); ODataServiceDocument serviceDocument = new ODataServiceDocument { EntitySets = new[] { collection } }; return new PayloadWriterTestDescriptor<ODataServiceDocument>( this.Settings, serviceDocument, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, ExpectedException2 = testCase.ExpectedException, FragmentExtractor = result => result .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingWorkspaceElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCollectionElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCategoriesElementName) .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomCategoryElementName) }); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyTopLevelContent( testDescriptor, testConfiguration, (messageWriter) => messageWriter.WriteServiceDocument(testDescriptor.PayloadItems.Single()), this.Assert, baselineLogger:this.Logger); }); }
/// <summary> /// Visits an item in the object model. /// </summary> /// <param name="objectModelItem">The item to visit.</param> public virtual T Visit(object objectModelItem) { ODataResourceSet feed = objectModelItem as ODataResourceSet; if (feed != null) { return(this.VisitFeed(feed)); } ODataResource entry = objectModelItem as ODataResource; if (entry != null) { return(this.VisitEntry(entry)); } ODataProperty property = objectModelItem as ODataProperty; if (property != null) { return(this.VisitProperty(property)); } ODataNestedResourceInfo navigationLink = objectModelItem as ODataNestedResourceInfo; if (navigationLink != null) { return(this.VisitNavigationLink(navigationLink)); } ODataResourceValue resourceValue = objectModelItem as ODataResourceValue; if (resourceValue != null) { return(this.VisitResourceValue(resourceValue)); } ODataCollectionValue collection = objectModelItem as ODataCollectionValue; if (collection != null) { return(this.VisitCollectionValue(collection)); } ODataStreamReferenceValue streamReferenceValue = objectModelItem as ODataStreamReferenceValue; if (streamReferenceValue != null) { return(this.VisitStreamReferenceValue(streamReferenceValue)); } ODataCollectionStart collectionStart = objectModelItem as ODataCollectionStart; if (collectionStart != null) { return(this.VisitCollectionStart(collectionStart)); } ODataServiceDocument serviceDocument = objectModelItem as ODataServiceDocument; if (serviceDocument != null) { return(this.VisitWorkspace(serviceDocument)); } ODataEntitySetInfo entitySetInfo = objectModelItem as ODataEntitySetInfo; if (entitySetInfo != null) { return(this.VisitResourceCollection(entitySetInfo)); } ODataError error = objectModelItem as ODataError; if (error != null) { return(this.VisitError(error)); } ODataInnerError innerError = objectModelItem as ODataInnerError; if (innerError != null) { return(this.VisitInnerError(innerError)); } ODataEntityReferenceLinks entityReferenceLinks = objectModelItem as ODataEntityReferenceLinks; if (entityReferenceLinks != null) { return(this.VisitEntityReferenceLinks(entityReferenceLinks)); } ODataEntityReferenceLink entityReferenceLink = objectModelItem as ODataEntityReferenceLink; if (entityReferenceLink != null) { return(this.VisitEntityReferenceLink(entityReferenceLink)); } ODataAction action = objectModelItem as ODataAction; if (action != null) { return(this.VisitODataOperation(action)); } ODataFunction function = objectModelItem as ODataFunction; if (function != null) { return(this.VisitODataOperation(function)); } ODataParameters parameters = objectModelItem as ODataParameters; if (parameters != null) { return(this.VisitParameters(parameters)); } ODataBatch batch = objectModelItem as ODataBatch; if (batch != null) { return(this.VisitBatch(batch)); } if (objectModelItem == null || objectModelItem is ODataPrimitiveValue || objectModelItem.GetType().IsValueType || objectModelItem is string || objectModelItem is byte[] || objectModelItem is ISpatial) { return(this.VisitPrimitiveValue(objectModelItem)); } if (objectModelItem is ODataUntypedValue) { object val = ODataObjectModelVisitor.ParseJsonToPrimitiveValue( (objectModelItem as ODataUntypedValue).RawValue); return(this.VisitPrimitiveValue(val)); } return(this.VisitUnsupportedValue(objectModelItem)); }
/// <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; }
public void AtomCategoriesMetadataTest() { var testCases = new [] { // Empty categories new { CategoriesMetadata = new AtomCategoriesMetadata(), Xml = "<categories xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with href new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href") }, Xml = "<categories href='http://odata.org/href' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with href and non-null empty categories (null and empty collection should be treated the same) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Categories = new AtomCategoryMetadata[0] }, Xml = "<categories href='http://odata.org/href' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with fixed yes new { CategoriesMetadata = new AtomCategoriesMetadata() { Fixed = true }, Xml = "<categories fixed='yes' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with fixed no new { CategoriesMetadata = new AtomCategoriesMetadata() { Fixed = false }, Xml = "<categories fixed='no' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with scheme new { CategoriesMetadata = new AtomCategoriesMetadata() { Scheme = "http://odata.org/scheme" }, Xml = "<categories scheme='http://odata.org/scheme' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with scheme and fixed new { CategoriesMetadata = new AtomCategoriesMetadata() { Fixed = true, Scheme = "http://odata.org/scheme" }, Xml = "<categories fixed='yes' scheme='http://odata.org/scheme' xmlns='http://www.w3.org/2007/app'/>", ExpectedException = (ExpectedException)null }, // Categories with single category new { CategoriesMetadata = new AtomCategoriesMetadata() { Categories = new [] { new AtomCategoryMetadata { Term = "myterm", Scheme = "http://odata.org/scheme" } } }, Xml = "<categories xmlns='http://www.w3.org/2007/app'><atom:category term='myterm' scheme='http://odata.org/scheme' xmlns:atom='http://www.w3.org/2005/Atom'/></categories>", ExpectedException = (ExpectedException)null }, // Categories with two categories new { CategoriesMetadata = new AtomCategoriesMetadata() { Categories = new [] { new AtomCategoryMetadata { Term = "myterm", Scheme = "http://odata.org/scheme" }, new AtomCategoryMetadata { Term = "second", Scheme = "http://odata.org/scheme2" } } }, Xml = "<categories xmlns='http://www.w3.org/2007/app'>" + "<atom:category term='myterm' scheme='http://odata.org/scheme' xmlns:atom='http://www.w3.org/2005/Atom'/>" + "<atom:category term='second' scheme='http://odata.org/scheme2' xmlns:atom='http://www.w3.org/2005/Atom'/>" + "</categories>", ExpectedException = (ExpectedException)null }, // Categories with href and fixed (error) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Fixed = true }, Xml = string.Empty, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues") }, // Categories with href and scheme (error) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Scheme = "http://odata.org/scheme" }, Xml = string.Empty, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues") }, // Categories with href and non-empty categories (error) new { CategoriesMetadata = new AtomCategoriesMetadata() { Href = new Uri("http://odata.org/href"), Categories = new [] { new AtomCategoryMetadata() } }, Xml = string.Empty, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_CategoriesHrefWithOtherValues") }, }; var testDescriptors = testCases.Select(testCase => { ODataEntitySetInfo collection = new ODataEntitySetInfo { Url = new Uri("http://odata.org/url") }; AtomResourceCollectionMetadata metadata = new AtomResourceCollectionMetadata() { Categories = testCase.CategoriesMetadata }; collection.SetAnnotation(metadata); ODataServiceDocument serviceDocument = new ODataServiceDocument { EntitySets = new [] { collection } }; return(new PayloadWriterTestDescriptor <ODataServiceDocument>( this.Settings, new [] { serviceDocument }, tc => { if (testCase.ExpectedException != null) { return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings) { ExpectedException2 = testCase.ExpectedException }; } else { return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, FragmentExtractor = result => result .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingWorkspaceElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCollectionElementName) .Element(TestAtomConstants.AtomPublishingXNamespace + TestAtomConstants.AtomPublishingCategoriesElementName) }; } })); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyTopLevelContent( testDescriptor, testConfiguration, (messageWriter) => messageWriter.WriteServiceDocument(testDescriptor.PayloadItems.Single()), this.Assert, baselineLogger: this.Logger); }); }