private void WriteNavigationLink(ODataWriter writer, ODataNestedResourceInfo link) { writer.WriteStart(link); var expanded = link.GetAnnotation <ODataNavigationLinkExpandedItemObjectModelAnnotation>(); if (expanded != null) { var feed = expanded.ExpandedItem as ODataResourceSet; if (feed != null) { this.WriteFeed(writer, feed); } else { ODataResource entry = expanded.ExpandedItem as ODataResource; if (entry != null || expanded.ExpandedItem == null) { this.WriteEntry(writer, entry); } else { ExceptionUtilities.Assert(expanded.ExpandedItem is ODataEntityReferenceLink, "Content of a nav. link can only be a feed, entry or entity reference link."); writer.WriteEntityReferenceLink((ODataEntityReferenceLink)expanded.ExpandedItem); } } } writer.WriteEnd(); }
/// <summary> /// Creates the materializer link with a resource set. /// </summary> /// <param name="link">The link.</param> /// <param name="resourceSet">The resource set.</param> /// <returns>The materializer link.</returns> public static MaterializerNavigationLink CreateLink(ODataNestedResourceInfo link, ODataResourceSet resourceSet) { Debug.Assert(link.GetAnnotation <MaterializerNavigationLink>() == null, "there should be no MaterializerNestedResourceInfo annotation on the feed link yet"); MaterializerNavigationLink materializedNestedResourceInfo = new MaterializerNavigationLink(link, resourceSet); link.SetAnnotation <MaterializerNavigationLink>(materializedNestedResourceInfo); return(materializedNestedResourceInfo); }
/// <summary> /// Gets the expanded content of a navigation link. /// </summary> /// <param name="navigationLink">The <see cref="ODataNestedResourceInfo"/> to get the navigation content for.</param> /// <param name="expandedContent">The expanded content (if the method returns null), which can be either /// null (null expanded entry), or <see cref="ODataResource"/> or <see cref="ODataResourceSet"/>.</param> /// <returns>true if the <paramref name="navigationLink"/> is expanded, or false otherwise.</returns> public static bool TryGetExpandedContent(this ODataNestedResourceInfo navigationLink, out object expandedContent) { ExceptionUtilities.CheckArgumentNotNull(navigationLink, "navigationLink"); var expandedItemAnnotation = navigationLink.GetAnnotation <ODataNavigationLinkExpandedItemObjectModelAnnotation>(); if (expandedItemAnnotation != null) { expandedContent = expandedItemAnnotation.ExpandedItem; return(true); } else { expandedContent = null; return(false); } }
/// <summary> /// Gets the materializer link. /// </summary> /// <param name="link">The link.</param> /// <returns>The materializer link.</returns> public static MaterializerNavigationLink GetLink(ODataNestedResourceInfo link) { return(link.GetAnnotation <MaterializerNavigationLink>()); }
/// <summary> /// Visits a navigation link item. /// </summary> /// <param name="navigationLink">The navigation link to visit.</param> protected override ODataPayloadElement VisitNavigationLink(ODataNestedResourceInfo navigationLink) { ExceptionUtilities.CheckArgumentNotNull(navigationLink, "navigationLink"); ODataPayloadElement navigationPropertyContent = null; // check whether there is an entry or feed associated with the link var expandedItemAnnotation = navigationLink.GetAnnotation <ODataNavigationLinkExpandedItemObjectModelAnnotation>(); if (expandedItemAnnotation != null) { string navigationLinkUrlString = !this.payloadContainsIdentityMetadata || navigationLink.Url == null ? null : navigationLink.Url.OriginalString; if (expandedItemAnnotation.ExpandedItem is ODataResource) { navigationPropertyContent = new ExpandedLink(this.Visit((ODataResource)expandedItemAnnotation.ExpandedItem)) { UriString = navigationLinkUrlString }; } else if (expandedItemAnnotation.ExpandedItem is ODataResourceSet) { navigationPropertyContent = new ExpandedLink(this.Visit((ODataResourceSet)expandedItemAnnotation.ExpandedItem)) { UriString = navigationLinkUrlString }; } else if (expandedItemAnnotation.ExpandedItem is ODataEntityReferenceLink) { ExceptionUtilities.Assert(!this.response, "Entity reference links in navigation links can only appear in requests."); navigationPropertyContent = this.VisitEntityReferenceLink((ODataEntityReferenceLink)expandedItemAnnotation.ExpandedItem); } else if (expandedItemAnnotation.ExpandedItem is List <ODataItem> ) { ExceptionUtilities.Assert(!this.response, "Navigation links with multiple items in content can only appear in requests."); LinkCollection linkCollection = new LinkCollection(); foreach (ODataItem item in (List <ODataItem>)expandedItemAnnotation.ExpandedItem) { if (item is ODataResourceSet) { linkCollection.Add(new ExpandedLink(this.Visit((ODataResourceSet)item))); } else { ExceptionUtilities.Assert(item is ODataEntityReferenceLink, "Only feed and entity reference links can appear in navigation link content with multiple items."); linkCollection.Add(this.VisitEntityReferenceLink((ODataEntityReferenceLink)item)); } } navigationPropertyContent = linkCollection; } else { ExceptionUtilities.Assert(expandedItemAnnotation.ExpandedItem == null, "Only expanded entry, feed or null is allowed."); navigationPropertyContent = new ExpandedLink(new EntityInstance(null, true)) { UriString = navigationLinkUrlString }; } } else { ExceptionUtilities.Assert(this.response, "Deferred links are only valid in responses."); // this is a deferred link DeferredLink deferredLink = new DeferredLink() { UriString = !this.payloadContainsIdentityMetadata || navigationLink.Url == null ? null : navigationLink.Url.OriginalString, }; navigationPropertyContent = deferredLink; } DeferredLink associationLink = null; if (this.payloadContainsIdentityMetadata && navigationLink.AssociationLinkUrl != null) { associationLink = new DeferredLink() { UriString = navigationLink.AssociationLinkUrl.OriginalString }; } return(new NavigationPropertyInstance(navigationLink.Name, navigationPropertyContent, associationLink)); }
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.ResourceSetStart: if (readItems.Count > 0) { ODataNestedResourceInfo navLink = (ODataNestedResourceInfo)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.ResourceStart: var currentEntry = (ODataResource)lazyReader.Value.Item; if (readItems.Count > 0) { ODataResourceSet feed = readItems.Peek() as ODataResourceSet; if (feed != null) { var annotation = feed.GetAnnotation <ODataFeedEntriesObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataFeedEntriesObjectModelAnnotation(); feed.SetAnnotation(annotation); } annotation.Add((ODataResource)lazyReader.Value.Item); } else { ODataNestedResourceInfo navLink = (ODataNestedResourceInfo)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.NestedResourceInfoStart: ODataResource entry = (ODataResource)readItems.Peek(); var navLinksAnnotation = entry.GetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>(); if (navLinksAnnotation == null) { navLinksAnnotation = new ODataEntryNavigationLinksObjectModelAnnotation(); entry.SetAnnotation(navLinksAnnotation); } navLinksAnnotation.Add((ODataNestedResourceInfo)lazyReader.Value.Item, entry.Properties.Count() + navLinksAnnotation.Count); readItems.Push(lazyReader.Value.Item); break; case ODataReaderState.ResourceEnd: case ODataReaderState.ResourceSetEnd: case ODataReaderState.NestedResourceInfoEnd: if (readItems.Count() > 1) { readItems.Pop(); } break; } } this.expectedStates.Clear(); }