/// <summary>
        /// Parse the constant entity node.
        /// </summary>
        /// <param name="nodeIn">The input constant node.</param>
        /// <returns>The parsed object.</returns>
        private object ParseEntity(ConstantNode nodeIn)
        {
            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
            InMemoryMessage            message  = new InMemoryMessage()
            {
                Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(nodeIn.LiteralText)),
            };

            var resourceType = (nodeIn.TypeReference as IEdmStructuredTypeReference).Definition as IEdmStructuredType;

            using (
                ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, settings,
                                                                   this.UriParser.Model))
            {
                if (nodeIn.LiteralText.Contains("@odata.id"))
                {
                    ODataEntityReferenceLink referenceLink = reader.ReadEntityReferenceLink();
                    var queryContext = new QueryContext(this.UriParser.ServiceRoot, referenceLink.Url,
                                                        this.DataSource.Model, this.UriParser.Container);
                    var target = queryContext.ResolveQuery(this.DataSource);
                    return(target);
                }

                var entityType = resourceType as IEdmEntityType;

                var entryReader = reader.CreateODataUriParameterResourceReader(
                    entityType == null ? null : new EdmEntitySet(new EdmEntityContainer("NS", "Test"), "TestType", entityType),
                    resourceType);
                return(ODataObjectModelConverter.ReadEntityOrEntityCollection(entryReader, false));
            }
        }
Exemple #2
0
        /// <summary>
        /// Writes an OData entry.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the entry.</param>
        /// <param name="element">The item from the data store to write.</param>
        /// <param name="navigationSource">The navigation source in the model that the entry belongs to.</param>
        /// <param name="model">The data store model.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteEntry(ODataWriter writer, object element, IEdmNavigationSource entitySource, ODataVersion targetVersion, SelectExpandClause selectExpandClause, Dictionary <string, string> incomingHeaders = null)
        {
            var entry = ODataObjectModelConverter.ConvertToODataEntry(element, entitySource, targetVersion);

            entry.ETag = Utility.GetETagValue(element);

            if (selectExpandClause != null && selectExpandClause.SelectedItems.OfType <PathSelectItem>().Any())
            {
                ExpandSelectItemHandler selectItemHandler = new ExpandSelectItemHandler(entry);
                foreach (var item in selectExpandClause.SelectedItems.OfType <PathSelectItem>())
                {
                    item.HandleWith(selectItemHandler);
                }

                entry = selectItemHandler.ProjectedEntry;
            }

            CustomizeEntry(incomingHeaders, entry);

            writer.WriteStart(entry);

            // gets all of the expandedItems, including ExpandedRefernceSelectItem and ExpandedNavigationItem
            var expandedItems = selectExpandClause == null ? null : selectExpandClause.SelectedItems.OfType <ExpandedReferenceSelectItem>();

            WriteNavigationLinks(writer, element, entry.ReadLink, entitySource, targetVersion, expandedItems);
            writer.WriteEnd();
        }
Exemple #3
0
        /// <summary>
        /// Writes a ReferenceLink
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the ReferenceLink.</param>
        public static void WriteReferenceLink(ODataWriter writer, object element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
        {
            ODataEntry entry = ODataObjectModelConverter.ConvertToODataEntityReferenceLink(element, entitySource, targetVersion);

            entry.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.AnnotationByEntry", new ODataPrimitiveValue(true)));
            writer.WriteStart(entry);
            writer.WriteEnd();
        }
        private static void SnapResult(List <DeltaSnapshotEntry> results, object entry, IEdmNavigationSource entitySource, SelectExpandClause selectExpandClause, string parentId, string relationShip)
        {
            var oDataEntry = ODataObjectModelConverter.ConvertToODataEntry(entry, entitySource, ODataVersion.V4);

            results.Add(new DeltaSnapshotEntry(oDataEntry.Id.AbsoluteUri, parentId, relationShip));
            var expandedNavigationItems = selectExpandClause == null ? null : selectExpandClause.SelectedItems.OfType <ExpandedNavigationSelectItem>();

            SnapExpandedEntry(results, entry, entitySource, expandedNavigationItems, oDataEntry.Id.AbsoluteUri);
        }
Exemple #5
0
        /// <summary>
        /// Create the CLR object given an ODataProperty.
        /// </summary>
        /// <param name="propertyValue">The value of the ODataProperty.</param>
        /// <param name="propertyType">The CLR type to be converted to.</param>
        /// <returns>The CLR object.</returns>
        public static object ConvertPropertyValue(object propertyValue, Type propertyType)
        {
            if (propertyValue == null)
            {
                return(null);
            }

            bool isNullable = propertyType.IsNullable();
            Type propertyUnderlyingType;

            if (isNullable)
            {
                propertyUnderlyingType = Nullable.GetUnderlyingType(propertyType);
            }
            else
            {
                propertyUnderlyingType = propertyType;
            }

            if (propertyUnderlyingType == typeof(DateTime) && !(propertyValue is DateTime))
            {
                return(XmlConvert.ToDateTimeOffset(propertyValue.ToString()));
            }
            else if (propertyUnderlyingType == typeof(float))
            {
                return(Convert.ToSingle(propertyValue));
            }
            else if (propertyUnderlyingType.IsEnum)
            {
                ODataEnumValue enumValue = (ODataEnumValue)propertyValue;
                return(Enum.Parse(propertyUnderlyingType, enumValue.Value));
            }
            else if (propertyUnderlyingType.IsGenericType && propertyValue is IEnumerable)
            {
                var collection = Utility.QuickCreateInstance(propertyUnderlyingType);

                foreach (var item in propertyValue as IEnumerable)
                {
                    var itemType       = propertyUnderlyingType.GetGenericArguments().Single();
                    var collectionItem = ODataObjectModelConverter.ConvertPropertyValue(item, itemType);

                    propertyUnderlyingType.GetMethod("Add").Invoke(collection, new object[] { collectionItem });
                }

                return(collection);
            }

            return(propertyValue);
        }
        /// <summary>
        /// Parse the constant entity collection node.
        /// </summary>
        /// <param name="nodeIn">The input constant node.</param>
        /// <returns>The parsed object.</returns>
        private object ParseEntityCollection(ConstantNode nodeIn)
        {
            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
            InMemoryMessage            message  = new InMemoryMessage()
            {
                Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(nodeIn.LiteralText)),
            };

            var resourceType =
                ((nodeIn.TypeReference.Definition as IEdmCollectionType).ElementType as IEdmStructuredTypeReference)
                .Definition as IEdmStructuredType;
            object     list      = null;
            MethodInfo addMethod = null;

            using (
                ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, settings,
                                                                   this.UriParser.Model))
            {
                if (nodeIn.LiteralText.Contains("@odata.id"))
                {
                    ODataEntityReferenceLinks referenceLinks = reader.ReadEntityReferenceLinks();
                    foreach (var referenceLink in referenceLinks.Links)
                    {
                        var queryContext = new QueryContext(this.UriParser.ServiceRoot, referenceLink.Url,
                                                            this.DataSource.Model, this.UriParser.Container);
                        var target = queryContext.ResolveQuery(this.DataSource);

                        if (list == null)
                        {
                            // create the list. This would require the first type is not derived type.
                            Type listType = typeof(List <>).MakeGenericType(target.GetType());
                            addMethod = listType.GetMethod("Add");
                            list      = Activator.CreateInstance(listType);
                        }

                        addMethod.Invoke(list, new[] { target });
                    }

                    return(list);
                }

                var entityType = resourceType as IEdmEntityType;
                var feedReader = reader.CreateODataUriParameterResourceSetReader(
                    entityType == null ? null : new EdmEntitySet(new EdmEntityContainer("NS", "Test"), "TestType", entityType),
                    resourceType);

                return(ODataObjectModelConverter.ReadEntityOrEntityCollection(feedReader, true));
            }
        }
Exemple #7
0
        /// <summary>
        /// Writes a ReferenceLinks
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the ReferenceLinks.</param>
        public static void WriteReferenceLinks(ODataWriter writer, IEnumerable element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
        {
            IEnumerable <ODataEntry> links = ODataObjectModelConverter.ConvertToODataEntityReferenceLinks(element, entitySource, targetVersion);
            var feed = new ODataFeed {
            };

            writer.WriteStart(feed);
            foreach (var entry in links)
            {
                entry.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.AnnotationByFeed", new ODataPrimitiveValue(true)));
                writer.WriteStart(entry);
                writer.WriteEnd();
            }
            writer.WriteEnd();
        }
Exemple #8
0
        /// <summary>
        /// Visit a ConstantNode
        /// </summary>
        /// <param name="nodeIn">The node to visit</param>
        /// <returns>The translated expression</returns>
        public override Expression Visit(ConstantNode nodeIn)
        {
            this.CheckArgumentNull(nodeIn, "ConstantNode");
            if (null == nodeIn.Value)
            {
                return(Expression.Constant(null));
            }

            // collection of entity
            if (nodeIn.TypeReference != null && nodeIn.TypeReference.IsCollection() &&
                (nodeIn.TypeReference.Definition as IEdmCollectionType).ElementType.IsEntity())
            {
                return(Expression.Constant(ParseEntityCollection(nodeIn)));
            }

            // the value is entity or entity reference.
            if (nodeIn.TypeReference != null && nodeIn.TypeReference.IsEntity())
            {
                return(Expression.Constant(ParseEntity(nodeIn)));
            }
            // the value is complex or collection.
            if (nodeIn.Value is ODataComplexValue || nodeIn.Value is ODataCollectionValue || nodeIn.Value is ODataEntry)
            {
                object value = ODataObjectModelConverter.ConvertPropertyValue(nodeIn.Value);
                return(Expression.Constant(value));
            }

            // the value is enum
            if (nodeIn.TypeReference.IsEnum())
            {
                ODataEnumValue enumValue  = (ODataEnumValue)nodeIn.Value;
                object         enumClrVal = Enum.Parse(EdmClrTypeUtils.GetInstanceType(enumValue.TypeName), enumValue.Value);
                return(Expression.Constant(enumClrVal, EdmClrTypeUtils.GetInstanceType(nodeIn.TypeReference)));
            }

            // the value is primitive
            Type targetType = nodeIn.Value.GetType();

            if (nodeIn.TypeReference.IsSpatial())
            {
                targetType = GetPublicSpatialBaseType(nodeIn.Value);
            }

            return(Expression.Constant(nodeIn.Value, targetType));
        }
Exemple #9
0
        /// <summary>
        /// Parse the constant entity node.
        /// </summary>
        /// <param name="nodeIn">The input constant node.</param>
        /// <returns>The parsed object.</returns>
        private object ParseEntity(ConstantNode nodeIn)
        {
            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
            InMemoryMessage            message  = new InMemoryMessage()
            {
                Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(nodeIn.LiteralText)),
            };

            var entityType = (nodeIn.TypeReference as IEdmEntityTypeReference).Definition as IEdmEntityType;

            using (
                ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, settings,
                                                                   this.UriParser.Model))
            {
                if (nodeIn.LiteralText.Contains("@odata.id"))
                {
                    ODataEntityReferenceLink referenceLink = reader.ReadEntityReferenceLink();
                    var queryContext = new QueryContext(this.UriParser.ServiceRoot, referenceLink.Url,
                                                        this.DataSource.Model);
                    var target = queryContext.ResolveQuery(this.DataSource);
                    return(target);
                }

                var entryReader = reader.CreateODataEntryReader(
                    new EdmEntitySet(new EdmEntityContainer("NS", "Test"), "TestType", entityType),
                    entityType);
                ODataEntry entry = null;
                while (entryReader.Read())
                {
                    if (entryReader.State == ODataReaderState.EntryEnd)
                    {
                        entry = entryReader.Item as ODataEntry;
                    }
                }
                return(ODataObjectModelConverter.ConvertPropertyValue(entry));
            }
        }
Exemple #10
0
        public static object ReadEntityOrEntityCollection(ODataReader reader, bool forFeed)
        {
            MethodInfo addMethod = null;

            // Store the last entry of the top-level feed or the top-level entry;
            ODataResource entry = null;

            // Store entries at each level
            Stack <ODataItem> items = new Stack <ODataItem>();

            // Store the objects with its parent for current level.
            // Example:
            //    CompleCollection: [ complex1, complex2 ]
            //    objects contains [{CompleCollection, complex1Obj}, {CompleCollection, complex2Obj}] when NestedResourceInfoEnd for CompleCollection
            Stack <KeyValuePair <ODataItem, object> > objects = new Stack <KeyValuePair <ODataItem, object> >();

            // Store the SetValue action for complex property.
            Stack <KeyValuePair <ODataItem, Action <object> > > actions = new Stack <KeyValuePair <ODataItem, Action <object> > >();

            while (reader.Read())
            {
                switch (reader.State)
                {
                case ODataReaderState.ResourceStart:
                case ODataReaderState.NestedResourceInfoStart:
                {
                    items.Push(reader.Item);
                    break;
                }

                case ODataReaderState.NestedResourceInfoEnd:
                {
                    items.Pop();
                    // Create current complex property value.
                    var currentProperty = reader.Item as ODataNestedResourceInfo;
                    var parent          = items.Peek() as ODataResource;
                    var parentType      = EdmClrTypeUtils.GetInstanceType(parent.TypeName);
                    var propertyInfo    = parentType.GetProperty(currentProperty.Name);
                    if (propertyInfo != null)
                    {
                        var propertyType = propertyInfo.PropertyType;
                        if (propertyType.IsGenericType)
                        {
                            Type listType = typeof(List <>).MakeGenericType(propertyType.GetGenericArguments()[0]);
                            addMethod = listType.GetMethod("Add");
                            var currentList = Activator.CreateInstance(listType);
                            while (objects.Count > 0 && objects.Peek().Key == currentProperty)
                            {
                                addMethod.Invoke(currentList, new[] { objects.Pop().Value });
                            }

                            // Keep the order of all the items
                            MethodInfo reverseMethod = listType.GetMethod("Reverse", new Type[0]);
                            reverseMethod.Invoke(currentList, new object[0]);
                            actions.Push(new KeyValuePair <ODataItem, Action <object> >(parent, obj => propertyInfo.SetValue(obj, currentList)));
                        }
                        else
                        {
                            var propertyValue = objects.Pop().Value;
                            actions.Push(new KeyValuePair <ODataItem, Action <object> >(parent, obj => propertyInfo.SetValue(obj, propertyValue)));
                        }
                    }

                    break;
                }

                case ODataReaderState.ResourceEnd:
                {
                    // Create object for current resource.
                    entry = reader.Item as ODataResource;
                    object item = ODataObjectModelConverter.ConvertPropertyValue(entry);
                    while (actions.Count > 0 && actions.Peek().Key == entry)
                    {
                        actions.Pop().Value.Invoke(item);
                    }

                    items.Pop();
                    var parent = items.Count > 0 ? items.Peek() : null;
                    objects.Push(new KeyValuePair <ODataItem, object>(parent, item));
                    break;
                }

                default:
                    break;
                }
            }
            if (forFeed)
            {
                // create the list. This would require the first type is not derived type.
                List <object> topLeveObjects = new List <object>();
                while (objects.Count > 0)
                {
                    topLeveObjects.Add(objects.Pop().Value);
                }

                Type type = null;
                // Need to fix this if all items in the collection are null;
                if (entry == null || string.IsNullOrEmpty(entry.TypeName))
                {
                    for (int i = 0; i < topLeveObjects.Count; i++)
                    {
                        if (topLeveObjects[i] != null)
                        {
                            type = topLeveObjects[i].GetType();
                            break;
                        }
                    }
                }
                else
                {
                    type = EdmClrTypeUtils.GetInstanceType(entry.TypeName);
                }

                Type listType = typeof(List <>).MakeGenericType(type);
                addMethod = listType.GetMethod("Add");
                var list = Activator.CreateInstance(listType);
                for (int i = topLeveObjects.Count - 1; i >= 0; i--)
                {
                    addMethod.Invoke(list, new[] { topLeveObjects[i] });
                }

                return(list);
            }
            else
            {
                return(objects.Pop().Value);
            }
        }
        public virtual ODataValue ConvertValueToODataValue()
        {
            ODataValue value = ODataObjectModelConverter.CreateODataValue(this.Value) as ODataValue ?? new ODataPrimitiveValue(this.Value);

            return(value);
        }