Example #1
0
        private static void SnapExpandedEntry(List <DeltaSnapshotEntry> results, object element, IEdmNavigationSource edmParent, IEnumerable <ExpandedNavigationSelectItem> expandedNavigationItems, string parentId)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                if (expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                    expandedNavigationItem.HandleWith(expandItemHandler);
                    var propertyValue = expandItemHandler.ExpandedChildElement;

                    if (propertyValue != null)
                    {
                        IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                        if (isCollection)
                        {
                            SnapResults(results, propertyValue as IEnumerable, targetSource as IEdmEntitySetBase, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                        else
                        {
                            SnapResult(results, propertyValue, targetSource, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Converts an item from the data store into an ODataEntityReferenceLink.
        /// </summary>
        /// <param name="element">The item to convert.</param>
        /// <param name="navigationSource">The navigation source that the item belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <returns>The converted ODataEntityReferenceLink represent with ODataEntry.</returns>
        public static ODataResource ConvertToODataEntityReferenceLink(object element, IEdmNavigationSource entitySource, ODataVersion targetVersion)
        {
            IEdmStructuredType entityType = EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element) as IEdmStructuredType;

            if (entityType == null)
            {
                throw new InvalidOperationException("Can not create an entry for " + entitySource.Name);
            }

            var link = new ODataResource();

            if (!string.IsNullOrEmpty(((ClrObject)element).EntitySetName) && entitySource is IEdmEntitySet && entityType is IEdmEntityType)
            {
                entitySource = new EdmEntitySet(((IEdmEntitySet)entitySource).Container, ((ClrObject)element).EntitySetName, (IEdmEntityType)entityType);
            }

            if (!(entitySource is IEdmContainedEntitySet))
            {
                Uri Url = BuildEntryUri(element, entitySource, targetVersion);
                link.Id = Url;
            }

            // This is workaround now to make Photo/$ref works or it will fail validation as it is MediaEntity but no stream
            if (Utility.IsMediaEntity(element.GetType()))
            {
                var streamProvider = DataSourceManager.GetCurrentDataSource().StreamProvider;
                link.MediaResource = new ODataStreamReferenceValue()
                {
                    ContentType = streamProvider.GetContentType(element),
                    ETag        = streamProvider.GetETag(element),
                };
            }
            return(link);
        }
Example #3
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable <ExpandedNavigationSelectItem> expandedNavigationItems)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                // For Atom, we always manually write out the links for the navigation properties off of the entity type
                // Or if the navigation is expanded, we manually write out the links for the navigation properties along with the expanded entries
                if (writer.GetType().Name != "ODataJsonLightWriter" || expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    var navigationLink = new ODataNavigationLink
                    {
                        IsCollection = isCollection,
                        Name         = navigationProperty.Name,
                    };

                    if (writer.GetType().Name == "ODataAtomWriter")
                    {
                        //If the passed in parentEntryUri is null then exception will be thrown, to avoid this, create a relative 'potato' Uri.
                        navigationLink.Url = (parentEntryUri == null) ? new Uri("potato", UriKind.Relative) : new Uri(new Uri(parentEntryUri.AbsoluteUri + "/"), navigationProperty.Name);
                    }

                    writer.WriteStart(navigationLink);

                    if (expandedNavigationItem != null)
                    {
                        ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                        expandedNavigationItem.HandleWith(expandItemHandler);
                        var propertyValue = expandItemHandler.ExpandedChildElement;

                        if (propertyValue != null)
                        {
                            IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                            if (isCollection)
                            {
                                long?count           = null;
                                var  collectionValue = propertyValue as IEnumerable;
                                if (collectionValue != null && expandedNavigationItem.CountOption == true)
                                {
                                    count = collectionValue.Cast <object>().LongCount();
                                }
                                WriteFeed(writer, collectionValue, targetSource as IEdmEntitySetBase, targetVersion, expandedNavigationItem.SelectAndExpand, count, null, null);
                            }
                            else
                            {
                                WriteEntry(writer, propertyValue, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand);
                            }
                        }
                    }

                    writer.WriteEnd();
                }
            }
        }
        /// <summary>
        /// Converts an item from the data store into an ODataEntityReferenceLink.
        /// </summary>
        /// <param name="element">The item to convert.</param>
        /// <param name="navigationSource">The navigation source that the item belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <returns>The converted ODataEntityReferenceLink represent with ODataEntry.</returns>
        public static ODataEntry ConvertToODataEntityReferenceLink(object element, IEdmNavigationSource entitySource, ODataVersion targetVersion)
        {
            IEdmStructuredType entityType = EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element) as IEdmStructuredType;

            if (entityType == null)
            {
                throw new InvalidOperationException("Can not create an entry for " + entitySource.Name);
            }

            var link = new ODataEntry();

            if (!string.IsNullOrEmpty(((ClrObject)element).EntitySetName) && entitySource is IEdmEntitySet && entityType is IEdmEntityType)
            {
                entitySource = new EdmEntitySet(((IEdmEntitySet)entitySource).Container, ((ClrObject)element).EntitySetName, (IEdmEntityType)entityType);
            }

            if (!(entitySource is IEdmContainedEntitySet))
            {
                Uri Url = BuildEntryUri(element, entitySource, targetVersion);
                link.Id = Url;
            }

            return(link);
        }
Example #5
0
        /// <summary>
        /// Converts an item from the data store into an ODataEntry.
        /// </summary>
        /// <param name="element">The item to convert.</param>
        /// <param name="navigationSource">The navigation source that the item belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <returns>The converted ODataEntry.</returns>
        public static ODataResourceWrapper ConvertToODataEntry(object element, IEdmNavigationSource entitySource, ODataVersion targetVersion)
        {
            IEdmStructuredType entityType = EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element) as IEdmStructuredType;

            if (entityType == null)
            {
                throw new InvalidOperationException("Can not create an entry for " + entitySource.Name);
            }

            var propertiesOrNestedResourceInfos = GetPropertiesOrNestedResourceInfos(element, entityType);
            var entry = new ODataResource
            {
                Properties = propertiesOrNestedResourceInfos.OfType <ODataProperty>(),
            };

            var resourceWrapper = new ODataResourceWrapper()
            {
                Resource = entry,
                NestedResourceInfoWrappers = propertiesOrNestedResourceInfos.OfType <ODataNestedResourceInfoWrapper>().ToList(),
            };

            // Add Annotation in Entity Level
            if (((ClrObject)element).Annotations != null)
            {
                foreach (InstanceAnnotationType annotation in ((ClrObject)element).Annotations)
                {
                    if (string.IsNullOrEmpty(annotation.Target))
                    {
                        entry.InstanceAnnotations.Add(new ODataInstanceAnnotation(annotation.Name, annotation.ConvertValueToODataValue()));
                    }
                }
            }

            // Work around for entities from different entity set.
            if (!string.IsNullOrEmpty(((ClrObject)element).EntitySetName) && entitySource is IEdmEntitySet && entityType is IEdmEntityType)
            {
                entitySource = new EdmEntitySet(((IEdmEntitySet)entitySource).Container, ((ClrObject)element).EntitySetName, (IEdmEntityType)entityType);
            }

            string typeName;

            if (entityType is IEdmEntityType)
            {
                typeName = (entityType as IEdmEntityType).Name;
            }
            else if (entityType is IEdmComplexType)
            {
                typeName = (entityType as IEdmComplexType).Name;
            }
            else
            {
                throw new InvalidOperationException("Not Supported Edmtype to convert to OData Entry.");
            }
            entry.TypeName = element.GetType().Namespace + "." + typeName;

            // TODO: work around for now
            if (entitySource != null && !(entitySource is IEdmContainedEntitySet))
            {
                Uri entryUri = BuildEntryUri(element, entitySource, targetVersion);
                if (element.GetType().BaseType != null && entitySource.EntityType().Name != typeName)
                {
                    var editLink = new Uri(entryUri.AbsoluteUri.TrimEnd('/') + "/" + entry.TypeName);
                    entry.EditLink = editLink;
                    entry.ReadLink = editLink;
                }
                else
                {
                    entry.EditLink = entryUri;
                    entry.ReadLink = entryUri;
                }
                entry.Id = entryUri;
            }

            if (Utility.IsMediaEntity(element.GetType()))
            {
                var streamProvider = DataSourceManager.GetCurrentDataSource().StreamProvider;
                entry.MediaResource = new ODataStreamReferenceValue()
                {
                    ContentType = streamProvider.GetContentType(element),
                    ETag        = streamProvider.GetETag(element),
                };
            }

            return(resourceWrapper);
        }
        public static object CreateODataValue(object value)
        {
            if (value != null)
            {
                Type t = value.GetType();
                if (t.IsGenericType)
                {
                    // Build a collection type property
                    string itemTypeName = t.GetGenericArguments().First().FullName;
                    if (itemTypeName == "System.UInt16" || itemTypeName == "System.UInt32" || itemTypeName == "System.UInt64")
                    {
                        string modelNS = DataSourceManager.GetCurrentDataSource().Model.DeclaredNamespaces.First();
                        itemTypeName = itemTypeName.Replace("System", modelNS);
                    }
                    else if (itemTypeName == "System.TimeSpan")
                    {
                        itemTypeName = "Edm.Duration";
                    }
                    else
                    {
                        itemTypeName = itemTypeName.Replace("System.", "Edm.");
                    }

                    var genericTypeName      = "Collection(" + itemTypeName + ")";
                    ICollection <object> tmp = new Collection <object>();
                    foreach (var o in (value as IEnumerable))
                    {
                        tmp.Add(CreateODataValue(o));
                    }
                    return(new ODataCollectionValue()
                    {
                        TypeName = genericTypeName, Items = tmp
                    });
                }
                else if (t.Namespace != "System" && !t.Namespace.StartsWith("Microsoft.Data.Spatial") && !t.Namespace.StartsWith("Microsoft.OData.Edm.Library"))
                {
                    if (t.IsEnum == true)
                    {
                        return(new ODataEnumValue(value.ToString(), t.FullName));
                    }
                    else
                    {
                        // Build a complex type property. We consider type t to be primitive if t.Namespace is  "System" or if t is spatial type.
                        List <ODataProperty> properties     = new List <ODataProperty>();
                        IEdmStructuredType   structuredType = (IEdmStructuredType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, value);
                        foreach (var p in GetProperties(value, structuredType))
                        {
                            if (t.GetProperty(p.Name) != null)
                            {
                                properties.Add(p);
                            }
                            else if (structuredType.IsOpen)
                            {
                                var instance = value as OpenClrObject;
                                properties.Add(CreateODataProperty(instance.OpenProperties[p.Name], p.Name));
                            }
                        }

                        var complexValue = new ODataComplexValue()
                        {
                            TypeName = t.FullName, Properties = properties,
                        };

                        // Add Annotation in complex level
                        if (((ClrObject)value).Annotations != null)
                        {
                            foreach (InstanceAnnotationType annotation in ((ClrObject)value).Annotations)
                            {
                                if (string.IsNullOrEmpty(annotation.Target))
                                {
                                    complexValue.InstanceAnnotations.Add(new ODataInstanceAnnotation(annotation.Name, annotation.ConvertValueToODataValue()));
                                }
                            }
                        }
                        return(complexValue);
                    }
                }
            }
            return(value);
        }