public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, MaterializerEntry entry)
        {
            MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, entry);

            link.SetAnnotation <MaterializerNavigationLink>(annotation);
            return(annotation);
        }
Example #2
0
        /// <summary>
        /// Reads a navigation link.
        /// </summary>
        /// <returns>A navigation link.</returns>
        private ODataNavigationLink ReadNavigationLink()
        {
            Debug.Assert(this.reader.State == ODataReaderState.NavigationLinkStart, "this.reader.State == ODataReaderState.NavigationLinkStart");

            ODataNavigationLink link = (ODataNavigationLink)this.reader.Item;

            MaterializerEntry entry;
            ODataFeed         feed;

            if (this.TryReadFeedOrEntry(false, out feed, out entry))
            {
                if (feed != null)
                {
                    MaterializerNavigationLink.CreateLink(link, feed);
                }
                else
                {
                    Debug.Assert(entry != null, "entry != null");
                    MaterializerNavigationLink.CreateLink(link, entry);
                }

                this.ReadAndExpectState(ODataReaderState.NavigationLinkEnd);
            }

            this.ExpectState(ODataReaderState.NavigationLinkEnd);

            return(link);
        }
        public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed)
        {
            MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, feed);

            link.SetAnnotation <MaterializerNavigationLink>(annotation);
            return(annotation);
        }
        /// <summary>
        /// Creates the materializer link with a feed.
        /// </summary>
        /// <param name="link">The link.</param>
        /// <param name="feed">The feed.</param>
        /// <returns>The materializer link.</returns>
        public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed)
        {
            Debug.Assert(link.GetAnnotation <MaterializerNavigationLink>() == null, "there should be no MaterializerNavigationLink annotation on the feed link yet");
            MaterializerNavigationLink materializedNavigationLink = new MaterializerNavigationLink(link, feed);

            link.SetAnnotation <MaterializerNavigationLink>(materializedNavigationLink);
            return(materializedNavigationLink);
        }
Example #5
0
        internal static IEnumerable ProjectionSelect(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, Type resultType, ProjectionPath path, Func <object, object, Type, object> selector)
        {
            ClientEdmModel             model = ClientEdmModel.GetModel(materializer.ResponseInfo.MaxProtocolVersion);
            ClientTypeAnnotation       clientTypeAnnotation = entry.ActualType ?? model.GetClientTypeAnnotation(model.GetOrCreateEdmType(expectedType));
            IEnumerable                enumerable           = (IEnumerable)Util.ActivatorCreateInstance(typeof(List <>).MakeGenericType(new Type[] { resultType }), new object[0]);
            MaterializerNavigationLink link     = null;
            ClientPropertyAnnotation   property = null;

            for (int i = 0; i < path.Count; i++)
            {
                ProjectionPathSegment segment = path[i];
                if (segment.SourceTypeAs != null)
                {
                    clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(segment.SourceTypeAs));
                }
                if (segment.Member != null)
                {
                    string member = segment.Member;
                    property = clientTypeAnnotation.GetProperty(member, false);
                    link     = GetPropertyOrThrow(entry.NavigationLinks, member, entry.Id);
                    if (link.Entry != null)
                    {
                        entry = link.Entry;
                        clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(property.PropertyType));
                    }
                }
            }
            ValidatePropertyMatch(property, link.Link);
            MaterializerFeed        feed = MaterializerFeed.GetFeed(link.Feed);
            Action <object, object> addToCollectionDelegate = ODataMaterializer.GetAddToCollectionDelegate(enumerable.GetType());

            foreach (ODataEntry entry2 in feed.Entries)
            {
                object obj2 = selector(materializer, entry2, property.EntityCollectionItemType);
                addToCollectionDelegate(enumerable, obj2);
            }
            ProjectionPlan plan = new ProjectionPlan {
                LastSegmentType = property.EntityCollectionItemType,
                Plan            = selector,
                ProjectedType   = resultType
            };

            materializer.FoundNextLinkForCollection(enumerable, feed.NextPageLink, plan);
            return(enumerable);
        }
Example #6
0
        private static MaterializerNavigationLink GetPropertyOrThrow(IEnumerable <ODataNavigationLink> links, string propertyName, string entryIdentity)
        {
            Func <ODataNavigationLink, bool> predicate = null;
            ODataNavigationLink link = null;

            if (links != null)
            {
                if (predicate == null)
                {
                    predicate = p => p.Name == propertyName;
                }
                link = links.Where <ODataNavigationLink>(predicate).FirstOrDefault <ODataNavigationLink>();
            }
            if (link == null)
            {
                throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyMissing(propertyName, entryIdentity));
            }
            return(MaterializerNavigationLink.GetLink(link));
        }
Example #7
0
            private ODataNavigationLink ReadNavigationLink()
            {
                MaterializerEntry   entry;
                ODataFeed           feed;
                ODataNavigationLink item = (ODataNavigationLink)this.reader.Item;

                if (this.TryReadFeedOrEntry(false, out feed, out entry))
                {
                    if (feed != null)
                    {
                        MaterializerNavigationLink.CreateLink(item, feed);
                    }
                    else
                    {
                        MaterializerNavigationLink.CreateLink(item, entry);
                    }
                    this.ReadAndExpectState(ODataReaderState.NavigationLinkEnd);
                }
                this.ExpectState(ODataReaderState.NavigationLinkEnd);
                return(item);
            }
Example #8
0
        internal static object ProjectionValueForPath(ODataEntityMaterializer materializer, MaterializerEntry entry, Type expectedType, ProjectionPath path)
        {
            if ((path.Count == 0) || ((path.Count == 1) && (path[0].Member == null)))
            {
                if (!entry.EntityHasBeenResolved)
                {
                    materializer.Materialize(entry, expectedType, false);
                }
                return(entry.ResolvedObject);
            }
            object streamLink                = null;
            ODataNavigationLink link         = null;
            ODataProperty       atomProperty = null;
            ICollection <ODataNavigationLink> navigationLinks = entry.NavigationLinks;
            IEnumerable <ODataProperty>       properties      = entry.Entry.Properties;
            ClientEdmModel model = ClientEdmModel.GetModel(materializer.ResponseInfo.MaxProtocolVersion);

            for (int i = 0; i < path.Count; i++)
            {
                Func <StreamDescriptor, bool>    predicate = null;
                Func <ODataNavigationLink, bool> func2     = null;
                Func <ODataProperty, bool>       func3     = null;
                Func <ODataProperty, bool>       func4     = null;
                Func <ODataNavigationLink, bool> func5     = null;
                string propertyName;
                ProjectionPathSegment segment = path[i];
                if (segment.Member != null)
                {
                    bool flag = i == (path.Count - 1);
                    propertyName = segment.Member;
                    expectedType = segment.SourceTypeAs ?? expectedType;
                    ClientPropertyAnnotation property = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(expectedType)).GetProperty(propertyName, false);
                    if (property.IsStreamLinkProperty)
                    {
                        if (predicate == null)
                        {
                            predicate = sd => sd.Name == propertyName;
                        }
                        StreamDescriptor descriptor = entry.EntityDescriptor.StreamDescriptors.Where <StreamDescriptor>(predicate).SingleOrDefault <StreamDescriptor>();
                        if (descriptor == null)
                        {
                            if (segment.SourceTypeAs == null)
                            {
                                throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyMissing(propertyName, entry.Entry.Id));
                            }
                            return(WebUtil.GetDefaultValue <DataServiceStreamLink>());
                        }
                        streamLink = descriptor.StreamLink;
                    }
                    else
                    {
                        if (segment.SourceTypeAs != null)
                        {
                            if (func2 == null)
                            {
                                func2 = p => p.Name == propertyName;
                            }
                            if (!navigationLinks.Any <ODataNavigationLink>(func2))
                            {
                                if (func3 == null)
                                {
                                    func3 = p => p.Name == propertyName;
                                }
                                if (!properties.Any <ODataProperty>(func3) && flag)
                                {
                                    return(WebUtil.GetDefaultValue(property.PropertyType));
                                }
                            }
                        }
                        if (func4 == null)
                        {
                            func4 = p => p.Name == propertyName;
                        }
                        atomProperty = properties.Where <ODataProperty>(func4).FirstOrDefault <ODataProperty>();
                        if (func5 == null)
                        {
                            func5 = p => p.Name == propertyName;
                        }
                        link = ((atomProperty == null) && (navigationLinks != null)) ? navigationLinks.Where <ODataNavigationLink>(func5).FirstOrDefault <ODataNavigationLink>() : null;
                        if ((link == null) && (atomProperty == null))
                        {
                            throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_PropertyMissing(propertyName, entry.Entry.Id));
                        }
                        if (link != null)
                        {
                            ValidatePropertyMatch(property, link);
                            MaterializerNavigationLink link2 = MaterializerNavigationLink.GetLink(link);
                            if (link2.Feed != null)
                            {
                                MaterializerFeed feed = MaterializerFeed.GetFeed(link2.Feed);
                                Type             implementationType = ClientTypeUtil.GetImplementationType(segment.ProjectionType, typeof(ICollection <>));
                                if (implementationType == null)
                                {
                                    implementationType = ClientTypeUtil.GetImplementationType(segment.ProjectionType, typeof(IEnumerable <>));
                                }
                                Type nestedExpectedType = implementationType.GetGenericArguments()[0];
                                Type projectionType     = segment.ProjectionType;
                                if (projectionType.IsInterfaceEx() || ODataMaterializer.IsDataServiceCollection(projectionType))
                                {
                                    projectionType = typeof(Collection <>).MakeGenericType(new Type[] { nestedExpectedType });
                                }
                                IEnumerable list = (IEnumerable)Util.ActivatorCreateInstance(projectionType, new object[0]);
                                MaterializeToList(materializer, list, nestedExpectedType, feed.Entries);
                                if (ODataMaterializer.IsDataServiceCollection(segment.ProjectionType))
                                {
                                    list = (IEnumerable)Util.ActivatorCreateInstance(WebUtil.GetDataServiceCollectionOfT(new Type[] { nestedExpectedType }), new object[] { list, TrackingMode.None });
                                }
                                ProjectionPlan plan = CreatePlanForShallowMaterialization(nestedExpectedType);
                                materializer.FoundNextLinkForCollection(list, feed.Feed.NextPageLink, plan);
                                streamLink = list;
                            }
                            else if (link2.Entry != null)
                            {
                                MaterializerEntry entry2 = link2.Entry;
                                if (flag)
                                {
                                    if ((entry2.Entry != null) && !entry2.EntityHasBeenResolved)
                                    {
                                        materializer.Materialize(entry2, property.PropertyType, false);
                                    }
                                }
                                else
                                {
                                    CheckEntryToAccessNotNull(entry2, propertyName);
                                }
                                properties      = entry2.Properties;
                                navigationLinks = entry2.NavigationLinks;
                                streamLink      = entry2.ResolvedObject;
                                entry           = entry2;
                            }
                        }
                        else
                        {
                            if (atomProperty.Value is ODataStreamReferenceValue)
                            {
                                streamLink      = null;
                                navigationLinks = ODataMaterializer.EmptyLinks;
                                properties      = ODataMaterializer.EmptyProperties;
                                continue;
                            }
                            ValidatePropertyMatch(property, atomProperty);
                            if (ClientTypeUtil.TypeOrElementTypeIsEntity(property.PropertyType))
                            {
                                throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidEntityType(property.EntityCollectionItemType ?? property.PropertyType));
                            }
                            if (property.IsPrimitiveOrComplexCollection)
                            {
                                object instance = streamLink ?? (entry.ResolvedObject ?? Util.ActivatorCreateInstance(expectedType, new object[0]));
                                ODataMaterializer.ApplyDataValue(model.GetClientTypeAnnotation(model.GetOrCreateEdmType(instance.GetType())), atomProperty, materializer.ResponseInfo.IgnoreMissingProperties, materializer.ResponseInfo, instance);
                                navigationLinks = ODataMaterializer.EmptyLinks;
                                properties      = ODataMaterializer.EmptyProperties;
                            }
                            else if (atomProperty.Value is ODataComplexValue)
                            {
                                ODataComplexValue complexValue = atomProperty.Value as ODataComplexValue;
                                ODataMaterializer.MaterializeComplexTypeProperty(property.PropertyType, complexValue, materializer.ResponseInfo.IgnoreMissingProperties, materializer.ResponseInfo);
                                properties      = complexValue.Properties;
                                navigationLinks = ODataMaterializer.EmptyLinks;
                            }
                            else
                            {
                                if ((atomProperty.Value == null) && !ClientTypeUtil.CanAssignNull(property.NullablePropertyType))
                                {
                                    throw new InvalidOperationException(System.Data.Services.Client.Strings.AtomMaterializer_CannotAssignNull(atomProperty.Name, property.NullablePropertyType));
                                }
                                ODataMaterializer.MaterializePrimitiveDataValue(property.NullablePropertyType, atomProperty);
                                navigationLinks = ODataMaterializer.EmptyLinks;
                                properties      = ODataMaterializer.EmptyProperties;
                            }
                            streamLink = atomProperty.GetMaterializedValue();
                        }
                    }
                    expectedType = property.PropertyType;
                }
            }
            return(streamLink);
        }
Example #9
0
        internal static bool ProjectionCheckValueForPathIsNull(MaterializerEntry entry, Type expectedType, ProjectionPath path)
        {
            if ((path.Count == 0) || ((path.Count == 1) && (path[0].Member == null)))
            {
                return(entry.Entry == null);
            }
            bool flag = false;
            MaterializerNavigationLink        link            = null;
            IEnumerable <ODataNavigationLink> navigationLinks = entry.NavigationLinks;
            ClientEdmModel model = ClientEdmModel.GetModel(entry.EntityDescriptor.MaxProtocolVersion);

            for (int i = 0; i < path.Count; i++)
            {
                Func <ODataNavigationLink, bool> predicate = null;
                string propertyName;
                ProjectionPathSegment segment = path[i];
                if (segment.Member != null)
                {
                    bool flag2 = i == (path.Count - 1);
                    propertyName = segment.Member;
                    if (segment.SourceTypeAs != null)
                    {
                        expectedType = segment.SourceTypeAs;
                        if (predicate == null)
                        {
                            predicate = p => p.Name == propertyName;
                        }
                        if (!navigationLinks.Any <ODataNavigationLink>(predicate))
                        {
                            return(true);
                        }
                    }
                    IEdmType orCreateEdmType          = model.GetOrCreateEdmType(expectedType);
                    ClientPropertyAnnotation property = model.GetClientTypeAnnotation(orCreateEdmType).GetProperty(propertyName, false);
                    link = GetPropertyOrThrow(navigationLinks, propertyName, entry.Id);
                    ValidatePropertyMatch(property, link.Link);
                    if (link.Feed != null)
                    {
                        flag = false;
                    }
                    else
                    {
                        if (link.Entry == null)
                        {
                            return(true);
                        }
                        if (flag2)
                        {
                            flag = link.Entry.Entry == null;
                        }
                        else
                        {
                            entry           = link.Entry;
                            navigationLinks = entry.NavigationLinks;
                        }
                    }
                    expectedType = property.PropertyType;
                }
            }
            return(flag);
        }
Example #10
0
        private void MaterializeResolvedEntry(MaterializerEntry entry, bool includeLinks)
        {
            ClientTypeAnnotation actualType = entry.ActualType;

            if (!actualType.IsEntityType)
            {
                throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidNonEntityType(actualType.ElementTypeName));
            }
            ODataMaterializer.MaterializeDataValues(actualType, entry.Properties, base.ResponseInfo.IgnoreMissingProperties);
            if (entry.NavigationLinks != null)
            {
                foreach (ODataNavigationLink link in entry.NavigationLinks)
                {
                    ClientPropertyAnnotation annotation2 = actualType.GetProperty(link.Name, true);
                    if (annotation2 != null)
                    {
                        ValidatePropertyMatch(annotation2, link, base.ResponseInfo, true);
                    }
                }
            }
            if (includeLinks && (entry.NavigationLinks != null))
            {
                foreach (ODataNavigationLink link2 in entry.NavigationLinks)
                {
                    MaterializerNavigationLink link3 = MaterializerNavigationLink.GetLink(link2);
                    if (link3 != null)
                    {
                        ClientPropertyAnnotation annotation3 = actualType.GetProperty(link2.Name, base.ResponseInfo.IgnoreMissingProperties);
                        if (annotation3 != null)
                        {
                            if (link3.Feed != null)
                            {
                                this.ApplyFeedToCollection(entry, annotation3, link3.Feed, includeLinks);
                            }
                            else if (link3.Entry != null)
                            {
                                MaterializerEntry entry2 = link3.Entry;
                                if (entry2.Entry != null)
                                {
                                    this.Materialize(entry2, annotation3.PropertyType, includeLinks);
                                }
                                if (entry.ShouldUpdateFromPayload)
                                {
                                    annotation3.SetValue(entry.ResolvedObject, entry2.ResolvedObject, link2.Name, true);
                                    this.log.SetLink(entry, annotation3.PropertyName, entry2.ResolvedObject);
                                }
                            }
                        }
                    }
                }
            }
            foreach (ODataProperty property in entry.Properties)
            {
                if (!(property.Value is ODataStreamReferenceValue))
                {
                    ClientPropertyAnnotation annotation4 = actualType.GetProperty(property.Name, base.ResponseInfo.IgnoreMissingProperties);
                    if ((annotation4 != null) && entry.ShouldUpdateFromPayload)
                    {
                        ValidatePropertyMatch(annotation4, property, base.ResponseInfo, true);
                        ODataMaterializer.ApplyDataValue(actualType, property, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo, entry.ResolvedObject);
                    }
                }
            }
            ApplyLinkProperties(actualType, entry);
            if (base.ResponseInfo.HasReadingEntityHandlers)
            {
                ODataMaterializer.ReadingEntityInfo annotation = entry.Entry.GetAnnotation <ODataMaterializer.ReadingEntityInfo>();
                base.ResponseInfo.FireReadingEntityEvent(entry.ResolvedObject, annotation.EntryPayload, annotation.BaseUri);
            }
        }
        /// <summary>Materializes the specified <paramref name="entry"/>.</summary>
        /// <param name="entry">Entry with object to materialize.</param>
        /// <param name="includeLinks">Whether links that are expanded should be materialized.</param>
        /// <remarks>This is a payload-driven materialization process.</remarks>
        private void MaterializeResolvedEntry(MaterializerEntry entry, bool includeLinks)
        {
            Debug.Assert(entry.Entry != null, "entry != null");
            Debug.Assert(entry.ResolvedObject != null, "entry.ResolvedObject != null -- otherwise not resolved/created!");

            ClientTypeAnnotation actualType = entry.ActualType;

            // While materializing entities, we need to make sure the payload that came in the wire is also an entity.
            // Otherwise we need to fail.
            if (!actualType.IsEntityType)
            {
                throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidNonEntityType(actualType.ElementTypeName));
            }

            // Note that even if ShouldUpdateFromPayload is false, we will still be creating
            // nested instances (but not their links), so they show up in the data context
            // entries. This keeps this code compatible with V1 behavior.
            this.MaterializeDataValues(actualType, entry.Properties, this.MaterializerContext.IgnoreMissingProperties);

            if (entry.NavigationLinks != null)
            {
                foreach (ODataNavigationLink link in entry.NavigationLinks)
                {
                    var prop = actualType.GetProperty(link.Name, true);
                    if (prop != null)
                    {
                        ValidatePropertyMatch(prop, link, this.MaterializerContext.Model, true /*performEntityCheck*/);
                    }
                }

                if (includeLinks)
                {
                    foreach (ODataNavigationLink link in entry.NavigationLinks)
                    {
                        MaterializerNavigationLink linkState = MaterializerNavigationLink.GetLink(link);

                        // Ignore...
                        if (linkState == null)
                        {
                            continue;
                        }

                        var prop = actualType.GetProperty(link.Name, this.MaterializerContext.IgnoreMissingProperties);

                        if (prop == null)
                        {
                            continue;
                        }

                        if (linkState.Feed != null)
                        {
                            this.ApplyFeedToCollection(entry, prop, linkState.Feed, includeLinks);
                        }
                        else if (linkState.Entry != null)
                        {
                            MaterializerEntry linkEntry = linkState.Entry;

                            if (linkEntry.Entry != null)
                            {
                                Debug.Assert(includeLinks, "includeLinks -- otherwise we shouldn't be materializing this entry");
                                this.Materialize(linkEntry, prop.PropertyType, includeLinks);
                            }

                            if (entry.ShouldUpdateFromPayload)
                            {
                                prop.SetValue(entry.ResolvedObject, linkEntry.ResolvedObject, link.Name, true /* allowAdd? */);
                                this.EntityTrackingAdapter.MaterializationLog.SetLink(entry, prop.PropertyName, linkEntry.ResolvedObject);
                            }
                        }
                    }
                }
            }

            foreach (var e in entry.Properties)
            {
                if (e.Value is ODataStreamReferenceValue)
                {
                    continue;
                }

                var prop = actualType.GetProperty(e.Name, this.MaterializerContext.IgnoreMissingProperties);
                if (prop == null)
                {
                    continue;
                }

                if (entry.ShouldUpdateFromPayload)
                {
                    ValidatePropertyMatch(prop, e, this.MaterializerContext.Model, true /*performEntityCheck*/);

                    this.ApplyDataValue(actualType, e, entry.ResolvedObject);
                }
            }

            // apply link values if present
            ApplyLinkProperties(actualType, entry);

            Debug.Assert(entry.ResolvedObject != null, "entry.ResolvedObject != null -- otherwise we didn't do any useful work");

            this.MaterializerContext.ResponsePipeline.FireEndEntryEvents(entry);
        }
 public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, MaterializerEntry entry)
 {
     MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, entry);
     link.SetAnnotation<MaterializerNavigationLink>(annotation);
     return annotation;
 }
 public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed)
 {
     MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, feed);
     link.SetAnnotation<MaterializerNavigationLink>(annotation);
     return annotation;
 }