Beispiel #1
0
        /// <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++;
        }
Beispiel #2
0
        /// <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)
                });
            }
        }
Beispiel #3
0
        /// <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) });
            }
        }