/// <summary> /// Reads an ODataFeed or an ODataItem from the reader. /// </summary> /// <param name="reader">The OData reader to read from.</param> /// <returns>The read feed or entry.</returns> public static ODataItemBase ReadEntryOrFeed(ODataReader reader) { if (reader == null) { throw Error.ArgumentNull("odataReader"); } ODataItemBase topLevelItem = null; Stack<ODataItemBase> itemsStack = new Stack<ODataItemBase>(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryStart: ODataEntry entry = (ODataEntry)reader.Item; ODataEntryWithNavigationLinks entryWrapper = null; if (entry != null) { entryWrapper = new ODataEntryWithNavigationLinks(entry); } if (itemsStack.Count == 0) { Contract.Assert(entry != null, "The top-level entry can never be null."); topLevelItem = entryWrapper; } else { ODataItemBase parentItem = itemsStack.Peek(); ODataFeedWithEntries parentFeed = parentItem as ODataFeedWithEntries; if (parentFeed != null) { parentFeed.Entries.Add(entryWrapper); } else { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)parentItem; Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == false, "Only singleton navigation properties can contain entry as their child."); Contract.Assert(parentNavigationLink.NestedItems.Count == 0, "Each navigation property can contain only one entry as its direct child."); parentNavigationLink.NestedItems.Add(entryWrapper); } } itemsStack.Push(entryWrapper); break; case ODataReaderState.EntryEnd: Contract.Assert(itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item), "The entry which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.NavigationLinkStart: ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item; Contract.Assert(navigationLink != null, "Navigation link should never be null."); ODataNavigationLinkWithItems navigationLinkWrapper = new ODataNavigationLinkWithItems(navigationLink); Contract.Assert(itemsStack.Count > 0, "Navigation link can't appear as top-level item."); { ODataEntryWithNavigationLinks parentEntry = (ODataEntryWithNavigationLinks)itemsStack.Peek(); parentEntry.NavigationLinks.Add(navigationLinkWrapper); } itemsStack.Push(navigationLinkWrapper); break; case ODataReaderState.NavigationLinkEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The navigation link which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.FeedStart: ODataFeed feed = (ODataFeed)reader.Item; Contract.Assert(feed != null, "Feed should never be null."); ODataFeedWithEntries feedWrapper = new ODataFeedWithEntries(feed); if (itemsStack.Count > 0) { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek(); Contract.Assert(parentNavigationLink != null, "this has to be an inner feed. inner feeds always have a navigation link."); Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == true, "Only collection navigation properties can contain feed as their child."); parentNavigationLink.NestedItems.Add(feedWrapper); } else { topLevelItem = feedWrapper; } itemsStack.Push(feedWrapper); break; case ODataReaderState.FeedEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The feed which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.EntityReferenceLink: ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item; Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null."); ODataEntityReferenceLinkBase entityReferenceLinkWrapper = new ODataEntityReferenceLinkBase(entityReferenceLink); Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item."); { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek(); parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper); } break; default: Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state."); break; } } Contract.Assert(reader.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 ODataResponse ReadResponse(ODataReader odataReader) { ResponseNode rootNode = null; var nodeStack = new Stack<ResponseNode>(); while (odataReader.Read()) { if (odataReader.State == ODataReaderState.Completed) break; switch (odataReader.State) { case ODataReaderState.FeedStart: StartFeed(nodeStack, CreateFeedDetails(odataReader.Item as ODataFeed)); break; case ODataReaderState.FeedEnd: EndFeed(nodeStack, CreateFeedDetails(odataReader.Item as ODataFeed), ref rootNode); break; case ODataReaderState.EntryStart: StartEntry(nodeStack); break; case ODataReaderState.EntryEnd: EndEntry(nodeStack, ref rootNode, odataReader.Item); break; case ODataReaderState.NavigationLinkStart: StartNavigationLink(nodeStack, (odataReader.Item as ODataNavigationLink).Name); break; case ODataReaderState.NavigationLinkEnd: EndNavigationLink(nodeStack); break; } } return ODataResponse.FromNode(rootNode); }
public ODataReaderEntityMaterializer(ODataMessageReader odataMessageReader, ODataReader reader, ResponseInfo responseInfo, QueryComponents queryComponents, Type expectedType, ProjectionPlan materializeEntryPlan) : base(responseInfo, queryComponents, expectedType, materializeEntryPlan) { this.messageReader = odataMessageReader; this.itemReader = new ODataFeedOrEntryReader(reader, responseInfo); }
public ODataFeedOrEntryReader(ODataReader reader, ResponseInfo responseInfo) { this.reader = reader; this.responseInfo = responseInfo; this.currentEntry = null; this.currentFeed = null; this.feedEntries = null; }
private void ReadAndOutputEntryOrFeed(ODataReader reader) { while (reader.Read()) { switch (reader.State) { case ODataReaderState.FeedStart: { ODataFeed feed = (ODataFeed)reader.Item; this.writer.WriteLine("ODataFeed:"); this.writer.Indent++; } break; case ODataReaderState.FeedEnd: { ODataFeed feed = (ODataFeed)reader.Item; if (feed.Count != null) { this.writer.WriteLine("Count: " + feed.Count.ToString()); } if (feed.NextPageLink != null) { this.writer.WriteLine("NextPageLink: " + feed.NextPageLink.AbsoluteUri); } this.writer.Indent--; } break; case ODataReaderState.EntryStart: { ODataEntry entry = (ODataEntry)reader.Item; this.writer.WriteLine("ODataEntry:"); this.writer.Indent++; } break; case ODataReaderState.EntryEnd: { ODataEntry entry = (ODataEntry)reader.Item; this.writer.WriteLine("TypeName: " + (entry.TypeName ?? "<null>")); this.writer.WriteLine("Id: " + (entry.Id ?? "<null>")); if (entry.ReadLink != null) { this.writer.WriteLine("ReadLink: " + entry.ReadLink.AbsoluteUri); } if (entry.EditLink != null) { this.writer.WriteLine("EditLink: " + entry.EditLink.AbsoluteUri); } if (entry.MediaResource != null) { this.writer.Write("MediaResource: "); this.WriteValue(entry.MediaResource); } this.WriteProperties(entry.Properties); this.writer.Indent--; } break; case ODataReaderState.NavigationLinkStart: { ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item; this.writer.WriteLine(navigationLink.Name + ": ODataNavigationLink: "); this.writer.Indent++; } break; case ODataReaderState.NavigationLinkEnd: { ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item; this.writer.WriteLine("Url: " + (navigationLink.Url == null ? "<null>" : navigationLink.Url.AbsoluteUri)); this.writer.Indent--; } break; } } }
private ODataResponse ReadResponse(ODataReader odataReader, bool includeResourceTypeInEntryProperties) { ResponseNode rootNode = null; var nodeStack = new Stack<ResponseNode>(); while (odataReader.Read()) { if (odataReader.State == ODataReaderState.Completed) break; switch (odataReader.State) { case ODataReaderState.FeedStart: StartFeed(nodeStack, CreateFeedDetails(odataReader.Item as ODataFeed)); break; case ODataReaderState.FeedEnd: EndFeed(nodeStack, CreateFeedDetails(odataReader.Item as ODataFeed), ref rootNode); break; case ODataReaderState.EntryStart: StartEntry(nodeStack); break; case ODataReaderState.EntryEnd: EndEntry(nodeStack, ref rootNode, odataReader.Item, includeResourceTypeInEntryProperties); break; case ODataReaderState.NavigationLinkStart: StartNavigationLink(nodeStack, (odataReader.Item as ODataNavigationLink).Name); break; case ODataReaderState.NavigationLinkEnd: EndNavigationLink(nodeStack); break; } } return rootNode.Feed != null ? ODataResponse.FromFeed(rootNode.Feed, rootNode.FeedAnnotations) : ODataResponse.FromEntry(rootNode.Entry); }