private void WriteStart(ODataWriter writer, ODataItem item) { var feed = item as ODataFeed; if (feed != null) { this.expectedStates.Add(ODataReaderState.FeedStart); writer.WriteStart(feed); return; } var entry = item as ODataEntry; if (entry != null) { this.expectedStates.Add(ODataReaderState.EntryStart); writer.WriteStart(entry); return; } var navLink = item as ODataNavigationLink; if (navLink != null) { this.expectedStates.Add(ODataReaderState.NavigationLinkStart); writer.WriteStart(navLink); } }
internal Scope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmStructuredType expectedResourceType, ODataUri odataUri) { Debug.Assert( state == ODataReaderState.Exception && item == null || state == ODataReaderState.ResourceStart && (item == null || item is ODataResource) || state == ODataReaderState.ResourceEnd && (item is ODataResource || item == null) || state == ODataReaderState.Primitive && (item == null || item is ODataPrimitiveValue) || state == ODataReaderState.ResourceSetStart && item is ODataResourceSet || state == ODataReaderState.ResourceSetEnd && item is ODataResourceSet || state == ODataReaderState.NestedResourceInfoStart && item is ODataNestedResourceInfo || state == ODataReaderState.NestedResourceInfoEnd && item is ODataNestedResourceInfo || state == ODataReaderState.EntityReferenceLink && item is ODataEntityReferenceLink || state == ODataReaderState.DeletedResourceStart && (item == null || item is ODataDeletedResource) || state == ODataReaderState.DeletedResourceEnd && (item is ODataDeletedResource || item == null) || state == ODataReaderState.DeltaResourceSetStart && item is ODataDeltaResourceSet || state == ODataReaderState.DeltaResourceSetEnd && item is ODataDeltaResourceSet || state == ODataReaderState.DeltaLink && (item == null || item is ODataDeltaLink) || state == ODataReaderState.DeltaDeletedLink && (item == null || item is ODataDeltaDeletedLink) || state == ODataReaderState.Start && item == null || state == ODataReaderState.Completed && item == null, "Reader state and associated item do not match."); this.state = state; this.item = item; this.ResourceType = expectedResourceType; this.NavigationSource = navigationSource; this.odataUri = odataUri; }
/// <summary> /// Replaces the current scope with a new scope; checks that the transition is valid. /// </summary> /// <param name="newState">The new state to transition into.</param> /// <param name="item">The item associated with the new state.</param> private void ReplaceScope(CollectionWriterState newState, ODataItem item) { this.ValidateTransition(newState); this.scopes.Pop(); this.scopes.Push(new Scope(newState, item)); this.NotifyListener(newState); }
private ODataItem QueryEntityItem(string uri, int expectedStatusCode = 200) { ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings() { BaseUri = ServiceBaseUri }; var queryRequestMessage = new HttpWebRequestMessage(new Uri(ServiceBaseUri.AbsoluteUri + uri, UriKind.Absolute)); queryRequestMessage.SetHeader("Accept", MimeTypes.ApplicationJsonLight); var queryResponseMessage = queryRequestMessage.GetResponse(); Assert.Equal(expectedStatusCode, queryResponseMessage.StatusCode); ODataItem item = null; if (expectedStatusCode == 200) { using (var messageReader = new ODataMessageReader(queryResponseMessage, readerSettings, Model)) { var reader = messageReader.CreateODataResourceReader(); while (reader.Read()) { if (reader.State == ODataReaderState.ResourceEnd) { item = reader.Item; } } Assert.Equal(ODataReaderState.Completed, reader.State); } } return(item); }
private void WriteEntry(ODataWriter writer, ODataItem entry) { ODataResource resource = entry as ODataResource; if (resource != null) { writer.WriteStart(resource); } else { writer.WritePrimitive((ODataPrimitiveValue)entry); } var annotation = entry.GetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(); ODataNestedResourceInfo navLink = null; if (annotation != null) { for (int i = 0; i < annotation.Count; ++i) { bool found = annotation.TryGetNavigationLinkAt(i, out navLink); ExceptionUtilities.Assert(found, "Navigation links should be ordered sequentially for writing"); this.WriteNavigationLink(writer, navLink); } } writer.WriteEnd(); }
private void WriteStart(ODataWriter writer, ODataItem item) { var feed = item as ODataResourceSet; if (feed != null) { this.expectedStates.Add(ODataReaderState.ResourceSetStart); writer.WriteStart(feed); return; } var entry = item as ODataResource; if (entry != null) { this.expectedStates.Add(ODataReaderState.ResourceStart); writer.WriteStart(entry); return; } var navLink = item as ODataNestedResourceInfo; if (navLink != null) { this.expectedStates.Add(ODataReaderState.NestedResourceInfoStart); writer.WriteStart(navLink); } }
internal Scope(ODataReaderState state, ODataItem item, ODataUri odataUri) { Debug.Assert( state == ODataReaderState.Exception && item == null || state == ODataReaderState.ResourceStart && (item == null || item is ODataResource) || state == ODataReaderState.ResourceEnd && (item is ODataResource || item == null) || state == ODataReaderState.Primitive && (item == null || item is ODataPrimitiveValue || item is ODataNullValue) || state == ODataReaderState.Stream && (item == null || item is ODataStreamItem) || state == ODataReaderState.NestedProperty && (item == null || item is ODataPropertyInfo) || state == ODataReaderState.ResourceSetStart && item is ODataResourceSet || state == ODataReaderState.ResourceSetEnd && item is ODataResourceSet || state == ODataReaderState.NestedResourceInfoStart && item is ODataNestedResourceInfo || state == ODataReaderState.NestedResourceInfoEnd && item is ODataNestedResourceInfo || state == ODataReaderState.EntityReferenceLink && item is ODataEntityReferenceLink || state == ODataReaderState.DeletedResourceStart && (item == null || item is ODataDeletedResource) || state == ODataReaderState.DeletedResourceEnd && (item is ODataDeletedResource || item == null) || state == ODataReaderState.DeltaResourceSetStart && item is ODataDeltaResourceSet || state == ODataReaderState.DeltaResourceSetEnd && item is ODataDeltaResourceSet || state == ODataReaderState.DeltaLink && (item == null || item is ODataDeltaLink) || state == ODataReaderState.DeltaDeletedLink && (item == null || item is ODataDeltaDeletedLink) || state == ODataReaderState.Start && item == null || state == ODataReaderState.Completed && item == null, "Reader state and associated item do not match."); this.state = state; this.item = item; this.odataUri = odataUri; }
public ODataVCardReader(VCardInputContext inputContext) { Debug.Assert(inputContext != null, "inputContext != null"); this.reader = inputContext.VCardReader; this.item = null; this.state = ODataReaderState.Start; this.throwExceptionOnDuplicatedPropertyNames = inputContext.ThrowExceptionOnDuplicatedPropertyNames; }
private bool ReadResourceFromRecord(object record) { this.item = ODataAvroConvert.ToODataEntry(record as AvroRecord); if (record == null) { this.state = ODataReaderState.Exception; return(false); } return(true); }
public ODataAvroReader(ODataAvroInputContext inputContext, bool readingFeed, object currentObject = null) { Debug.Assert(inputContext != null, "inputContext != null"); this.reader = inputContext.AvroReader; this.readingFeed = readingFeed; this.currentObject = currentObject; this.item = null; this.recordEnumerator = null; this.state = ODataReaderState.Start; }
protected static void AddChildInstanceAnnotations(ODataItem item, IList <object> childEntries) { var annotation = item.GetAnnotation <ChildInstanceAnnotation>(); if (annotation == null) { annotation = new ChildInstanceAnnotation { ChildInstances = childEntries }; item.SetAnnotation(annotation); } }
private void AddBoundNavigationPropertyAnnotation(ODataItem item, ODataNestedResourceInfo navigationLink, object boundValue) { var annotation = item.GetAnnotation <BoundNavigationPropertyAnnotation>(); if (annotation == null) { annotation = new BoundNavigationPropertyAnnotation { BoundProperties = new List <Tuple <ODataNestedResourceInfo, object> >() }; item.SetAnnotation(annotation); } annotation.BoundProperties.Add(new Tuple <ODataNestedResourceInfo, object>(navigationLink, boundValue)); }
private void AddChildInstanceAnnotation(ODataItem item, object childEntry) { var annotation = item.GetAnnotation <ChildInstanceAnnotation>(); if (annotation == null) { annotation = new ChildInstanceAnnotation { ChildInstances = new List <object>() }; item.SetAnnotation(annotation); } annotation.ChildInstances.Add(childEntry); }
public void FeedInvalidContentTests() { ODataFeed defaultFeed = ObjectModelUtils.CreateDefaultFeed(); ODataItem[] invalidPayload1 = new ODataItem[] { defaultFeed, defaultFeed }; var testCases = new[] { new { Items = invalidPayload1, ExpectedError = "Cannot transition from state 'Feed' to state 'Feed'. The only valid action in state 'Feed' is to write an entry." } }; this.CombinatorialEngineProvider.RunCombinations( testCases, ODataFormatUtils.ODataFormats.Where(f => f != null), // Async test configuration is not supported for Phone and Silverlight #if !SILVERLIGHT && !WINDOWS_PHONE new bool[] { false, true }, #else new bool[] { true }, #endif (testCase, format, synchronous) => { using (var memoryStream = new TestStream()) { ODataMessageWriterSettings settings = new ODataMessageWriterSettings(); settings.Version = ODataVersion.V4; settings.SetServiceDocumentUri(ServiceDocumentUri); using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, new WriterTestConfiguration(format, settings, false, synchronous), this.Assert)) { ODataWriter writer = messageWriter.CreateODataWriter(isFeed: true); TestExceptionUtils.ExpectedException <ODataException>( this.Assert, () => TestWriterUtils.WritePayload(messageWriter, writer, true, testCase.Items), testCase.ExpectedError); } } }); }
private void WriteEntry(ODataWriter writer, Lazy <ODataReader> lazyReader, ODataItem entry) { this.WriteStart(writer, entry); var annotation = entry.GetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(); ODataNestedResourceInfo navLink = null; if (annotation != null) { for (int i = 0; i < annotation.Count; ++i) { bool found = annotation.TryGetNavigationLinkAt(i, out navLink); ExceptionUtilities.Assert(found, "Navigation links should be ordered sequentially for writing"); this.WriteNavigationLink(writer, lazyReader, navLink); } } this.WriteEnd(writer, ODataReaderState.ResourceEnd); this.Read(lazyReader); }
private bool DefaultRead() { if (this.enumerator == null) { this.enumerator = this.items.GetEnumerator(); } bool hasRead = this.enumerator.MoveNext(); if (hasRead) { this.currentState = this.enumerator.Current.State; this.currentItem = this.enumerator.Current.Item; } else { this.currentState = ODataReaderState.Completed; this.currentItem = null; } return hasRead; }
internal Scope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType expectedEntityType, ODataUri odataUri) { Debug.Assert( state == ODataReaderState.Exception && item == null || state == ODataReaderState.EntryStart && (item == null || item is ODataEntry) || state == ODataReaderState.EntryEnd && (item == null || item is ODataEntry) || state == ODataReaderState.FeedStart && item is ODataFeed || state == ODataReaderState.FeedEnd && item is ODataFeed || state == ODataReaderState.NavigationLinkStart && item is ODataNavigationLink || state == ODataReaderState.NavigationLinkEnd && item is ODataNavigationLink || state == ODataReaderState.EntityReferenceLink && item is ODataEntityReferenceLink || state == ODataReaderState.Start && item == null || state == ODataReaderState.Completed && item == null, "Reader state and associated item do not match."); this.state = state; this.item = item; this.EntityType = expectedEntityType; this.NavigationSource = navigationSource; this.odataUri = odataUri; }
private bool DefaultRead() { if (this.enumerator == null) { this.enumerator = this.items.GetEnumerator(); } bool hasRead = this.enumerator.MoveNext(); if (hasRead) { this.currentState = this.enumerator.Current.State; this.currentItem = this.enumerator.Current.Item; } else { this.currentState = ODataReaderState.Completed; this.currentItem = null; } return(hasRead); }
public static Scope Create(WriterState state, ODataItem item) { Debug.Assert( state == WriterState.Error || state == WriterState.ODataExceptionThrown || state == WriterState.FatalExceptionThrown || state == WriterState.Entry && item is ODataEntry || state == WriterState.Feed && item is ODataFeed || state == WriterState.Link && item is ODataLink || state == WriterState.ExpandedLink && item is ODataLink || state == WriterState.Start && item == null || state == WriterState.Completed && item == null, "Writer state and associated item do not match."); switch (state) { case WriterState.Entry: return(new EntryScope(state, (ODataEntry)item)); case WriterState.Feed: return(new FeedScope(state, (ODataFeed)item)); case WriterState.Start: // fall through case WriterState.Link: // fall through case WriterState.ExpandedLink: // fall through case WriterState.Completed: // fall through case WriterState.ODataExceptionThrown: // fall through case WriterState.FatalExceptionThrown: // fall through case WriterState.Error: return(new Scope(state, item)); default: string errorMessage = Strings.General_InternalError(InternalErrorCodes.ODataWriterCore_Scope_Create_UnreachableCodePath); Debug.Assert(false, errorMessage); throw new ODataException(errorMessage); } }
public void WritingNestedInlinecountTest() { ODataFeed feed = new ODataFeed { Count = 1 }; ODataItem[] itemsToWrite = new ODataItem[] { new ODataFeed(), this.entryWithOnlyData1, this.containedCollectionNavLink, feed }; string resourcePath = "EntitySet"; string result = this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, Model, EntitySet, EntityType, null, null, resourcePath); string expectedPayload = "{" + "\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet\"," + "\"value\":[" + "{" + "\"ID\":101,\"Name\":\"Alice\"," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedCollectionNavProp\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"[email protected]\":1," + "\"ContainedCollectionNavProp\":[]" + "}" + "]" + "}"; result.Should().Be(expectedPayload); }
public void WritingEntryExpandWithMixedCollectionAndNonCollectionContainedElementWithTypeCast() { ODataItem[] itemsToWrite = new ODataItem[] { this.entryWithOnlyData1, this.containedCollectionNavLink, new ODataFeed(), this.entryWithOnlyData2, this.containedNavLink, this.entryWithOnlyData3, }; const string selectClause = "Namespace.DerivedType/ContainedCollectionNavProp"; const string expandClause = "Namespace.DerivedType/ContainedCollectionNavProp($select=ContainedNavProp;$expand=ContainedNavProp)"; string result = this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, Model, EntitySet, EntityType, selectClause, expandClause, "EntitySet(101)"); string expectedPayload = "{\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet(Namespace.DerivedType/ContainedCollectionNavProp,Namespace.DerivedType/ContainedCollectionNavProp(ContainedNavProp))/$entity\"," + "\"ID\":101,\"Name\":\"Alice\"," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/Namespace.DerivedType/ContainedCollectionNavProp(ContainedNavProp)\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"ContainedCollectionNavProp\":" + "[" + "{" + "\"ID\":102,\"Name\":\"Bob\"," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/Namespace.DerivedType/ContainedCollectionNavProp(102)/ContainedNavProp/$entity\"," + "\"ContainedNavProp\":" + "{" + "\"ID\":103,\"Name\":\"Charlie\"" + "}" + "}" + "]" + "}"; result.Should().Be(expectedPayload); }
public void WritingTopLevelContainedEntryWithTypeCast() { ODataItem[] itemsToWrite = new ODataItem[] { this.entryWithOnlyData2 }; IEdmNavigationProperty containedNavProp = EntityType.FindProperty("ContainedNavProp") as IEdmNavigationProperty; IEdmEntitySetBase contianedEntitySet = EntitySet.FindNavigationTarget(containedNavProp) as IEdmEntitySetBase; string resourcePath = "EntitySet(123)/ContainedNavProp/Namespace.DerivedType"; string result = this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, Model, contianedEntitySet, DerivedType, null, null, resourcePath); string expectedPayload = "{\"" + "@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet(123)/ContainedNavProp/Namespace.DerivedType/$entity\"," + "\"ID\":102,\"Name\":\"Bob\"" + "}"; result.Should().Be(expectedPayload); }
private void WriteEntry(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx) { if (currentIdx < itemsToWrite.Length) { ODataEntry entry = (ODataEntry)itemsToWrite[currentIdx++]; writer.WriteStart(entry); while (currentIdx < itemsToWrite.Length) { if (itemsToWrite[currentIdx] is ODataNavigationLink) { this.WriteLink(writer, itemsToWrite, ref currentIdx); } else if (itemsToWrite[currentIdx] is ODataNavigationLinkEnd) { currentIdx++; writer.WriteEnd(); return; } else { break; } } writer.WriteEnd(); } }
public StackItem(ODataItem item) { _item = item; _navigationProperties = new List <NavigationInfo>(); }
internal Scope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmTypeReference expectedResourceTypeReference, ODataUri odataUri) : this(state, item, odataUri) { this.NavigationSource = navigationSource; this.ResourceTypeReference = expectedResourceTypeReference; }
private void WriteResponseWithoutModelAndValidatePayload(ODataItem[] nestedItemToWrite, string expectedPayload, bool setMetadataDocumentUri = true) { // without model, write response var stream = new MemoryStream(); var outputContext = CreateAtomOutputContext(stream, null, true, null); var writer = new ODataAtomWriter(outputContext, null, null, nestedItemToWrite[0] is ODataFeed); WriteNestedItems(nestedItemToWrite, writer); ValidateWrittenPayload(stream, writer, expectedPayload); }
/// <summary> /// Create a new delta feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly create scope.</returns> private DeltaFeedScope CreateDeltaFeedScope(ODataItem feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightDeltaFeedScope(feed, navigationSource, entityType, selectedProperties, odataUri); }
public void AssociationLinkTest() { string associationLinkName1 = "AssociationLinkOne"; string linkUrl1 = "http://odata.org/associationlink"; Uri linkUrlUri1 = new Uri(linkUrl1); string associationLinkName2 = "AssociationLinkTwo"; string linkUrl2 = "http://odata.org/associationlink2"; Uri linkUrlUri2 = new Uri(linkUrl2); EdmModel model = new EdmModel(); var edmEntityTypeOrderType = new EdmEntityType("TestModel", "OrderType"); model.AddElement(edmEntityTypeOrderType); var edmEntityTypeCustomerType = new EdmEntityType("TestModel", "CustomerType"); var edmNavigationPropertyAssociationLinkOne = edmEntityTypeCustomerType.AddUnidirectionalNavigation( new EdmNavigationPropertyInfo { Name = associationLinkName1, Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.One }); var edmNavigationPropertyAssociationLinkTwo = edmEntityTypeCustomerType.AddUnidirectionalNavigation( new EdmNavigationPropertyInfo { Name = associationLinkName2, Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.Many }); model.AddElement(edmEntityTypeCustomerType); var container = new EdmEntityContainer("TestModel", "Default"); model.AddElement(container); var customerSet = container.AddEntitySet("Customers", edmEntityTypeCustomerType); var orderSet = container.AddEntitySet("Orders", edmEntityTypeOrderType); customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkOne, orderSet); customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkTwo, orderSet); var testCases = new[] { new { NavigationLink = ObjectModelUtils.CreateDefaultNavigationLink(associationLinkName1, linkUrlUri1), Atom = BuildXmlAssociationLink(associationLinkName1, "application/xml", linkUrl1), JsonLight = (string)null, }, new { NavigationLink = ObjectModelUtils.CreateDefaultNavigationLink(associationLinkName2, linkUrlUri2), Atom = BuildXmlAssociationLink(associationLinkName2, "application/xml", linkUrl2), JsonLight = (string)null }, }; var testCasesWithMultipleLinks = testCases.Variations() .Select(tcs => new { NavigationLinks = tcs.Select(tc => tc.NavigationLink), Atom = string.Concat(tcs.Select(tc => tc.Atom)), JsonLight = string.Join(",", tcs.Where(tc => tc.JsonLight != null).Select(tc => tc.JsonLight)) }); var testDescriptors = testCasesWithMultipleLinks.Select(testCase => { ODataResource entry = ObjectModelUtils.CreateDefaultEntry(); entry.TypeName = "TestModel.CustomerType"; List <ODataItem> items = new ODataItem[] { entry }.ToList(); foreach (var navLink in testCase.NavigationLinks) { items.Add(navLink); items.Add(null); } return(new PayloadWriterTestDescriptor <ODataItem>( this.Settings, items, (testConfiguration) => { var firstAssocLink = testCase.NavigationLinks == null ? null : testCase.NavigationLinks.FirstOrDefault(); if (testConfiguration.Format == ODataFormat.Json) { return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = string.Join( "$(NL)", "{", testCase.JsonLight, "}"), FragmentExtractor = (result) => { var associationLinks = result.Object().GetAnnotationsWithName("@" + JsonLightConstants.ODataAssociationLinkUrlAnnotationName).ToList(); var jsonResult = new JsonObject(); associationLinks.ForEach(l => { // NOTE we remove all annoatations here and in particular the text annotations to be able to easily compare // against the expected results. This however means that we do not distinguish between the indented and non-indented case here. l.RemoveAllAnnotations(true); jsonResult.Add(l); }); return jsonResult; }, }; } else { this.Settings.Assert.Fail("Unknown format '{0}'.", testConfiguration.Format); return null; } }) { Model = model, PayloadEdmElementContainer = customerSet }); }); // With and without model testDescriptors = testDescriptors.SelectMany(td => new[] { td, new PayloadWriterTestDescriptor <ODataItem>(td) { Model = null, PayloadEdmElementContainer = null } }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.EntryPayloads), this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent, (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); if (testDescriptor.Model == null && testConfiguration.Format == ODataFormat.Json) { return; } if (testDescriptor.IsGeneratedPayload && testDescriptor.Model != null) { return; } TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
public override bool Read() { switch (this.state) { case ODataReaderState.Start: if (this.currentObject == null) { if (!this.reader.MoveNext()) { this.state = ODataReaderState.Exception; return(false); } this.currentObject = this.reader.Current; } this.state = readingFeed ? ODataReaderState.FeedStart : ODataReaderState.EntryStart; break; case ODataReaderState.FeedStart: this.item = new ODataFeed(); var objs = this.currentObject as object[]; if (objs == null) { this.state = ODataReaderState.Exception; return(false); } this.recordEnumerator = objs.GetEnumerator(); this.state = (this.recordEnumerator.MoveNext()) ? ODataReaderState.EntryStart : ODataReaderState.FeedEnd; break; case ODataReaderState.FeedEnd: this.state = ODataReaderState.Completed; return(false); case ODataReaderState.EntryStart: var record = (this.readingFeed ? this.recordEnumerator.Current : this.currentObject) as AvroRecord; if (record == null) { this.state = ODataReaderState.Exception; return(false); } this.item = ODataAvroConvert.ToODataEntry(record); this.state = ODataReaderState.EntryEnd; return(true); case ODataReaderState.EntryEnd: if (!readingFeed) { this.state = ODataReaderState.Completed; return(false); } this.state = this.recordEnumerator.MoveNext() ? ODataReaderState.EntryStart : ODataReaderState.FeedEnd; break; default: throw new ApplicationException("Invalid state"); } return(true); }
internal AtomScope(ODataReaderState state, ODataItem item, IEdmEntityType expectedEntityType) : base(state, item, expectedEntityType) { }
/// <summary> /// Constructor creating a new reader scope. /// </summary> /// <param name="state">The reader state of this scope.</param> /// <param name="item">The item attached to this scope.</param> /// <param name="navigationSource">The navigation source we are going to read entities for.</param> /// <param name="expectedResourceType">The expected resource type for the scope.</param> /// <param name="odataUri">The odataUri parsed based on the context uri for current scope</param> internal StreamScope(ODataReaderState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmTypeReference expectedResourceType, ODataUri odataUri) : base(state, item, navigationSource, expectedResourceType, odataUri) { this.StreamingState = StreamingState.None; }
private string GetWriterOutputForContentTypeAndKnobValue( string contentType, bool autoComputePayloadMetadataInJson, ODataItem[] itemsToWrite, EdmModel edmModel, IEdmEntitySetBase edmEntitySet, EdmEntityType edmEntityType, string selectClause = null, string expandClause = null, string resourcePath = null, bool enableFullValidation = true) { MemoryStream outputStream = new MemoryStream(); IODataResponseMessage message = new InMemoryMessage() { Stream = outputStream }; message.SetHeader("Content-Type", contentType); ODataMessageWriterSettings settings = new ODataMessageWriterSettings() { AutoComputePayloadMetadataInJson = autoComputePayloadMetadataInJson, EnableFullValidation = enableFullValidation }; var result = new ODataQueryOptionParser(edmModel, edmEntityType, edmEntitySet, new Dictionary<string, string> { { "$expand", expandClause }, { "$select", selectClause } }).ParseSelectAndExpand(); ODataUri odataUri = new ODataUri() { ServiceRoot = new Uri("http://example.org/odata.svc"), SelectAndExpand = result }; if (resourcePath != null) { Uri requestUri = new Uri("http://example.org/odata.svc/" + resourcePath); odataUri.RequestUri = requestUri; odataUri.Path = new ODataUriParser(edmModel, new Uri("http://example.org/odata.svc/"), requestUri).ParsePath(); } settings.ODataUri = odataUri; string output; using (var messageWriter = new ODataMessageWriter(message, settings, edmModel)) { int currentIdx = 0; if (itemsToWrite[currentIdx] is ODataFeed) { ODataWriter writer = messageWriter.CreateODataFeedWriter(edmEntitySet, edmEntityType); this.WriteFeed(writer, itemsToWrite, ref currentIdx); } else if (itemsToWrite[currentIdx] is ODataEntry) { ODataWriter writer = messageWriter.CreateODataEntryWriter(edmEntitySet, edmEntityType); this.WriteEntry(writer, itemsToWrite, ref currentIdx); } else { Assert.True(false, "Top level item to write must be entry or feed."); } currentIdx.Should().Be(itemsToWrite.Length, "Invalid list of items to write."); outputStream.Seek(0, SeekOrigin.Begin); output = new StreamReader(outputStream).ReadToEnd(); } return output; }
/// <summary> /// Create a new delta link scope. /// </summary> /// <param name="state">The writer state of the scope to create.</param> /// <param name="link">The link for the new scope.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> /// <returns>The newly create scope.</returns> private DeltaLinkScope CreateDeltaLinkScope(WriterState state, ODataItem link, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { return new JsonLightDeltaLinkScope( state, link, this.GetLinkSerializationInfo(link), navigationSource, entityType, this.jsonLightOutputContext.MessageWriterSettings.WriterBehavior, selectedProperties, odataUri); }
private void WriteRequestWithModelAndValidatePayload(ODataItem[] nestedItemToWrite, string expectedPayload, bool setMetadataDocumentUri = true) { // with model, write request var stream = new MemoryStream(); var outputContext = CreateAtomOutputContext(stream, null, false, this.userModel); var writer = new ODataAtomWriter(outputContext, this.entitySet, this.entityType, nestedItemToWrite[0] is ODataFeed); WriteNestedItems(nestedItemToWrite, writer); ValidateWrittenPayload(stream, writer, expectedPayload); }
/// <summary> /// Gets the serialization info for the given delta entry. /// </summary> /// <param name="item">The entry to get the serialization info for.</param> /// <returns>The serialization info for the given entry.</returns> private ODataFeedAndEntrySerializationInfo GetEntrySerializationInfo(ODataItem item) { Debug.Assert(item != null, "item != null"); ODataFeedAndEntrySerializationInfo serializationInfo = null; var entry = item as ODataEntry; if (entry != null) { serializationInfo = entry.SerializationInfo; } var deltaDeletedEntry = item as ODataDeltaDeletedEntry; if (deltaDeletedEntry != null) { serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(deltaDeletedEntry.SerializationInfo); } if (serializationInfo == null) { serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(this.GetParentFeedSerializationInfo()); } return serializationInfo; }
/// <summary> /// Initializes a new instance of <see cref="ODataItemBase"/>. /// </summary> /// <param name="item">The wrapped item.</param> protected ODataItemBase(ODataItem item) { _item = item; }
public TestODataReaderItem(ODataReaderState state, ODataItem item) { this.State = state; this.Item = item; }
private void AddChildInstanceAnnotation(ODataItem item, object childEntry) { var annotation = item.GetAnnotation<ChildInstanceAnnotation>(); if (annotation == null) { annotation = new ChildInstanceAnnotation { ChildInstances = new List<object>() }; item.SetAnnotation(annotation); } annotation.ChildInstances.Add(childEntry); }
/// <summary> /// Constructor creating a new writer scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="item">The item attached to this scope.</param> protected Scope(WriterState state, ODataItem item) { this.state = state; this.item = item; }
private void WriteFeed(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx) { if (currentIdx < itemsToWrite.Length) { ODataFeed feed = (ODataFeed)itemsToWrite[currentIdx++]; writer.WriteStart(feed); while (currentIdx < itemsToWrite.Length && itemsToWrite[currentIdx] is ODataEntry) { this.WriteEntry(writer, itemsToWrite, ref currentIdx); } writer.WriteEnd(); } }
/// <summary> /// Constructor to create a new entry scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="entry">The entry for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected DeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, entry, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(entry != null, "entry != null"); Debug.Assert( state == WriterState.DeltaEntry && entry is ODataEntry || state == WriterState.DeltaDeletedEntry && entry is ODataDeltaDeletedEntry, "entry must be either DeltaEntry or DeltaDeletedEntry."); Debug.Assert(writerBehavior != null, "writerBehavior != null"); this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, /*writingResponse*/ true); this.serializationInfo = serializationInfo; }
private void WriteLink(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx) { if (currentIdx < itemsToWrite.Length) { ODataNavigationLink link = (ODataNavigationLink)itemsToWrite[currentIdx++]; writer.WriteStart(link); if (currentIdx < itemsToWrite.Length) { if (itemsToWrite[currentIdx] is ODataEntry) { this.WriteEntry(writer, itemsToWrite, ref currentIdx); } else if (itemsToWrite[currentIdx] is ODataFeed) { this.WriteFeed(writer, itemsToWrite, ref currentIdx); } } writer.WriteEnd(); } }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="item">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected DeltaFeedScope(ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(WriterState.DeltaFeed, item, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(item != null, "item != null"); var feed = item as ODataDeltaFeed; Debug.Assert(feed != null, "feed must be DeltaFeed."); this.serializationInfo = feed.SerializationInfo; }
public void WritingFeedWithFunctionAndAction() { ODataFeed feed = new ODataFeed(); feed.AddAction(new ODataAction { Metadata = new Uri("http://example.org/odata.svc/$metadata#Action"), Target = new Uri("http://example.org/odata.svc/DoAction"), Title = "ActionTitle" }); feed.AddFunction(new ODataFunction() { Metadata = new Uri("http://example.org/odata.svc/$metadata#Function"), Target = new Uri("http://example.org/odata.svc/DoFunction"), Title = "FunctionTitle" }); ODataItem[] itemsToWrite = new ODataItem[] { feed, this.entryWithOnlyData1, }; string result = this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, Model, EntitySet, EntityType); const string expectedPayload = "{\"" + "@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet\"," + "\"#Action\":{" + "\"title\":\"ActionTitle\"," + "\"target\":\"http://example.org/odata.svc/DoAction\"" + "}," + "\"#Function\":{" + "\"title\":\"FunctionTitle\"," + "\"target\":\"http://example.org/odata.svc/DoFunction\"" + "}," + "\"value\":[" + "{" + "\"ID\":101,\"Name\":\"Alice\"" + "}" + "]" + "}"; result.Should().Be(expectedPayload); }
/// <summary> /// Constructor to create a new delta link scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="link">The link for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> protected DeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, link, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(link != null, "link != null"); Debug.Assert( state == WriterState.DeltaLink && link is ODataDeltaLink || state == WriterState.DeltaDeletedLink && link is ODataDeltaDeletedLink, "link must be either DeltaLink or DeltaDeletedLink."); Debug.Assert(writerBehavior != null, "writerBehavior != null"); this.serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(serializationInfo); }
public void WritingEntryExpandWithMixedCollectionAndNonCollectionContainedElementAtSameLevel() { ODataItem[] itemsToWrite = new ODataItem[] { this.entryWithOnlyData1, this.expandedNavLink, this.entryWithOnlyData2, new ODataNavigationLinkEnd(), this.containedCollectionNavLink, new ODataFeed(), this.entryWithOnlyData2, new ODataNavigationLinkEnd(), this.containedNavLink, this.entryWithOnlyData3, }; const string selectClause = "ID,Name"; const string expandClause = "ExpandedNavProp,ContainedCollectionNavProp($select=ID),ContainedNavProp($select=ID,Name)"; string result = this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, Model, EntitySet, EntityType, selectClause, expandClause, "EntitySet(101)"); string expectedPayload = "{\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet(ID,Name,ExpandedNavProp,ContainedCollectionNavProp,ContainedNavProp,ContainedCollectionNavProp(ID),ContainedNavProp(ID,Name))/$entity\"," + "\"ID\":101,\"Name\":\"Alice\"," + "\"ExpandedNavProp\":{\"ID\":102,\"Name\":\"Bob\"}," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedCollectionNavProp(ID)\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"ContainedCollectionNavProp\":[" + "{\"ID\":102,\"Name\":\"Bob\"}" + "]," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedNavProp(ID,Name)/$entity\"," + "\"ContainedNavProp\":{\"ID\":103,\"Name\":\"Charlie\"}" + "}"; result.Should().Be(expectedPayload); }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal JsonLightDeltaFeedScope(ODataItem feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(feed, navigationSource, entityType, selectedProperties, odataUri) { }
public void ShouldWriteNestedContextUrlIfCanNotBeInferred() { var entryWithOnlyData2WithSerializationInfo = new ODataEntry { Properties = new[] { new ODataProperty { Name = "ID", Value = 102 }, new ODataProperty { Name = "Name", Value = "Bob" } }, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceName = "FooSet", NavigationSourceEntityTypeName = "NS.BarType" }, }; ODataItem[] itemsToWrite = new ODataItem[] { this.entryWithOnlyData1, this.containedCollectionNavLink, new ODataFeed(), entryWithOnlyData2WithSerializationInfo, }; const string selectClause = "ContainedNavProp"; const string expandClause = "ContainedNavProp"; string result = this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, Model, EntitySet, EntityType, selectClause, expandClause, "EntitySet"); string expectedPayload = "{\"@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet(ContainedNavProp)/$entity\"," + "\"ID\":101,\"Name\":\"Alice\"," + "\"[email protected]\":\"http://example.org/odata.svc/$metadata#EntitySet(101)/ContainedCollectionNavProp\"," + "\"[email protected]\":\"http://example.org/odata.svc/navigation\"," + "\"ContainedCollectionNavProp\":[{\"ID\":102,\"Name\":\"Bob\"}]" + "}"; result.Should().Be(expectedPayload); }
/// <summary> /// Constructor to create a new delta link scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="link">The link for the new scope.</param> /// <param name="serializationInfo">The serialization info for the current entry.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal JsonLightDeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, link, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri) { }
private IEnumerable <ODataItem> CreatePayload(ProjectedPropertiesTestCase testCase) { // First create the entry itself (it might get wrapped later) ODataEntry entry = new ODataEntry() { TypeName = "TestModel.EntityType", Properties = new List <ODataProperty>() { new ODataProperty { Name = "StringProperty", Value = "foo" }, new ODataProperty { Name = "NumberProperty", Value = 42 }, new ODataProperty { Name = "SimpleComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Name", Value = "Bart" } } } }, new ODataProperty { Name = "DeepComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.NestedComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "InnerComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType2", Properties = new ODataProperty[] { new ODataProperty { Name = "Value", Value = 43 } } } } } } }, new ODataProperty { Name = "PrimitiveCollection", Value = new ODataCollectionValue { TypeName = "Collection(Edm.String)", Items = new object[] { "Simpson" } } }, new ODataProperty { Name = "ComplexCollection", Value = new ODataCollectionValue { TypeName = "Collection(TestModel.RatingComplexType)", Items = new object[] { new ODataComplexValue { TypeName = "TestModel.RatingComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Rating", Value = -3 } } } } } } }, SerializationInfo = MySerializationInfo }; if (testCase.ResponseOnly) { // Add a stream property for responses ((List <ODataProperty>)entry.Properties).Add(new ODataProperty { Name = "NamedStream", Value = new ODataStreamReferenceValue { EditLink = new Uri("http://odata.org/namedstream") } }); } ODataItem[] entryItems = new ODataItem[] { entry, new ODataNavigationLink { Name = "DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred"), AssociationLinkUrl = testCase.ResponseOnly ? new Uri("http://odata.org/associationlink2") : null }, null, // End deferred link new ODataNavigationLink { Name = "ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/entry") }, new ODataEntry() { TypeName = "TestModel.ExpandedEntryType", Properties = new ODataProperty[] { new ODataProperty { Name = "ExpandedEntryName", Value = "bar" } }, SerializationInfo = MySerializationInfo }, new ODataNavigationLink { Name = "ExpandedEntry_DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred") }, null, // End deffered link new ODataNavigationLink { Name = "ExpandedEntry_ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid1"), SerializationInfo = MySerializationInfo }, null, // End feed null, // End exanded expanded feed link null, // End expanded entry null, // End expanded entry nav link new ODataNavigationLink { Name = "ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid2") }, new ODataEntry { TypeName = "TestModel.EntityType" }, null, // End entry new ODataEntry { TypeName = "TestModel.EntityType", SerializationInfo = MySerializationInfo }, null, // End entry null, // End expanded feed null, // End expanded feed nav link null, // End the top-level entry }; ProjectedPropertiesAnnotation projectedProperties = testCase.TopLevelProjectedProperties; if (!testCase.NestedPayload) { this.Assert.IsNull(testCase.NestedProjectedProperties, "For a non-nested payload, no nested annotation must be specified."); entry.SetAnnotation(projectedProperties); return(entryItems); } // If we are processing a test case for a nested payload, wrap the entry items into a wrapping entry with an expanded navigation link. ODataEntry wrappingEntry = new ODataEntry() { TypeName = "TestModel.WrappingEntityType", Properties = new[] { new ODataProperty { Name = "Wrapping_ID", Value = 1 } }, SerializationInfo = MySerializationInfo }; IEnumerable <ODataItem> wrappedItems = new ODataItem[] { wrappingEntry, new ODataNavigationLink { Name = "Wrapping_ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/wrapping") } } .Concat(entryItems) .Concat(new ODataItem[] { null, null }); ProjectedPropertiesAnnotation nestedProjectedProperties = testCase.NestedProjectedProperties; entry.SetAnnotation(nestedProjectedProperties); wrappingEntry.SetAnnotation(projectedProperties); return(wrappedItems); }
/// <summary> /// Verifies that calling WriteStart delta (deleted) entry is valid. /// </summary> /// <param name="synchronousCall">true if the call is to be synchronous; false otherwise.</param> /// <param name="entry">Entry/item to write.</param> private void VerifyCanWriteEntry(bool synchronousCall, ODataItem entry) { this.VerifyNotDisposed(); this.VerifyCallAllowed(synchronousCall); ExceptionUtils.CheckArgumentNotNull(entry, "entry"); }
private void WriteRequestWithoutModelAndValidatePayload(ODataItem[] nestedItemToWrite, string expectedPayload, bool setMetadataDocumentUri = true) { // without model, write request // 1. CreateEntityContainerElementContextUri(): no entitySetName --> no context uri is output. // 2. but odata.type will be output because of no model. JsonMinimalMetadataTypeNameOracle.GetEntryTypeNameForWriting method: // We only write entity type names in Json Light if it's more derived (different) from the expected type name. var stream = new MemoryStream(); var outputContext = CreateAtomOutputContext(stream, null, false, null); var writer = new ODataAtomWriter(outputContext, null, null, nestedItemToWrite[0] is ODataFeed); WriteNestedItems(nestedItemToWrite, writer); ValidateWrittenPayload(stream, writer, expectedPayload); }
internal static ODataItem ReadEntryOrFeed(ODataReader odataReader, ODataDeserializerContext readContext) { ODataItem topLevelItem = null; Stack <ODataItem> itemsStack = new Stack <ODataItem>(); while (odataReader.Read()) { switch (odataReader.State) { case ODataReaderState.EntryStart: ODataEntry entry = (ODataEntry)odataReader.Item; ODataEntryAnnotation entryAnnotation = null; if (entry != null) { entryAnnotation = new ODataEntryAnnotation(); entry.SetAnnotation(entryAnnotation); } if (itemsStack.Count == 0) { Contract.Assert(entry != null, "The top-level entry can never be null."); topLevelItem = entry; } else { ODataItem parentItem = itemsStack.Peek(); ODataFeed parentFeed = parentItem as ODataFeed; if (parentFeed != null) { ODataFeedAnnotation parentFeedAnnotation = parentFeed.GetAnnotation <ODataFeedAnnotation>(); Contract.Assert(parentFeedAnnotation != null, "Every feed we added to the stack should have the feed annotation on it."); parentFeedAnnotation.Add(entry); } else { ODataNavigationLink parentNavigationLink = (ODataNavigationLink)parentItem; ODataNavigationLinkAnnotation parentNavigationLinkAnnotation = parentNavigationLink.GetAnnotation <ODataNavigationLinkAnnotation>(); Contract.Assert(parentNavigationLinkAnnotation != null, "Every navigation link we added to the stack should have the navigation link annotation on it."); Contract.Assert(parentNavigationLink.IsCollection == false, "Only singleton navigation properties can contain entry as their child."); Contract.Assert(parentNavigationLinkAnnotation.Count == 0, "Each navigation property can contain only one entry as its direct child."); parentNavigationLinkAnnotation.Add(entry); } } itemsStack.Push(entry); RecurseEnter(readContext); break; case ODataReaderState.EntryEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek() == odataReader.Item, "The entry which is ending should be on the top of the items stack."); itemsStack.Pop(); RecurseLeave(readContext); break; case ODataReaderState.NavigationLinkStart: ODataNavigationLink navigationLink = (ODataNavigationLink)odataReader.Item; Contract.Assert(navigationLink != null, "Navigation link should never be null."); navigationLink.SetAnnotation(new ODataNavigationLinkAnnotation()); Contract.Assert(itemsStack.Count > 0, "Navigation link can't appear as top-level item."); { ODataEntry parentEntry = (ODataEntry)itemsStack.Peek(); ODataEntryAnnotation parentEntryAnnotation = parentEntry.GetAnnotation <ODataEntryAnnotation>(); Contract.Assert(parentEntryAnnotation != null, "Every entry we added to the stack should have the entry annotation on it."); parentEntryAnnotation.Add(navigationLink); } itemsStack.Push(navigationLink); RecurseEnter(readContext); break; case ODataReaderState.NavigationLinkEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek() == odataReader.Item, "The navigation link which is ending should be on the top of the items stack."); itemsStack.Pop(); RecurseLeave(readContext); break; case ODataReaderState.FeedStart: ODataFeed feed = (ODataFeed)odataReader.Item; Contract.Assert(feed != null, "Feed should never be null."); feed.SetAnnotation(new ODataFeedAnnotation()); if (itemsStack.Count > 0) { ODataNavigationLink parentNavigationLink = (ODataNavigationLink)itemsStack.Peek(); Contract.Assert(parentNavigationLink != null, "this has to be an inner feed. inner feeds always have a navigation link."); ODataNavigationLinkAnnotation parentNavigationLinkAnnotation = parentNavigationLink.GetAnnotation <ODataNavigationLinkAnnotation>(); Contract.Assert(parentNavigationLinkAnnotation != null, "Every navigation link we added to the stack should have the navigation link annotation on it."); Contract.Assert(parentNavigationLink.IsCollection == true, "Only collection navigation properties can contain feed as their child."); parentNavigationLinkAnnotation.Add(feed); } else { topLevelItem = feed; } itemsStack.Push(feed); RecurseEnter(readContext); break; case ODataReaderState.FeedEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek() == odataReader.Item, "The feed which is ending should be on the top of the items stack."); itemsStack.Pop(); RecurseLeave(readContext); break; case ODataReaderState.EntityReferenceLink: ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)odataReader.Item; Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null."); Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item."); { ODataNavigationLink parentNavigationLink = (ODataNavigationLink)itemsStack.Peek(); ODataNavigationLinkAnnotation parentNavigationLinkAnnotation = parentNavigationLink.GetAnnotation <ODataNavigationLinkAnnotation>(); Contract.Assert(parentNavigationLinkAnnotation != null, "Every navigation link we added to the stack should have the navigation link annotation on it."); parentNavigationLinkAnnotation.Add(entityReferenceLink); } break; default: Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state."); break; } } Contract.Assert(odataReader.State == ODataReaderState.Completed, "We should have consumed all of the input by now."); Contract.Assert(topLevelItem != null, "A top level entry or feed should have been read by now."); return(topLevelItem); }
private static void WriteNestedItems(ODataItem[] nestedItemsToWrite, ODataAtomWriter writer) { foreach (ODataItem itemToWrite in nestedItemsToWrite) { ODataFeed feedToWrite = itemToWrite as ODataFeed; if (feedToWrite != null) { writer.WriteStart(feedToWrite); } else { ODataEntry entryToWrite = itemToWrite as ODataEntry; if (entryToWrite != null) { writer.WriteStart(entryToWrite); } else { writer.WriteStart((ODataNavigationLink)itemToWrite); } } } for (int count = 0; count < nestedItemsToWrite.Length; count++) { writer.WriteEnd(); } }
private void AddBoundNavigationPropertyAnnotation(ODataItem item, ODataNavigationLink navigationLink, object boundValue) { var annotation = item.GetAnnotation<BoundNavigationPropertyAnnotation>(); if (annotation == null) { annotation = new BoundNavigationPropertyAnnotation { BoundProperties = new List<Tuple<ODataNavigationLink, object>>() }; item.SetAnnotation(annotation); } annotation.BoundProperties.Add(new Tuple<ODataNavigationLink, object>(navigationLink, boundValue)); }
/// <summary> /// Gets the serialization info for the given delta link. /// </summary> /// <param name="item">The entry to get the serialization info for.</param> /// <returns>The serialization info for the given entry.</returns> private ODataDeltaSerializationInfo GetLinkSerializationInfo(ODataItem item) { Debug.Assert(item != null, "item != null"); ODataDeltaSerializationInfo serializationInfo = null; var deltaLink = item as ODataDeltaLink; if (deltaLink != null) { serializationInfo = deltaLink.SerializationInfo; } var deltaDeletedLink = item as ODataDeltaDeletedLink; if (deltaDeletedLink != null) { serializationInfo = deltaDeletedLink.SerializationInfo; } return serializationInfo ?? this.GetParentFeedSerializationInfo(); }
private void EnterScope(ODataReaderState state, ODataItem item, IEdmEntityType expectedEntityType) { base.EnterScope(new AtomScope(state, item, expectedEntityType)); }
/// <summary> /// Constructor creating a new writer scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="item">The item attached to this scope.</param> /// <param name="navigationSource">The navigation source we are going to write entities for.</param> /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="odataUri">The ODataUri info of this scope.</param> internal Scope(WriterState state, ODataItem item, IEdmNavigationSource navigationSource, IEdmEntityType entityType, SelectedPropertiesNode selectedProperties, ODataUri odataUri) { this.state = state; this.item = item; this.EntityType = entityType; this.NavigationSource = navigationSource; this.selectedProperties = selectedProperties; this.odataUri = odataUri; }