/// <summary> /// Initializes a new expanded ODataNestedResourceInfo instance and visits the payload. /// </summary> /// <param name="payloadElement">The expanded link to visit.</param> public override void Visit(ExpandedLink payloadElement) { Debug.Assert(this.items.Peek() is ODataNestedResourceInfo); ODataNestedResourceInfo navigationLink = (ODataNestedResourceInfo)this.items.Pop(); navigationLink.IsCollection = !payloadElement.IsSingleEntity; // TODO, ckerer: where do I get the info whether this links is a singleton or collection? if (payloadElement.UriString != null) { navigationLink.Url = new Uri(payloadElement.UriString); } var entry = (ODataResource)this.items.Peek(); var annotation = entry.GetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataEntryNavigationLinksObjectModelAnnotation(); entry.SetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(annotation); } annotation.Add(navigationLink, this.currentPropertyPosition); this.items.Push(navigationLink); base.Visit(payloadElement); this.currentPropertyPosition++; }
/// <summary> /// Initializes an ODataNestedResourceInfo instance for the deferred link payload. /// </summary> /// <param name="payloadElement">The deferred link to process.</param> public override void Visit(DeferredLink payloadElement) { if (this.items.Peek() is ODataNestedResourceInfo) { ODataNestedResourceInfo navigationLink = (ODataNestedResourceInfo)this.items.Pop(); navigationLink.Url = new Uri(payloadElement.UriString); var contentType = payloadElement.Annotations.Where(a => a is ContentTypeAnnotation).SingleOrDefault(); if (contentType != null) { navigationLink.IsCollection = contentType.StringRepresentation.Contains("feed"); } var entry = (ODataResource)this.items.Peek(); var annotation = entry.GetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataEntryNavigationLinksObjectModelAnnotation(); entry.SetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(annotation); } annotation.Add(navigationLink, this.currentPropertyPosition); this.items.Push(navigationLink); if (!this.response) { navigationLink.SetAnnotation(new ODataNavigationLinkExpandedItemObjectModelAnnotation() { ExpandedItem = new ODataEntityReferenceLink() { Url = navigationLink.Url } }); } base.Visit(payloadElement); this.currentPropertyPosition++; } else { this.items.Push(new ODataEntityReferenceLink() { Url = new Uri(payloadElement.UriString) }); } }
/// <summary> /// Process all properties (regular and navigation properties) while preserving their order in /// the payload. /// </summary> /// <param name="entry">The <see cref="ODataResource"/> to process the properties for.</param> public static void ProcessPropertiesPreservingPayloadOrder(this ODataResource entry, Action <ODataProperty> propertyAction, Action <ODataNestedResourceInfo> navigationLinkAction) { ExceptionUtilities.CheckArgumentNotNull(entry, "entry"); ExceptionUtilities.CheckArgumentNotNull(propertyAction, "propertyAction"); ExceptionUtilities.CheckArgumentNotNull(navigationLinkAction, "navigationLinkAction"); ODataEntryNavigationLinksObjectModelAnnotation navigationLinks = entry.NavigationLinks(); if (navigationLinks == null) { navigationLinks = new ODataEntryNavigationLinksObjectModelAnnotation(); } int navigationLinksProcessed = 0; // NOTE we iterate over all the properties here just to get the count; since this is test code only we don't care int navigationLinkCount = navigationLinks == null ? 0 : navigationLinks.Count; int totalPropertyCount = entry.Properties.Count() + navigationLinkCount; // NOTE: we are preserving the same order of items as in the payload, i.e., if regular // properties and navigation properties are interleaved we preserve their relative order. using (IEnumerator <ODataProperty> propertyEnumerator = entry.Properties.GetEnumerator()) { ODataNestedResourceInfo navigationLink; for (int i = 0; i < totalPropertyCount; ++i) { if (navigationLinks != null && navigationLinks.TryGetNavigationLinkAt(i, out navigationLink)) { navigationLinkAction(navigationLink); navigationLinksProcessed++; } else { bool hasMore = propertyEnumerator.MoveNext(); Debug.Assert(hasMore, "More properties were expected."); propertyAction(propertyEnumerator.Current); } } } Debug.Assert(navigationLinksProcessed == navigationLinkCount, "All navigation links should have been processed."); }
/// <summary> /// Process all properties (regular and navigation properties) while preserving their order in /// the payload. /// </summary> /// <param name="entry">The <see cref="ODataEntry"/> to process the properties for.</param> public static void ProcessPropertiesPreservingPayloadOrder(this ODataEntry entry, Action<ODataProperty> propertyAction, Action<ODataNavigationLink> navigationLinkAction) { ExceptionUtilities.CheckArgumentNotNull(entry, "entry"); ExceptionUtilities.CheckArgumentNotNull(propertyAction, "propertyAction"); ExceptionUtilities.CheckArgumentNotNull(navigationLinkAction, "navigationLinkAction"); ODataEntryNavigationLinksObjectModelAnnotation navigationLinks = entry.NavigationLinks(); if (navigationLinks == null) { navigationLinks = new ODataEntryNavigationLinksObjectModelAnnotation(); } int navigationLinksProcessed = 0; // NOTE we iterate over all the properties here just to get the count; since this is test code only we don't care int navigationLinkCount = navigationLinks == null ? 0 : navigationLinks.Count; int totalPropertyCount = entry.Properties.Count() + navigationLinkCount; // NOTE: we are preserving the same order of items as in the payload, i.e., if regular // properties and navigation properties are interleaved we preserve their relative order. using (IEnumerator<ODataProperty> propertyEnumerator = entry.Properties.GetEnumerator()) { ODataNavigationLink navigationLink; for (int i = 0; i < totalPropertyCount; ++i) { if (navigationLinks != null && navigationLinks.TryGetNavigationLinkAt(i, out navigationLink)) { navigationLinkAction(navigationLink); navigationLinksProcessed++; } else { bool hasMore = propertyEnumerator.MoveNext(); Debug.Assert(hasMore, "More properties were expected."); propertyAction(propertyEnumerator.Current); } } } Debug.Assert(navigationLinksProcessed == navigationLinkCount, "All navigation links should have been processed."); }
private void Read(Lazy<ODataReader> lazyReader) { foreach (var state in this.expectedStates) { lazyReader.Value.Read(); ExceptionUtilities.Assert(lazyReader.Value.State == state, "Expected %1, Found %2", state, lazyReader.Value.State); switch (state) { case ODataReaderState.FeedStart: if (readItems.Count > 0) { ODataNavigationLink navLink = (ODataNavigationLink)readItems.Peek(); var annotation = navLink.GetAnnotation<ODataNavigationLinkExpandedItemObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataNavigationLinkExpandedItemObjectModelAnnotation(); navLink.SetAnnotation(annotation); } annotation.ExpandedItem = lazyReader.Value.Item; } readItems.Push(lazyReader.Value.Item); break; case ODataReaderState.EntryStart: var currentEntry = (ODataEntry)lazyReader.Value.Item; if (readItems.Count > 0) { ODataFeed feed = readItems.Peek() as ODataFeed; if (feed != null) { var annotation = feed.GetAnnotation<ODataFeedEntriesObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataFeedEntriesObjectModelAnnotation(); feed.SetAnnotation(annotation); } annotation.Add((ODataEntry)lazyReader.Value.Item); } else { ODataNavigationLink navLink = (ODataNavigationLink)readItems.Peek(); var annotation = navLink.GetAnnotation<ODataNavigationLinkExpandedItemObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataNavigationLinkExpandedItemObjectModelAnnotation(); navLink.SetAnnotation(annotation); } annotation.ExpandedItem = currentEntry; } } readItems.Push(currentEntry); break; case ODataReaderState.NavigationLinkStart: ODataEntry entry = (ODataEntry)readItems.Peek(); var navLinksAnnotation = entry.GetAnnotation<ODataEntryNavigationLinksObjectModelAnnotation>(); if (navLinksAnnotation == null) { navLinksAnnotation = new ODataEntryNavigationLinksObjectModelAnnotation(); entry.SetAnnotation(navLinksAnnotation); } navLinksAnnotation.Add((ODataNavigationLink)lazyReader.Value.Item, entry.Properties.Count() + navLinksAnnotation.Count); readItems.Push(lazyReader.Value.Item); break; case ODataReaderState.EntryEnd: case ODataReaderState.FeedEnd: case ODataReaderState.NavigationLinkEnd: if (readItems.Count() > 1) readItems.Pop(); break; } } this.expectedStates.Clear(); }
/// <summary> /// Read an entry with an <see cref="ODataReader"/> positioned on the entry start. /// </summary> /// <param name="reader">The <see cref="ODataReader"/> to use for reading the entry.</param> /// <returns>An <see cref="ODataEntry"/>, possibly with annotations.</returns> private ODataEntry ReadEntry(ODataReader reader) { this.assert.AreEqual(ODataReaderState.EntryStart, reader.State, "Reader states don't match."); ODataEntry entry = (ODataEntry)reader.Item; ODataEntryPayloadOrderObjectModelAnnotation payloadOrderItems = this.storePayloadOrder ? new ODataEntryPayloadOrderObjectModelAnnotation() : null; ODataEntryNavigationLinksObjectModelAnnotation navigationLinks = new ODataEntryNavigationLinksObjectModelAnnotation(); AddEntryPayloadOrderItems(entry, payloadOrderItems); if (payloadOrderItems != null) { payloadOrderItems.AddStartEntry(); } while (reader.Read()) { if (reader.State == ODataReaderState.NavigationLinkStart) { int positionInProperties = entry.Properties.Count(); AddEntryPayloadOrderItems(entry, payloadOrderItems); ODataNavigationLink navigationLinkAtStart = (ODataNavigationLink)reader.Item; if (payloadOrderItems != null) { payloadOrderItems.AddODataNavigationLink(navigationLinkAtStart); } ODataNavigationLink navigationLink = this.ReadNavigationLink(reader); this.assert.AreSame(navigationLinkAtStart, navigationLink, "Expected the same navigation link instance."); navigationLinks.Add(navigationLink, positionInProperties + navigationLinks.Count); } else if (reader.State == ODataReaderState.EntryEnd) { // we are done reading this entry break; } else { this.assert.Fail("Unexpected reader state '" + reader.State + "' for reading an entry."); } } this.assert.AreEqual(ODataReaderState.EntryEnd, reader.State, "Reader states don't match."); ODataEntry entryAtEnd = (ODataEntry)reader.Item; this.assert.AreSame(entry, entryAtEnd, "Expected the same entry instance."); AddEntryPayloadOrderItems(entry, payloadOrderItems); entry.SetAnnotation(navigationLinks); if (this.storePayloadOrder) { entry.SetAnnotation(payloadOrderItems); } return entry; }
/// <summary> /// Initializes a new expanded ODataNavigationLink instance and visits the payload. /// </summary> /// <param name="payloadElement">The expanded link to visit.</param> public override void Visit(ExpandedLink payloadElement) { Debug.Assert(this.items.Peek() is ODataNavigationLink); ODataNavigationLink navigationLink = (ODataNavigationLink) this.items.Pop(); navigationLink.IsCollection = !payloadElement.IsSingleEntity; // TODO, ckerer: where do I get the info whether this links is a singleton or collection? if (payloadElement.UriString != null) { navigationLink.Url = new Uri(payloadElement.UriString); } var entry = (ODataEntry) this.items.Peek(); var annotation = entry.GetAnnotation<ODataEntryNavigationLinksObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataEntryNavigationLinksObjectModelAnnotation(); entry.SetAnnotation<ODataEntryNavigationLinksObjectModelAnnotation>(annotation); } annotation.Add(navigationLink, this.currentPropertyPosition); this.items.Push(navigationLink); base.Visit(payloadElement); this.currentPropertyPosition++; }
/// <summary> /// Initializes an ODataNavigationLink instance for the deferred link payload. /// </summary> /// <param name="payloadElement">The deferred link to process.</param> public override void Visit(DeferredLink payloadElement) { if (this.items.Peek() is ODataNavigationLink) { ODataNavigationLink navigationLink = (ODataNavigationLink)this.items.Pop(); navigationLink.Url = new Uri(payloadElement.UriString); AddLinkMetadata(payloadElement, navigationLink); var contentType = payloadElement.Annotations.Where(a => a is ContentTypeAnnotation).SingleOrDefault(); if (contentType != null) { navigationLink.IsCollection = contentType.StringRepresentation.Contains("feed"); } var entry = (ODataEntry)this.items.Peek(); var annotation = entry.GetAnnotation<ODataEntryNavigationLinksObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataEntryNavigationLinksObjectModelAnnotation(); entry.SetAnnotation<ODataEntryNavigationLinksObjectModelAnnotation>(annotation); } annotation.Add(navigationLink, this.currentPropertyPosition); this.items.Push(navigationLink); if (!this.response) { navigationLink.SetAnnotation(new ODataNavigationLinkExpandedItemObjectModelAnnotation() { ExpandedItem = new ODataEntityReferenceLink() { Url = navigationLink.Url } }); } base.Visit(payloadElement); this.currentPropertyPosition++; } else { this.items.Push(new ODataEntityReferenceLink() { Url = new Uri(payloadElement.UriString) }); } }