Ejemplo n.º 1
0
        private void ReadDeltaResourceSetInline(ODataDeltaResourceSetWrapper resourceSetWrapper, IEdmTypeReference edmType,
                                                ODataDeserializerContext readContext, out System.Collections.ICollection modifiedItems, out ICollection deletedItems)
        {
            Contract.Assert(resourceSetWrapper != null);
            Contract.Assert(edmType != null);
            Contract.Assert(readContext != null);

            IEdmModel model = readContext.Model;
            IEdmStructuredTypeReference structuredType = edmType.AsCollection().ElementType().AsStructured();
            Type clrItemType = EdmLibHelpers.GetClrType(structuredType, model);
            Type deltaType   = typeof(Delta <>).MakeGenericType(clrItemType);

            IList addedResult = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(deltaType));

            foreach (ODataResourceWrapper resourceItemWrapper in resourceSetWrapper.Resources)
            {
                IEnumerable <string> updatableProperties = GetUpdatableProperties(model, structuredType);

                Delta resourceItem = (Delta)Activator.CreateInstance(deltaType, clrItemType, updatableProperties);
                ApplyResourceProperties(resourceItem, resourceItemWrapper, structuredType, readContext);

                addedResult.Add(resourceItem);
            }

            modifiedItems = addedResult;

            IList deletedResult = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(clrItemType));

            foreach (ODataDeletedResourceWrapper deletedItem in resourceSetWrapper.DeletedResources)
            {
                object resourceItem = Activator.CreateInstance(clrItemType);
                ApplyResourceProperties(resourceItem, deletedItem, structuredType, readContext);

                deletedResult.Add(resourceItem);
            }

            deletedItems = deletedResult;
        }
Ejemplo n.º 2
0
        private void ApplyDeltaResourceSetInNestedProperty(IEdmProperty nestedProperty, object resource,
                                                           ODataDeltaResourceSetWrapper resourceSetWrapper, ODataDeserializerContext readContext)
        {
            Contract.Assert(nestedProperty != null);
            Contract.Assert(resource != null);
            Contract.Assert(readContext != null);

            if (!readContext.IsDeltaOfT)
            {
                throw new ODataException("Read context of @odata.delta incorrect");
            }

            ICollection modifiedItems;
            ICollection deletedItems;

            ReadDeltaResourceSetInline(resourceSetWrapper, nestedProperty.Type, readContext, out modifiedItems, out deletedItems);

            IDelta resourceDelta = (IDelta)resource;

            string propertyName = EdmLibHelpers.GetClrPropertyName(nestedProperty, readContext.Model);

            resourceDelta.TrySetPropertyCollectionValue(propertyName, modifiedItems);
            resourceDelta.TrySetDeletedPropertyValue(propertyName, deletedItems);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Deserializes the nested property from <paramref name="resourceInfoWrapper"/> into <paramref name="resource"/>.
        /// </summary>
        /// <param name="resource">The object into which the nested property should be read.</param>
        /// <param name="resourceInfoWrapper">The nested resource info.</param>
        /// <param name="structuredType">The type of the resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNestedProperty(object resource, ODataNestedResourceInfoWrapper resourceInfoWrapper,
                                                IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
        {
            if (resource == null)
            {
                throw Error.ArgumentNull("resource");
            }

            if (resourceInfoWrapper == null)
            {
                throw Error.ArgumentNull("resourceInfoWrapper");
            }

            IEdmProperty edmProperty = structuredType.FindProperty(resourceInfoWrapper.NestedResourceInfo.Name);

            if (edmProperty == null)
            {
                if (!structuredType.IsOpen())
                {
                    throw new ODataException(
                              Error.Format(SRResources.NestedPropertyNotfound, resourceInfoWrapper.NestedResourceInfo.Name,
                                           structuredType.FullName()));
                }
            }

            foreach (ODataItemBase childItem in resourceInfoWrapper.NestedItems)
            {
                // it maybe null.
                if (childItem == null)
                {
                    if (edmProperty == null)
                    {
                        // for the dynamic, OData.net has a bug. see https://github.com/OData/odata.net/issues/977
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, null, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, null, readContext);
                    }
                }

                ODataEntityReferenceLinkBase entityReferenceLink = childItem as ODataEntityReferenceLinkBase;
                if (entityReferenceLink != null)
                {
                    // ignore entity reference links.
                    continue;
                }

                ODataResourceSetWrapper resourceSetWrapper = childItem as ODataResourceSetWrapper;
                if (resourceSetWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceSetInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name,
                                                                resource, structuredType, resourceSetWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceSetInNestedProperty(edmProperty, resource, resourceSetWrapper, readContext);
                    }

                    continue;
                }

                ODataDeltaResourceSetWrapper deltaResourceSetWrapper = childItem as ODataDeltaResourceSetWrapper;
                if (deltaResourceSetWrapper != null)
                {
                    if (edmProperty != null)
                    {
                        ApplyDeltaResourceSetInNestedProperty(edmProperty, resource, deltaResourceSetWrapper, readContext);
                    }

                    // Note: we do not deal with dynamic resource

                    continue;
                }

                // It must be resource by now.
                ODataResourceWrapper resourceWrapper = (ODataResourceWrapper)childItem;
                if (resourceWrapper != null)
                {
                    if (edmProperty == null)
                    {
                        ApplyDynamicResourceInNestedProperty(resourceInfoWrapper.NestedResourceInfo.Name, resource,
                                                             structuredType, resourceWrapper, readContext);
                    }
                    else
                    {
                        ApplyResourceInNestedProperty(edmProperty, resource, resourceWrapper, readContext);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        private static void ReadCollectionItem(ODataReader reader, Stack <ODataItemBase> itemsStack, ref ODataItemBase topLevelItem)
        {
            switch (reader.State)
            {
            case ODataReaderState.ResourceStart:
                ODataResource        resource        = (ODataResource)reader.Item;
                ODataResourceWrapper resourceWrapper = null;
                if (resource != null)
                {
                    resourceWrapper = new ODataResourceWrapper(resource);
                }

                if (itemsStack.Count == 0)
                {
                    Contract.Assert(resource != null, "The top-level resource can never be null.");
                    topLevelItem = resourceWrapper;
                }
                else
                {
                    ODataItemBase           parentItem        = itemsStack.Peek();
                    ODataResourceSetWrapper parentResourceSet = parentItem as ODataResourceSetWrapper;
                    if (parentResourceSet != null)
                    {
                        parentResourceSet.Resources.Add(resourceWrapper);
                    }
                    else
                    {
                        ODataNestedResourceInfoWrapper parentNestedResource = parentItem as ODataNestedResourceInfoWrapper;

                        if (parentNestedResource != null)
                        {
                            Contract.Assert(parentNestedResource.NestedResourceInfo.IsCollection == false, "Only singleton nested properties can contain resource as their child.");
                            Contract.Assert(parentNestedResource.NestedItems.Count == 0, "Each nested property can contain only one resource as its direct child.");
                            parentNestedResource.NestedItems.Add(resourceWrapper);
                        }
                        else
                        {
                            ODataDeltaResourceSetWrapper parentDeltaSetResource = (ODataDeltaResourceSetWrapper)parentItem;
                            parentDeltaSetResource.Resources.Add(resourceWrapper);
                        }
                    }
                }

                itemsStack.Push(resourceWrapper);
                break;

            case ODataReaderState.ResourceEnd:
                Contract.Assert(
                    itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item),
                    "The resource which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.NestedResourceInfoStart:
                ODataNestedResourceInfo nestedResourceInfo = (ODataNestedResourceInfo)reader.Item;
                Contract.Assert(nestedResourceInfo != null, "nested resource info should never be null.");

                ODataNestedResourceInfoWrapper nestedResourceInfoWrapper = new ODataNestedResourceInfoWrapper(nestedResourceInfo);
                Contract.Assert(itemsStack.Count > 0, "nested resource info can't appear as top-level item.");
                {
                    ODataResourceWrapper parentResource = (ODataResourceWrapper)itemsStack.Peek();
                    parentResource.NestedResourceInfos.Add(nestedResourceInfoWrapper);
                }

                itemsStack.Push(nestedResourceInfoWrapper);
                break;

            case ODataReaderState.NestedResourceInfoEnd:
                Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item,
                                "The nested resource info which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.ResourceSetStart:
                ODataResourceSet resourceSet = (ODataResourceSet)reader.Item;
                Contract.Assert(resourceSet != null, "ResourceSet should never be null.");

                ODataResourceSetWrapper resourceSetWrapper = new ODataResourceSetWrapper(resourceSet);
                if (itemsStack.Count > 0)
                {
                    ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner resource set. inner resource sets always have a nested resource info.");
                    Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain resource set as their child.");
                    parentNestedResourceInfo.NestedItems.Add(resourceSetWrapper);
                }
                else
                {
                    topLevelItem = resourceSetWrapper;
                }

                itemsStack.Push(resourceSetWrapper);
                break;

            case ODataReaderState.ResourceSetEnd:
                Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The resource set 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.");
                {
                    ODataNestedResourceInfoWrapper parentNavigationLink = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper);
                }

                break;

            case ODataReaderState.DeltaResourceSetStart:

                ODataDeltaResourceSet deltaResourceSet = (ODataDeltaResourceSet)reader.Item;
                Contract.Assert(deltaResourceSet != null, "ResourceSet should never be null.");

                ODataDeltaResourceSetWrapper deltaResourceSetWrapper = new ODataDeltaResourceSetWrapper(deltaResourceSet);
                if (itemsStack.Count > 0)
                {
                    ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner resource set. inner resource sets always have a nested resource info.");
                    Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain resource set as their child.");
                    parentNestedResourceInfo.NestedItems.Add(deltaResourceSetWrapper);
                }
                else
                {
                    topLevelItem = deltaResourceSetWrapper;
                }

                itemsStack.Push(deltaResourceSetWrapper);

                break;

            case ODataReaderState.DeltaResourceSetEnd:

                Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The resource set which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.DeletedResourceStart:
                ODataDeletedResource deletedResource = (ODataDeletedResource)reader.Item;

                if (deletedResource != null)
                {
                    // Note: I expect that deleted resourced will not have other nested resources

                    ODataDeletedResourceWrapper deletedResourceWrapper = new ODataDeletedResourceWrapper(deletedResource);
                    ODataItemBase parentItem = itemsStack.Peek();
                    ODataDeltaResourceSetWrapper parentDeltaSetResource = parentItem as ODataDeltaResourceSetWrapper;

                    if (parentDeltaSetResource != null)
                    {
                        parentDeltaSetResource.DeletedResources.Add(deletedResourceWrapper);
                    }
                }

                break;

            case ODataReaderState.DeletedResourceEnd:
                break;

            default:
                Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
                break;
            }
        }