/// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return null;
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.IsCollection() || !edmType.AsCollection().ElementType().IsEntity())
            {
                throw Error.Argument("edmType", SRResources.TypeMustBeEntityCollection, edmType.ToTraceString(), typeof(IEdmEntityType).Name);
            }

            IEdmEntityTypeReference elementType = edmType.AsCollection().ElementType().AsEntity();

            ODataFeedWithEntries feed = item as ODataFeedWithEntries;
            if (feed == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataFeedWithEntries).Name);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            return ReadFeed(feed, elementType, readContext);
        }
        public override ODataSerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Primitive:
                    return new ODataPrimitiveSerializer(edmType.AsPrimitive());

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return new ODataFeedSerializer(collectionType, this);
                    }
                    else
                    {
                        return new ODataCollectionSerializer(collectionType, this);
                    }

                case EdmTypeKind.Complex:
                    return new ODataComplexTypeSerializer(edmType.AsComplex(), this);

                case EdmTypeKind.Entity:
                    return new ODataEntityTypeSerializer(edmType.AsEntity(), this);

                default:
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter).Name);
            }
        }
        /// <inheritdoc />
        public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Entity:
                    return _entityDeserializer;

                case EdmTypeKind.Primitive:
                    return _primitiveDeserializer;

                case EdmTypeKind.Complex:
                    return _complexDeserializer;

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return _feedDeserializer;
                    }
                    else
                    {
                        return _collectionDeserializer;
                    }

                default:
                    return null;
            }
        }
        /// <summary>
        /// Creates a new instance of the <see cref="ODataEdmTypeSerializer"/> for the given edm type.
        /// </summary>
        /// <param name="edmType">The <see cref="IEdmTypeReference"/>.</param>
        /// <returns>The constructed <see cref="ODataEdmTypeSerializer"/>.</returns>
        public virtual ODataEdmTypeSerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Primitive:
                    return new ODataPrimitiveSerializer(edmType.AsPrimitive());

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return new ODataFeedSerializer(collectionType, this);
                    }
                    else
                    {
                        return new ODataCollectionSerializer(collectionType, this);
                    }

                case EdmTypeKind.Complex:
                    return new ODataComplexTypeSerializer(edmType.AsComplex(), this);

                case EdmTypeKind.Entity:
                    return new ODataEntityTypeSerializer(edmType.AsEntity(), this);

                default:
                    return null;
            }
        }
        protected override ODataEntryDeserializer CreateDeserializer(IEdmTypeReference edmType)
        {
            if (edmType != null)
            {
                switch (edmType.TypeKind())
                {
                    case EdmTypeKind.Entity:
                        return new ODataEntityDeserializer(edmType.AsEntity(), this);

                    case EdmTypeKind.Primitive:
                        return new ODataPrimitiveDeserializer(edmType.AsPrimitive());

                    case EdmTypeKind.Complex:
                        return new ODataComplexTypeDeserializer(edmType.AsComplex(), this);

                    case EdmTypeKind.Collection:
                        IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                        if (collectionType.ElementType().IsEntity())
                        {
                            return new ODataFeedDeserializer(collectionType, this);
                        }
                        else
                        {
                            return new ODataCollectionDeserializer(collectionType, this);
                        }
                }
            }

            return null;
        }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return null;
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                    Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference elementType = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            return ReadCollectionValue(collection, elementType, readContext);
        }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return null;
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                    Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference elementType = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }
            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            IEnumerable result = ReadCollectionValue(collection, elementType, readContext);
            if (result != null)
            {
                if (readContext.IsUntyped && elementType.IsComplex())
                {
                    EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType);
                    foreach (EdmComplexObject complexObject in result)
                    {
                        complexCollection.Add(complexObject);
                    }
                    return complexCollection;
                }
                else if (readContext.IsUntyped && elementType.IsEnum())
                {
                    EdmEnumObjectCollection enumCollection = new EdmEnumObjectCollection(collectionType);
                    foreach (EdmEnumObject enumObject in result)
                    {
                        enumCollection.Add(enumObject);
                    }
                    return enumCollection;
                } 
                else
                {
                    Type elementClrType = EdmLibHelpers.GetClrType(elementType, readContext.Model);
                    IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable;
                    return castedResult;
                }
            }
            return null;
        }
        /// <summary>
        /// Reads a value from the message reader.
        /// </summary>
        /// <param name="expectedClientType">The expected client type being materialized into.</param>
        /// <param name="expectedReaderType">The expected type for the underlying reader.</param>
        protected override void ReadWithExpectedType(IEdmTypeReference expectedClientType, IEdmTypeReference expectedReaderType)
        {
            ODataProperty property = this.messageReader.ReadProperty(expectedReaderType);
            Type underlyingExpectedType = Nullable.GetUnderlyingType(this.ExpectedType) ?? this.ExpectedType;

            object propertyValue = property.Value;
            if (expectedClientType.IsCollection())
            {
                Debug.Assert(WebUtil.IsCLRTypeCollection(underlyingExpectedType, this.MaterializerContext.Model) || (SingleResult.HasValue && !SingleResult.Value), "expected type must be collection or single result must be false");

                // We are here for two cases: 
                // (1) Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
                // (2) Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
                Type collectionItemType = this.ExpectedType;
                Type collectionICollectionType = ClientTypeUtil.GetImplementationType(underlyingExpectedType, typeof(ICollection<>));
                object collectionInstance;

                if (collectionICollectionType != null)
                {
                    // Case 1
                    collectionItemType = collectionICollectionType.GetGenericArguments()[0];
                    collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionPropertyInstance(property, underlyingExpectedType);
                }
                else
                {
                    // Case 2
                    collectionICollectionType = typeof(ICollection<>).MakeGenericType(new Type[] { collectionItemType });
                    collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionPropertyInstance(property, collectionICollectionType);
                }

                bool isElementNullable = expectedClientType.AsCollection().ElementType().IsNullable;
                this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues(
                    property,
                    collectionInstance,
                    collectionItemType,
                    ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType),
                    isElementNullable);

                this.currentValue = collectionInstance;
            }
            else if (expectedClientType.IsComplex())
            {
                ODataComplexValue complexValue = propertyValue as ODataComplexValue;
                Debug.Assert(this.MaterializerContext.Model.GetOrCreateEdmType(underlyingExpectedType).ToEdmTypeReference(false).IsComplex(), "expectedType must be complex type");

                this.ComplexValueMaterializationPolicy.MaterializeComplexTypeProperty(underlyingExpectedType, complexValue);
                this.currentValue = complexValue.GetMaterializedValue();
            }
            else if (expectedClientType.IsEnum())
            {
                this.currentValue = this.EnumValueMaterializationPolicy.MaterializeEnumTypeProperty(underlyingExpectedType, property);
            }
            else
            {
                Debug.Assert(this.MaterializerContext.Model.GetOrCreateEdmType(underlyingExpectedType).ToEdmTypeReference(false).IsPrimitive(), "expectedType must be primitive type");
                this.currentValue = this.PrimitivePropertyConverter.ConvertPrimitiveValue(property.Value, this.ExpectedType);
            }
        }
Example #9
0
        internal static string FullNameWithNamespace(this IEdmTypeReference type, string proxyClassNamespace)
        {
            var definition = type?.Definition as IEdmSchemaElement;

            if (definition == null && type?.IsCollection() == true)
            {
                definition = type?.AsCollection()?.ElementType()?.Definition as IEdmSchemaElement;
            }

            return(definition?.FullNameWithNamespace(proxyClassNamespace));
        }
Example #10
0
            public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
            {
                if (edmType.IsCollection() && edmType.AsCollection().ElementType().IsEntity())
                {
                    return(new CustomFeedSerializer(this));
                }
                else if (edmType.IsEntity())
                {
                    return(new CustomEntrySerializer(this));
                }

                return(base.GetEdmTypeSerializer(edmType));
            }
Example #11
0
        public void CloneForCollectionShouldBeExpect(bool nullable)
        {
            EdmComplexType          complexType          = new EdmComplexType("TestModel", "MyComplexType");
            EdmComplexTypeReference complexTypeReference = new EdmComplexTypeReference(complexType, isNullable: nullable);
            IEdmTypeReference       typeReference        = new EdmCollectionTypeReference(new EdmCollectionType(complexTypeReference));

            IEdmTypeReference clonedType = typeReference.Clone(nullable);

            Assert.IsType <EdmCollectionTypeReference>(clonedType);
            Assert.Equal(nullable, clonedType.IsNullable);

            Assert.Equal(nullable, clonedType.AsCollection().ElementType().IsNullable);
        }
        /// <inheritdoc />
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            IEdmTypeReference     edmType     = GetElementType(type, readContext);
            IEdmTypeReference     elementType = edmType.AsCollection().ElementType();
            ODataCollectionReader reader      = messageReader.CreateODataCollectionReader(elementType);

            return(ReadInline(ReadCollection(reader), edmType, readContext));
        }
Example #13
0
        private static bool IsInlineType(IEdmTypeReference reference)
        {
            if (reference.Definition is IEdmSchemaElement || reference.IsEntityReference())
            {
                return(true);
            }
            else if (reference.IsCollection())
            {
                return(reference.AsCollection().CollectionDefinition().ElementType.Definition is IEdmSchemaElement);
            }

            return(false);
        }
        private object GetPropertyValue(IEdmTypeReference propertyType, object value)
        {
            if (value == null)
            {
                return(value);
            }

            switch (propertyType.TypeKind())
            {
            case EdmTypeKind.Complex:
                return(new ODataComplexValue()
                {
                    TypeName = propertyType.FullName(),
                    Properties = value.ToDictionary().Select(x => new ODataProperty()
                    {
                        Name = x.Key,
                        Value = GetPropertyValue(propertyType.AsComplex().StructuralProperties(), x.Key, x.Value),
                    }),
                });

            case EdmTypeKind.Collection:
                var collection = propertyType.AsCollection();
                return(new ODataCollectionValue()
                {
                    TypeName = propertyType.FullName(),
                    Items = (value as IEnumerable <object>).Select(x => GetPropertyValue(collection.ElementType(), x)),
                });

            case EdmTypeKind.Primitive:
                var mappedTypes = _typeMap.Where(x => x.Value == (propertyType.Definition as IEdmPrimitiveType).PrimitiveKind);
                if (mappedTypes.Any())
                {
                    foreach (var mappedType in mappedTypes)
                    {
                        object result;
                        if (Utils.TryConvert(value, mappedType.Key, out result))
                        {
                            return(result);
                        }
                    }
                    throw new FormatException(string.Format("Unable to convert value of type {0} to OData type {1}", value.GetType(), propertyType));
                }
                return(value);

            case EdmTypeKind.Enum:
                return(new ODataEnumValue(value.ToString()));

            default:
                return(value);
            }
        }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return(null);
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference           elementType    = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }
            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            IEnumerable result = ReadCollectionValue(collection, elementType, readContext);

            if (result != null)
            {
                if (readContext.IsUntyped && elementType.IsComplex())
                {
                    EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType);
                    foreach (EdmComplexObject complexObject in result)
                    {
                        complexCollection.Add(complexObject);
                    }
                    return(complexCollection);
                }
                else
                {
                    Type        elementClrType = EdmLibHelpers.GetClrType(elementType, readContext.Model);
                    IEnumerable castedResult   = _castMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable;
                    return(castedResult);
                }
            }
            return(null);
        }
Example #16
0
        /// <summary>
        /// Tests type reference is enum or collection enum
        /// </summary>
        /// <param name="edmType"></param>
        /// <returns></returns>
        public static bool IsEnumOrCollectionEnum(this IEdmTypeReference edmType)
        {
            if (edmType.IsEnum())
            {
                return(true);
            }

            if (edmType.IsCollection())
            {
                return(IsEnumOrCollectionEnum(edmType.AsCollection().ElementType()));
            }

            return(false);
        }
Example #17
0
        public void BoundFunction_ForEnumTypeInODataConventionModelBuilder()
        {
            // Arrange
            ODataConventionModelBuilder         builder = new ODataConventionModelBuilder();
            EntityTypeConfiguration <EnumModel> entityTypeConfiguration = builder.EntityType <EnumModel>();
            FunctionConfiguration functionConfiguration = entityTypeConfiguration.Function("BoundFunction");

            functionConfiguration.CollectionParameter <Color?>("Colors");
            functionConfiguration.Returns <Color>();

            // Act & Assert
            IEdmModel    model    = builder.GetEdmModel();
            IEdmFunction function = model.FindDeclaredOperations("Default.BoundFunction").Single() as IEdmFunction;

            IEdmTypeReference colors     = function.Parameters.Single(p => p.Name == "Colors").Type;
            IEdmTypeReference returnType = function.ReturnType;
            IEdmEnumType      colorType  = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "Color");

            Assert.True(colors.IsCollection());
            Assert.True(colors.AsCollection().ElementType().IsNullable);
            Assert.Same(colorType, colors.AsCollection().ElementType().Definition);
            Assert.Same(colorType, returnType.Definition);
        }
        internal static bool IsResourceOrCollectionResource(this IEdmTypeReference edmType)
        {
            if (edmType.IsEntity() || edmType.IsComplex())
            {
                return(true);
            }

            if (edmType.IsCollection())
            {
                return(IsResourceOrCollectionResource(edmType.AsCollection().ElementType()));
            }

            return(false);
        }
Example #19
0
        public void UnboundAction_ForEnumTypeInODataConventionModelBuilder()
        {
            // Arrange
            ODataConventionModelBuilder builder             = new ODataConventionModelBuilder();
            ActionConfiguration         actionConfiguration = builder.Action("UnboundAction");

            actionConfiguration.CollectionParameter <Color>("Colors");
            actionConfiguration.Returns <Color?>();

            // Act & Assert
            IEdmModel        model        = builder.GetEdmModel();
            IEdmActionImport actionImport = model.EntityContainer.OperationImports().Single(o => o.Name == "UnboundAction") as IEdmActionImport;

            IEdmTypeReference colors     = actionImport.Action.Parameters.Single(p => p.Name == "Colors").Type;
            IEdmTypeReference returnType = actionImport.Action.ReturnType;
            IEdmEnumType      colorType  = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "Color");

            Assert.True(colors.IsCollection());
            Assert.False(colors.AsCollection().ElementType().IsNullable);
            Assert.Same(colorType, colors.AsCollection().ElementType().Definition);
            Assert.True(returnType.IsNullable);
            Assert.Same(colorType, returnType.Definition);
        }
        private IEdmTypeReference CreateCollectionStockTypeReference(IEdmTypeReference edmTypeReference, EdmModel stockModel)
        {
            var edmElementTypeReference = edmTypeReference.AsCollection().ElementType();

            if (edmElementTypeReference.Definition.TypeKind == EdmTypeKind.Collection)
            {
                return(EdmCoreModel.GetCollection(CreateCollectionStockTypeReference(edmElementTypeReference, stockModel)));
            }
            else
            {
                var stockElementTypeReference = ConvertToStockTypeReference(edmElementTypeReference, stockModel);
                return(EdmCoreModel.GetCollection(stockElementTypeReference));
            }
        }
        private void VisitTypeReference(IEdmTypeReference reference)
        {
            switch (reference.TypeKind())
            {
            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionTypeReferent = reference.AsCollection();
                VisitTypeReference(collectionTypeReferent.ElementType());
                break;

            case EdmTypeKind.Primitive:
                VisitPrimitiveTypeReference(reference.AsPrimitive());
                break;
            }
        }
        private object ReadNestedResourceSetInline(ODataResourceSetWrapper resourceSetWrapper, IEdmTypeReference edmType,
                                                   ODataDeserializerContext readContext)
        {
            Contract.Assert(resourceSetWrapper != null);
            Contract.Assert(edmType != null);
            Contract.Assert(readContext != null);

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmType);

            if (deserializer == null)
            {
                throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, edmType.FullName()));
            }

            IEdmStructuredTypeReference structuredType = edmType.AsCollection().ElementType().AsStructured();
            var nestedReadContext = new ODataDeserializerContext
            {
                Path     = readContext.Path,
                Model    = readContext.Model,
                Request  = readContext.Request,
                TimeZone = readContext.TimeZone
            };

            if (readContext.IsNoClrType)
            {
                if (structuredType.IsEntity())
                {
                    nestedReadContext.ResourceType = typeof(EdmEntityObjectCollection);
                }
                else
                {
                    nestedReadContext.ResourceType = typeof(EdmComplexObjectCollection);
                }
            }
            else
            {
                Type clrType = readContext.Model.GetClrType(structuredType);

                if (clrType == null)
                {
                    throw new ODataException(
                              Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName()));
                }

                nestedReadContext.ResourceType = typeof(List <>).MakeGenericType(clrType);
            }

            return(deserializer.ReadInline(resourceSetWrapper, edmType, nestedReadContext));
        }
Example #23
0
        /// <summary>
        /// Reads a value from the message reader.
        /// </summary>
        /// <param name="expectedClientType">The expected client type being materialized into.</param>
        /// <param name="expectedReaderType">The expected type for the underlying reader.</param>
        protected override void ReadWithExpectedType(IEdmTypeReference expectedClientType, IEdmTypeReference expectedReaderType)
        {
            if (!expectedClientType.IsCollection())
            {
                throw new DataServiceClientException(DSClient.Strings.AtomMaterializer_TypeShouldBeCollectionError(expectedClientType.FullName()));
            }

            Type underlyingExpectedType = Nullable.GetUnderlyingType(this.ExpectedType) ?? this.ExpectedType;

            Debug.Assert(WebUtil.IsCLRTypeCollection(underlyingExpectedType, this.MaterializerContext.Model) ||
                         (SingleResult.HasValue && !SingleResult.Value), "expected type must be collection or single result must be false");

            // We are here for two cases:
            // (1) Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
            // (2) Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
            Type collectionItemType        = underlyingExpectedType;
            Type collectionICollectionType = ClientTypeUtil.GetImplementationType(underlyingExpectedType, typeof(ICollection <>));

            if (collectionICollectionType != null)
            {
                // Case 1 : Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
                collectionItemType = collectionICollectionType.GetGenericArguments()[0];
            }
            else
            {
                // Case 2 : Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
                collectionICollectionType = typeof(ICollection <>).MakeGenericType(new Type[] { collectionItemType });
            }

            Type   clrCollectionType  = WebUtil.GetBackingTypeForCollectionProperty(collectionICollectionType);
            object collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionInstance((IEdmCollectionTypeReference)expectedClientType, clrCollectionType);

            // Enumerator over our collection reader was created, then ApplyDataCollections was refactored to
            // take an enumerable instead of a ODataCollectionValue. Enumerator is being used as a bridge
            ODataCollectionReader    collectionReader     = messageReader.CreateODataCollectionReader();
            NonEntityItemsEnumerable collectionEnumerable = new NonEntityItemsEnumerable(collectionReader);

            bool isElementNullable = expectedClientType.AsCollection().ElementType().IsNullable;

            this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues(
                collectionEnumerable,
                null /*wireTypeName*/,
                collectionInstance,
                collectionItemType,
                ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType),
                isElementNullable);

            this.currentValue = collectionInstance;
        }
Example #24
0
        private static IEdmEntityTypeReference GetEntityType(IEdmTypeReference feedType)
        {
            if (feedType.IsCollection())
            {
                IEdmTypeReference elementType = feedType.AsCollection().ElementType();
                if (elementType.IsEntity())
                {
                    return(elementType.AsEntity());
                }
            }

            string message = Error.Format(SRResources.CannotWriteType, typeof(ODataFeedSerializer).Name, feedType.FullName());

            throw new SerializationException(message);
        }
Example #25
0
        private static IEdmStructuredTypeReference GetResourceType(IEdmTypeReference resourceSetType)
        {
            if (resourceSetType.IsCollection())
            {
                IEdmTypeReference elementType = resourceSetType.AsCollection().ElementType();
                if (elementType.IsEntity() || elementType.IsComplex())
                {
                    return(elementType.AsStructured());
                }
            }

            string message = Error.Format(SRResources.CannotWriteType, typeof(ODataResourceSetSerializer).Name, resourceSetType.FullName());

            throw new SerializationException(message);
        }
Example #26
0
        /// <summary>
        /// Get element type reference if it's collection or return itself
        /// </summary>
        /// <param name="typeReference">The test type reference.</param>
        /// <returns>Element type or itself.</returns>
        public static IEdmTypeReference GetElementTypeOrSelf(this IEdmTypeReference typeReference)
        {
            if (typeReference == null)
            {
                return(typeReference);
            }

            if (typeReference.TypeKind() == EdmTypeKind.Collection)
            {
                IEdmCollectionTypeReference collectType = typeReference.AsCollection();
                return(collectType.ElementType());
            }

            return(typeReference);
        }
Example #27
0
        public void VisitTypeReference(IEdmTypeReference reference)
        {
            switch (reference.TypeKind())
            {
            case EdmTypeKind.Collection:
                this.ProcessCollectionTypeReference(reference.AsCollection());
                break;

            case EdmTypeKind.Complex:
                this.ProcessComplexTypeReference(reference.AsComplex());
                break;

            case EdmTypeKind.Entity:
                this.ProcessEntityTypeReference(reference.AsEntity());
                break;

            case EdmTypeKind.EntityReference:
                this.ProcessEntityReferenceTypeReference(reference.AsEntityReference());
                break;

            case EdmTypeKind.Enum:
                this.ProcessEnumTypeReference(reference.AsEnum());
                break;

            case EdmTypeKind.Primitive:
                this.VisitPrimitiveTypeReference(reference.AsPrimitive());
                break;

            case EdmTypeKind.TypeDefinition:
                this.ProcessTypeDefinitionReference(reference.AsTypeDefinition());
                break;

            case EdmTypeKind.None:
                this.ProcessTypeReference(reference);
                break;

            case EdmTypeKind.Path:
                this.ProcessPathTypeReference(reference.AsPath());
                break;

            case EdmTypeKind.Untyped:
                this.ProcessUntypedTypeReference(reference as IEdmUntypedTypeReference);
                break;

            default:
                throw new InvalidOperationException(Edm.Strings.UnknownEnumVal_TypeKind(reference.TypeKind().ToString()));
            }
        }
 internal static void SetDynamicProperty(object resource, IEdmStructuredTypeReference resourceType,
     EdmTypeKind propertyKind, string propertyName, object propertyValue, IEdmTypeReference propertyType,
     ODataDeserializerContext readContext, AssembliesResolver assembliesResolver)
 {  
     if (propertyKind == EdmTypeKind.Collection && propertyValue.GetType() != typeof(EdmComplexObjectCollection)
         && propertyValue.GetType() != typeof(EdmEnumObjectCollection))
     {
         SetDynamicCollectionProperty(resource, propertyName, propertyValue, propertyType.AsCollection(),
             resourceType.StructuredDefinition(), readContext, assembliesResolver);
     }
     else
     {
         SetDynamicProperty(resource, propertyName, propertyValue, resourceType.StructuredDefinition(),
             readContext);
     }
 }
        private string TypeReferenceAsXml(IEdmTypeReference type)
        {
            if (type.IsCollection())
            {
                IEdmCollectionTypeReference collectionReference = type.AsCollection();
                Debug.Assert(collectionReference.ElementType().Definition is IEdmSchemaElement, "Cannot inline parameter type if not a named element or collection of named elements");
                return(CsdlConstants.Value_Collection + "(" + this.SerializationName((IEdmSchemaElement)collectionReference.ElementType().Definition) + ")");
            }
            else if (type.IsEntityReference())
            {
                return(CsdlConstants.Value_Ref + "(" + this.SerializationName(type.AsEntityReference().EntityReferenceDefinition().EntityType) + ")");
            }

            Debug.Assert(type.Definition is IEdmSchemaElement, "Cannot inline parameter type if not a named element or collection of named elements");
            return(this.SerializationName((IEdmSchemaElement)type.Definition));
        }
Example #30
0
 internal static void SetDynamicProperty(object resource, IEdmStructuredTypeReference resourceType,
                                         EdmTypeKind propertyKind, string propertyName, object propertyValue, IEdmTypeReference propertyType,
                                         ODataDeserializerContext readContext, AssembliesResolver assembliesResolver)
 {
     if (propertyKind == EdmTypeKind.Collection && propertyValue.GetType() != typeof(EdmComplexObjectCollection) &&
         propertyValue.GetType() != typeof(EdmEnumObjectCollection))
     {
         SetDynamicCollectionProperty(resource, propertyName, propertyValue, propertyType.AsCollection(),
                                      resourceType.StructuredDefinition(), readContext, assembliesResolver);
     }
     else
     {
         SetDynamicProperty(resource, propertyName, propertyValue, resourceType.StructuredDefinition(),
                            readContext);
     }
 }
Example #31
0
 internal static void SetDynamicProperty(object resource, IEdmStructuredTypeReference resourceType,
                                         EdmTypeKind propertyKind, string propertyName, object propertyValue, IEdmTypeReference propertyType,
                                         IEdmModel model)
 {
     if (propertyKind == EdmTypeKind.Collection && propertyValue.GetType() != typeof(EdmComplexObjectCollection) &&
         propertyValue.GetType() != typeof(EdmEnumObjectCollection))
     {
         SetDynamicCollectionProperty(resource, propertyName, propertyValue, propertyType.AsCollection(),
                                      resourceType.StructuredDefinition(), model);
     }
     else
     {
         SetDynamicProperty(resource, propertyName, propertyValue, resourceType.StructuredDefinition(),
                            model);
     }
 }
Example #32
0
        public void Bind_ReturnsIEdmObject_WithRightEdmType()
        {
            // Arrange
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption(select: "ID", expand: null, context: _context);

            // Act
            IQueryable queryable = SelectExpandBinder.Bind(_queryable, _settings, selectExpand);

            // Assert
            Assert.NotNull(queryable);
            IEdmTypeReference edmType = _model.Model.GetEdmTypeReference(queryable.GetType());

            Assert.NotNull(edmType);
            Assert.True(edmType.IsCollection());
            Assert.Same(_model.Customer, edmType.AsCollection().ElementType().Definition);
        }
Example #33
0
            internal static object ConvertFeed(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext)
            {
                IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection();

                EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                              collectionType.ElementType().AsEntity().EntityDefinition());

                ODataReader odataReader = oDataMessageReader.CreateODataFeedReader(tempEntitySet,
                                                                                   collectionType.ElementType().AsEntity().EntityDefinition());
                ODataFeedWithEntries feed =
                    ODataEntityDeserializer.ReadEntryOrFeed(odataReader) as ODataFeedWithEntries;

                ODataFeedDeserializer feedDeserializer =
                    (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);

                object      result     = feedDeserializer.ReadInline(feed, collectionType, readContext);
                IEnumerable enumerable = result as IEnumerable;

                if (enumerable != null)
                {
                    IEnumerable newEnumerable = CovertFeedIds(enumerable, feed, collectionType, readContext);
                    if (readContext.IsUntyped)
                    {
                        EdmEntityObjectCollection entityCollection =
                            new EdmEntityObjectCollection(collectionType);
                        foreach (EdmEntityObject entity in newEnumerable)
                        {
                            entityCollection.Add(entity);
                        }

                        return(entityCollection);
                    }
                    else
                    {
                        IEdmTypeReference elementTypeReference = collectionType.ElementType();

                        Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference,
                                                                       readContext.Model);
                        IEnumerable castedResult =
                            CastMethodInfo.MakeGenericMethod(elementClrType)
                            .Invoke(null, new object[] { newEnumerable }) as IEnumerable;
                        return(castedResult);
                    }
                }

                return(null);
            }
Example #34
0
        private static object ConvertResourceSet(ODataMessageReader oDataMessageReader,
                                                 IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection();

            EdmEntitySet tempEntitySet = null;

            if (collectionType.ElementType().IsEntity())
            {
                tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                 collectionType.ElementType().AsEntity().EntityDefinition());
            }

            // TODO: Sam xu, can we use the parameter-less overload
            ODataReader odataReader = oDataMessageReader.CreateODataUriParameterResourceSetReader(tempEntitySet,
                                                                                                  collectionType.ElementType().AsStructured().StructuredDefinition());
            ODataResourceSetWrapper resourceSet =
                odataReader.ReadResourceOrResourceSet() as ODataResourceSetWrapper;

            ODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider();

            ODataResourceSetDeserializer resourceSetDeserializer =
                (ODataResourceSetDeserializer)deserializerProvider.GetEdmTypeDeserializer(collectionType);

            object      result     = resourceSetDeserializer.ReadInline(resourceSet, collectionType, readContext);
            IEnumerable enumerable = result as IEnumerable;

            if (enumerable != null)
            {
                if (readContext.IsNoClrType)
                {
                    return(enumerable.ConvertToEdmObject(collectionType));
                }
                else
                {
                    IEdmTypeReference elementTypeReference = collectionType.ElementType();

                    Type        elementClrType = readContext.Model.GetClrType(elementTypeReference);
                    IEnumerable castedResult   =
                        CastMethodInfo.MakeGenericMethod(elementClrType)
                        .Invoke(null, new object[] { enumerable }) as IEnumerable;
                    return(castedResult);
                }
            }

            return(null);
        }
 private void ProcessFacets(IEdmTypeReference element, bool inlineType)
 {
     if (((element != null) && !element.IsEntityReference()) && inlineType)
     {
         if (element.TypeKind() == EdmTypeKind.Collection)
         {
             IEdmCollectionTypeReference type = element.AsCollection();
             this.schemaWriter.WriteNullableAttribute(type.CollectionDefinition().ElementType);
             base.VisitTypeReference(type.CollectionDefinition().ElementType);
         }
         else
         {
             this.schemaWriter.WriteNullableAttribute(element);
             base.VisitTypeReference(element);
         }
     }
 }
        /// <inheritdoc />
        public ODataEdmTypeSerializer GetEdmTypeSerializer(HttpContext context, IEdmTypeReference edmType)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

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

            IServiceProvider provider = context.RequestServices;

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Enum:
                return(provider.GetRequiredService <ODataEnumSerializer>());

            case EdmTypeKind.Primitive:
                return(provider.GetRequiredService <ODataPrimitiveSerializer>());

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.Definition.IsDeltaFeed())
                {
                    return(provider.GetRequiredService <ODataDeltaFeedSerializer>());
                }
                else if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex())
                {
                    return(provider.GetRequiredService <ODataResourceSetSerializer>());
                }
                else
                {
                    return(provider.GetRequiredService <ODataCollectionSerializer>());
                }

            case EdmTypeKind.Complex:
            case EdmTypeKind.Entity:
                return(provider.GetRequiredService <ODataResourceSerializer>());

            default:
                return(null);
            }
        }
 private static TypeSyntax GetTypeSyntax(IEdmTypeReference type)
 {
     if (type.IsPrimitive())
     {
         return(GetPrimitiveTypeSyntax(type));
     }
     else if (type.IsCollection())
     {
         var elementType       = type.AsCollection().ElementType();
         var elementTypeSyntax = GetTypeSyntax(elementType);
         return(GenericName(Identifier("IEnumerable"))
                .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(elementTypeSyntax))));
     }
     else
     {
         return(IdentifierName(type.Definition.ToString()));
     }
 }
Example #38
0
        internal static IEdmCollectionTypeReference AsCollectionOrNull(this IEdmTypeReference typeReference)
        {
            if (typeReference == null)
            {
                return(null);
            }
            if (typeReference.TypeKind() != EdmTypeKind.Collection)
            {
                return(null);
            }
            IEdmCollectionTypeReference reference = typeReference.AsCollection();

            if (!reference.IsNonEntityODataCollectionTypeKind())
            {
                return(null);
            }
            return(reference);
        }
        private static IEdmEntityTypeReference GetEntityType(IEdmTypeReference feedType)
        {
            if (feedType.IsCollection())
            {
                IEdmTypeReference elementType = feedType.AsCollection().ElementType();
                if (elementType.IsEntity())
                {
                    return elementType.AsEntity();
                }
            }

            string message = string.Format(
                CultureInfo.InvariantCulture,
                "{0} cannot write an object of type '{1}'.",
                typeof(ODataDomainFeedSerializer).Name,
                feedType.FullName());
            throw new SerializationException(message);
        }
        private static IOpenApiAny GetTypeNameForExample(ODataContext context, IEdmTypeReference edmTypeReference)
        {
            switch (edmTypeReference.TypeKind())
            {
            case EdmTypeKind.Primitive:
                IEdmPrimitiveType primitiveType = edmTypeReference.AsPrimitive().PrimitiveDefinition();
                OpenApiSchema     schema        = context.CreateSchema(primitiveType);

                if (edmTypeReference.IsBoolean())
                {
                    return(new OpenApiBoolean(true));
                }
                else
                {
                    if (schema.Reference != null)
                    {
                        return(new OpenApiString(schema.Reference.Id));
                    }
                    else
                    {
                        return(new OpenApiString(schema.Type ?? schema.Format));
                    }
                }

            case EdmTypeKind.Entity:
            case EdmTypeKind.Complex:
            case EdmTypeKind.Enum:
                OpenApiObject obj = new OpenApiObject();
                obj[Constants.OdataType] = new OpenApiString(edmTypeReference.FullName());
                return(obj);

            case EdmTypeKind.Collection:
                OpenApiArray      array       = new OpenApiArray();
                IEdmTypeReference elementType = edmTypeReference.AsCollection().ElementType();
                array.Add(GetTypeNameForExample(context, elementType));
                return(array);

            case EdmTypeKind.Untyped:
            case EdmTypeKind.TypeDefinition:
            case EdmTypeKind.EntityReference:
            default:
                throw new OpenApiException("Not support for the type kind " + edmTypeReference.TypeKind());
            }
        }
        internal static void SetDynamicProperty(object resource, IEdmStructuredTypeReference resourceType,
            EdmTypeKind propertyKind, string propertyName, object propertyValue, IEdmTypeReference propertyType,
            ODataDeserializerContext readContext)
        {
            if (propertyKind == EdmTypeKind.Collection)
            {
                SetDynamicCollectionProperty(resource, propertyName, propertyValue, propertyType.AsCollection(),
                    resourceType.StructuredDefinition(), readContext);
            }
            else
            {
                if (propertyKind == EdmTypeKind.Enum)
                {
                    propertyValue = ConvertDynamicEnumValue(propertyValue, readContext);
                }

                SetDynamicProperty(resource, propertyName, propertyValue, resourceType.StructuredDefinition(),
                    readContext);
            }
        }
        /// <inheritdoc />
        public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Enum:
                    return _enumSerializer;

                case EdmTypeKind.Primitive:
                    return _primitiveSerializer;

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.Definition.IsDeltaFeed())
                    {
                        return _deltaFeedSerializer;
                    }
                    else if (collectionType.ElementType().IsEntity())
                    {
                        return _feedSerializer;
                    }
                    else
                    {
                        return _collectionSerializer;
                    }

                case EdmTypeKind.Complex:
                    return _complexTypeSerializer;

                case EdmTypeKind.Entity:
                    return _entityTypeSerializer;

                default:
                    return null;
            }
        }
        private bool TryWriteAggregationResult(
            object graph,
            Type type,
            ODataMessageWriter messageWriter,
            ODataSerializerContext writeContext,
            IEdmTypeReference resourceSetType)
        {
            if (typeof(IEnumerable<DynamicTypeWrapper>).IsAssignableFrom(type))
            {
                IEdmTypeReference elementType = resourceSetType.AsCollection().ElementType();
                if (elementType.IsEntity())
                {
                    var entitySet = writeContext.NavigationSource as IEdmEntitySetBase;
                    var entityType = elementType.AsEntity();
                    var writer = messageWriter.CreateODataResourceSetWriter(entitySet, entityType.EntityDefinition());
                    WriteObjectInline(graph, resourceSetType, writer, writeContext);
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Gets the serializer for the given EDM type reference.
        /// </summary>
        /// <param name="edmType">The EDM type reference involved in the serializer.</param>
        /// <returns>The serializer instance.</returns>
        public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType.IsEntity())
            {
                return this.entityTypeSerializer;
            }

            if (edmType.IsComplex())
            {
                return this.complexTypeSerializer;
            }

            if (edmType.IsPrimitive())
            {
                return this.primitiveSerializer;
            }

            if (edmType.IsEnum())
            {
                return this.enumSerializer;
            }

            if (edmType.IsCollection())
            {
                if (edmType.AsCollection().ElementType().IsEntity())
                {
                    return this.feedSerializer;
                }

                return this.collectionSerializer;
            }

            return base.GetEdmTypeSerializer(edmType);
        }
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataDeltaWriter writer,
            ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            ODataDeltaFeed deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext);
            if (deltaFeed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = deltaFeed.NextPageLink;
            deltaFeed.NextPageLink = null;

            //Start writing of the Delta Feed
            writer.WriteStart(deltaFeed);

            //Iterate over all the entries present and select the appropriate write method.
            //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry.
            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
                if (edmChangedObject == null)
                {
                    throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
                }

                switch (edmChangedObject.DeltaKind)
                {
                    case EdmDeltaEntityKind.DeletedEntry:
                        WriteDeltaDeletedEntry(entry, writer, writeContext);
                        break;
                    case EdmDeltaEntityKind.DeletedLinkEntry:
                        WriteDeltaDeletedLink(entry, writer, writeContext);
                        break;
                    case EdmDeltaEntityKind.LinkEntry:
                        WriteDeltaLink(entry, writer, writeContext);
                        break;
                    case EdmDeltaEntityKind.Entry:
                        {
                            IEdmEntityTypeReference elementType = GetEntityType(feedType);
                            ODataEntityTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataEntityTypeSerializer;
                            if (entrySerializer == null)
                            {
                                throw new SerializationException(
                                    Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                            }
                            entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext);
                            break;
                        }
                    default:
                        break;
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.
            if (nextPageLink != null)
            {
                deltaFeed.NextPageLink = nextPageLink;
            }

            //End Writing of the Delta Feed
            writer.WriteEnd();
        }
        private DataType ConvertToTaupoDataType(IEdmTypeReference edmTypeReference)
        {
            EdmTypeKind kind = edmTypeReference.TypeKind();

            if (kind == EdmTypeKind.Collection)
            {
                var elementEdmTypeReference = edmTypeReference.AsCollection().ElementType();
                return DataTypes.CollectionType
                                 .WithElementDataType(this.ConvertToTaupoDataType(elementEdmTypeReference))
                                 .Nullable(edmTypeReference.IsNullable);
            }
            else if (kind == EdmTypeKind.Complex)
            {
                var complexEdmTypeDefinition = edmTypeReference.AsComplex().ComplexDefinition();
                return DataTypes.ComplexType
                                .WithName(complexEdmTypeDefinition.Namespace, complexEdmTypeDefinition.Name)
                                .Nullable(edmTypeReference.IsNullable);
            }
            else if (kind == EdmTypeKind.Entity)
            {
                var entityEdmTypeDefinition = edmTypeReference.AsEntity().EntityDefinition();
                return DataTypes.EntityType
                                .WithName(entityEdmTypeDefinition.Namespace, entityEdmTypeDefinition.Name)
                                .Nullable(edmTypeReference.IsNullable);
            }
            else if (kind == EdmTypeKind.EntityReference)
            {
                var entityEdmTypeDefinition = edmTypeReference.AsEntityReference().EntityType();
                return DataTypes.ReferenceType
                                .WithEntityType(new EntityTypeReference(entityEdmTypeDefinition.Namespace, entityEdmTypeDefinition.Name))
                                .Nullable(edmTypeReference.IsNullable);
            }
            else if (kind == EdmTypeKind.Primitive)
            {
                return EdmToTaupoPrimitiveDataTypeConverter.ConvertToTaupoPrimitiveDataType(edmTypeReference.AsPrimitive());
            }
            else if (kind == EdmTypeKind.Enum)
            {
                var enumTypeDefinition = edmTypeReference.AsEnum().EnumDefinition();
                return DataTypes.EnumType.WithName(enumTypeDefinition.Namespace, enumTypeDefinition.Name);
            }

            throw new TaupoInvalidOperationException("unexpected Edm Type Kind: " + kind);
        }
        private object GetPropertyValue(IEdmTypeReference propertyType, object value)
        {
            if (value == null)
                return value;

            switch (propertyType.TypeKind())
            {
                case EdmTypeKind.Complex:
                    var complexTypeProperties = propertyType.AsComplex().StructuralProperties();
                    return new ODataComplexValue
                    {
                        TypeName = propertyType.FullName(),
                        Properties = value.ToDictionary()
                            .Where(val => complexTypeProperties.Any(p => p.Name == val.Key))
                            .Select(x => new ODataProperty
                            {
                                Name = x.Key,
                                Value = GetPropertyValue(complexTypeProperties, x.Key, x.Value),
                            })
                    };

                case EdmTypeKind.Collection:
                    var collection = propertyType.AsCollection();
                    return new ODataCollectionValue()
                    {
                        TypeName = propertyType.FullName(),
                        Items = (value as IEnumerable<object>).Select(x => GetPropertyValue(collection.ElementType(), x)),
                    };

                case EdmTypeKind.Primitive:
                    var mappedTypes = _typeMap.Where(x => x.Value == (propertyType.Definition as IEdmPrimitiveType).PrimitiveKind);
                    if (mappedTypes.Any())
                    {
                        foreach (var mappedType in mappedTypes)
                        {
                            object result;
                            if (Utils.TryConvert(value, mappedType.Key, out result))
                                return result;
                        }
                        throw new NotSupportedException(string.Format("Conversion is not supported from type {0} to OData type {1}", value.GetType(), propertyType));
                    }
                    return value;

                case EdmTypeKind.Enum:
                    return new ODataEnumValue(value.ToString());

                case EdmTypeKind.None:
                    if (CustomConverters.HasObjectConverter(value.GetType()))
                    {
                        return CustomConverters.Convert(value, value.GetType());
                    }
                    throw new NotSupportedException(string.Format("Conversion is not supported from type {0} to OData type {1}", value.GetType(), propertyType));

                default:
                    return value;
            }
        }
        internal static object GetDefaultValue(IEdmTypeReference propertyType)
        {
            Contract.Assert(propertyType != null);

            bool isCollection = propertyType.IsCollection();
            if (!propertyType.IsNullable || isCollection)
            {
                Type clrType = GetClrTypeForUntypedDelta(propertyType);

                if (propertyType.IsPrimitive() ||
                    (isCollection && propertyType.AsCollection().ElementType().IsPrimitive()))
                {
                    // primitive or primitive collection
                    return Activator.CreateInstance(clrType);
                }
                else
                {
                    // IEdmObject
                    return Activator.CreateInstance(clrType, propertyType);
                }
            }

            return null;
        }
 private static bool IsEntityOrFeed(IEdmTypeReference type)
 {
     Contract.Assert(type != null);
     return type.IsEntity() ||
         (type.IsCollection() && type.AsCollection().ElementType().IsEntity());
 }
        private object GetPropertyValue(IEdmTypeReference propertyType, object value)
        {
            if (value == null)
                return value;

            switch (propertyType.TypeKind())
            {
                case EdmTypeKind.Complex:
                    return new ODataComplexValue()
                    {
                        TypeName = propertyType.FullName(),
                        Properties = value.ToDictionary().Select(x => new ODataProperty()
                        {
                            Name = x.Key,
                            Value = GetPropertyValue(propertyType.AsComplex().StructuralProperties(), x.Key, x.Value),
                        }),
                    };

                case EdmTypeKind.Collection:
                    var collection = propertyType.AsCollection();
                    return new ODataCollectionValue()
                    {
                        TypeName = propertyType.FullName(),
                        Items = (value as IEnumerable<object>).Select(x => GetPropertyValue(collection.ElementType(), x)),
                    };

                case EdmTypeKind.Primitive:
                    var mappedTypes = _typeMap.Where(x => x.Value == (propertyType.Definition as IEdmPrimitiveType).PrimitiveKind);
                    if (mappedTypes.Any())
                    {
                        foreach (var mappedType in mappedTypes)
                        {
                            object result;
                            if (Utils.TryConvert(value, mappedType.Key, out result))
                                return result;
                        }
                        throw new FormatException(string.Format("Unable to convert value of type {0} to OData type {1}", value.GetType(), propertyType));
                    }
                    return value;

                case EdmTypeKind.Enum:
                    return new ODataEnumValue(value.ToString());

                default:
                    return value;
            }
        }
        internal static bool TryCastCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable<EdmError> discoveredErrors)
        {
            if (!type.IsCollection())
            {
                discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Edm.Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType) };
                return false;
            }

            IEdmTypeReference collectionElementType = type.AsCollection().ElementType();
            bool success = true;
            List<EdmError> errors = new List<EdmError>();
            IEnumerable<EdmError> recursiveErrors;
            foreach (IEdmExpression element in expression.Elements)
            {
                success = TryCast(element, collectionElementType, context, matchExactly, out recursiveErrors) && success;
                errors.AddRange(recursiveErrors);
            }

            discoveredErrors = errors;
            return success;
        }
Example #52
0
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
            ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            IEdmEntityTypeReference elementType = GetEntityType(feedType);
            ODataFeed feed = CreateODataFeed(enumerable, feedType.AsCollection(), writeContext);
            if (feed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed));
            }

            ODataEdmTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType);
            if (entrySerializer == null)
            {
                throw new SerializationException(
                    Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = feed.NextPageLink;
            feed.NextPageLink = null;

            writer.WriteStart(feed);

            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                entrySerializer.WriteObjectInline(entry, elementType, writer, writeContext);
            }

            // Subtle and suprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.

            if (nextPageLink != null)
            {
                feed.NextPageLink = nextPageLink;
            }

            writer.WriteEnd();
        }
Example #53
0
        private static IEdmEntityTypeReference GetEntityType(IEdmTypeReference feedType)
        {
            if (feedType.IsCollection())
            {
                IEdmTypeReference elementType = feedType.AsCollection().ElementType();
                if (elementType.IsEntity())
                {
                    return elementType.AsEntity();
                }
            }

            string message = Error.Format(SRResources.CannotWriteType, typeof(ODataFeedSerializer).Name, feedType.FullName());
            throw new SerializationException(message);
        }
        internal static Type GetClrTypeForUntypedDelta(IEdmTypeReference edmType)
        {
            Contract.Assert(edmType != null);

            switch (edmType.TypeKind())
            {
                case EdmTypeKind.Primitive:
                    return EdmLibHelpers.GetClrType(edmType.AsPrimitive(), EdmCoreModel.Instance);

                case EdmTypeKind.Complex:
                    return typeof(EdmComplexObject);

                case EdmTypeKind.Entity:
                    return typeof(EdmEntityObject);

                case EdmTypeKind.Enum:
                    return typeof(EdmEnumObject);

                case EdmTypeKind.Collection:
                    IEdmTypeReference elementType = edmType.AsCollection().ElementType();
                    if (elementType.IsPrimitive())
                    {
                        Type elementClrType = GetClrTypeForUntypedDelta(elementType);
                        return typeof(List<>).MakeGenericType(elementClrType);
                    }
                    else if (elementType.IsComplex())
                    {
                        return typeof(EdmComplexObjectCollection);
                    }
                    else if (elementType.IsEntity())
                    {
                        return typeof(EdmEntityObjectCollection);
                    }
                    else if (elementType.IsEnum())
                    {
                        return typeof(EdmEnumObjectCollection);
                    }
                    break;
            }

            throw Error.InvalidOperation(SRResources.UnsupportedEdmType, edmType.ToTraceString(), edmType.TypeKind());
        }
 private IEdmTypeReference CreateCollectionStockTypeReference(IEdmTypeReference edmTypeReference, EdmModel stockModel)
 {
     var edmElementTypeReference = edmTypeReference.AsCollection().ElementType();
     if (edmElementTypeReference.Definition.TypeKind == EdmTypeKind.Collection)
     {
         return EdmCoreModel.GetCollection(CreateCollectionStockTypeReference(edmElementTypeReference, stockModel));
     }
     else
     {
         var stockElementTypeReference = ConvertToStockTypeReference(edmElementTypeReference, stockModel);
         return EdmCoreModel.GetCollection(stockElementTypeReference);
     }
 }
Example #56
0
            private OdcmType ResolveType(IEdmTypeReference realizedType)
            {
                if (realizedType.IsCollection())
                {
                    return ResolveType(realizedType.AsCollection().ElementType());
                }

                var realizedSchemaElement = (IEdmSchemaElement)realizedType.Definition;

                return ResolveType(realizedSchemaElement.Name, realizedSchemaElement.Namespace);
            }
            internal static object ConvertFeed(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext)
            {
                IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection();

                EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                    collectionType.ElementType().AsEntity().EntityDefinition());

                ODataReader odataReader = oDataMessageReader.CreateODataFeedReader(tempEntitySet,
                    collectionType.ElementType().AsEntity().EntityDefinition());
                ODataFeedWithEntries feed =
                    ODataEntityDeserializer.ReadEntryOrFeed(odataReader) as ODataFeedWithEntries;

                ODataFeedDeserializer feedDeserializer =
                    (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);

                object result = feedDeserializer.ReadInline(feed, collectionType, readContext);
                IEnumerable enumerable = result as IEnumerable;
                if (enumerable != null)
                {
                    IEnumerable newEnumerable = CovertFeedIds(enumerable, feed, collectionType, readContext);
                    if (readContext.IsUntyped)
                    {
                        EdmEntityObjectCollection entityCollection =
                            new EdmEntityObjectCollection(collectionType);
                        foreach (EdmEntityObject entity in newEnumerable)
                        {
                            entityCollection.Add(entity);
                        }

                        return entityCollection;
                    }
                    else
                    {
                        IEdmTypeReference elementTypeReference = collectionType.ElementType();

                        Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference,
                            readContext.Model);
                        IEnumerable castedResult =
                            CastMethodInfo.MakeGenericMethod(elementClrType)
                                .Invoke(null, new object[] { newEnumerable }) as IEnumerable;
                        return castedResult;
                    }
                }

                return null;
            }
        /// <summary>
        /// Reads a value from the message reader.
        /// </summary>
        /// <param name="expectedClientType">The expected client type being materialized into.</param>
        /// <param name="expectedReaderType">The expected type for the underlying reader.</param>
        protected override void ReadWithExpectedType(IEdmTypeReference expectedClientType, IEdmTypeReference expectedReaderType)
        {
            if (!expectedClientType.IsCollection())
            {
                throw new DataServiceClientException(DSClient.Strings.AtomMaterializer_TypeShouldBeCollectionError(expectedClientType.FullName()));
            }

            Type underlyingExpectedType = Nullable.GetUnderlyingType(this.ExpectedType) ?? this.ExpectedType;
            bool isClrCollection = WebUtil.IsCLRTypeCollection(underlyingExpectedType, this.MaterializerContext.Model);
            Debug.Assert(isClrCollection || (SingleResult.HasValue && !SingleResult.Value), "expected type must be collection or single result must be false");
            
            // We are here for two cases: 
            // (1) Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
            // (2) Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
            Type collectionItemType = underlyingExpectedType;
            Type collectionICollectionType = ClientTypeUtil.GetImplementationType(underlyingExpectedType, typeof(ICollection<>));
            
            if (collectionICollectionType != null)
            {
                // Case 1 : Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T>
                collectionItemType = collectionICollectionType.GetGenericArguments()[0];
            }
            else
            {
                // Case 2 : Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T
                collectionICollectionType = typeof(ICollection<>).MakeGenericType(new Type[] { collectionItemType });
            }

            Type clrCollectionType = WebUtil.GetBackingTypeForCollectionProperty(collectionICollectionType, collectionItemType);
            object collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionInstance((IEdmCollectionTypeReference)expectedClientType, clrCollectionType);

            // Enumerator over our collection reader was created, then ApplyDataCollections was refactored to 
            // take an enumerable instead of a ODataCollectionValue. Enumerator is being used as a bridge
            ODataCollectionReader collectionReader = messageReader.CreateODataCollectionReader();
            NonEntityItemsEnumerable collectionEnumerable = new NonEntityItemsEnumerable(collectionReader);

            bool isElementNullable = expectedClientType.AsCollection().ElementType().IsNullable;
            this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues(
                collectionEnumerable,
                null /*wireTypeName*/,
                collectionInstance,
                collectionItemType,
                ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType),
                isElementNullable);

            this.currentValue = collectionInstance;
        }
            public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
            {
                if (edmType.IsCollection() && edmType.AsCollection().ElementType().IsEntity())
                {
                    return new CustomFeedSerializer(this);
                }

                return base.GetEdmTypeSerializer(edmType);
            }
Example #60
0
        private static IEdmCollectionTypeReference AsCollectionOrNull(IEdmTypeReference typeReference)
        {
            if (typeReference == null)
            {
                return null;
            }

            if (typeReference.TypeKind() != EdmTypeKind.Collection)
            {
                return null;
            }

            IEdmCollectionTypeReference collectionTypeReference = typeReference.AsCollection();
            if (!IsODataCollectionTypeKind(collectionTypeReference.Definition))
            {
                return null;
            }

            return collectionTypeReference;
        }