Example #1
0
        /// <summary>
        /// If this reference is of a structured type, this will return a valid structured type reference to the type definition. Otherwise, it will return a bad structured type reference.
        /// </summary>
        /// <param name="type">Reference to the calling object.</param>
        /// <returns>A valid structured type reference if the definition of the reference is of a structured type. Otherwise a bad structured type reference.</returns>
        public static IEdmStructuredTypeReference AsStructured(this IEdmTypeReference type)
        {
            EdmUtil.CheckArgumentNull(type, "type");
            IEdmStructuredTypeReference reference = type as IEdmStructuredTypeReference;

            if (reference != null)
            {
                return(reference);
            }

            switch (type.TypeKind())
            {
            case EdmTypeKind.Entity:
                return(type.AsEntity());

            case EdmTypeKind.Complex:
                return(type.AsComplex());

            case EdmTypeKind.Row:
                return(type.AsRow());
            }

            string          typeFullName = type.FullName();
            List <EdmError> errors       = new List <EdmError>(type.TypeErrors());

            if (errors.Count == 0)
            {
                errors.AddRange(ConversionError(type.Location(), typeFullName, EdmConstants.Type_Structured));
            }

            return(new BadEntityTypeReference(typeFullName, type.IsNullable, errors));
        }
        /// <summary>
        /// Creates a new instance of the <see cref="ODataEntrySerializer"/> for the given edm type.
        /// </summary>
        /// <param name="edmType">The <see cref="IEdmTypeReference"/>.</param>
        /// <returns>The constructed <see cref="ODataEntrySerializer"/>.</returns>
        public virtual ODataEntrySerializer 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;
            }
        }
        /// <summary>
        /// Creates an <see cref="ODataEdmTypeDeserializer"/> that can deserialize payloads of the given <paramref name="edmType"/>.
        /// </summary>
        /// <param name="edmType">The EDM type that the created deserializer can handle.</param>
        /// <returns>The created deserializer.</returns>
        /// <remarks> Override this method if you want to use a custom deserializer. <see cref="GetEdmTypeDeserializer"/> calls into this method and caches the result.</remarks>
        public virtual ODataEdmTypeDeserializer CreateEdmTypeDeserializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            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));
                }

            default:
                return(null);
            }
        }
Example #4
0
        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);
        }
        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);
            }
        }
Example #6
0
        private void WriteDynamicTypeEntry(object graph, ODataWriter writer, IEdmTypeReference expectedType,
                                           ODataSerializerContext writeContext)
        {
            var navigationProperties = new Dictionary <IEdmTypeReference, object>();
            var entityType           = expectedType.Definition as EdmEntityType;
            var entry = new ODataEntry()
            {
                TypeName   = expectedType.FullName(),
                Properties = CreateODataPropertiesFromDynamicType(entityType, graph, navigationProperties)
            };

            entry.IsTransient = true;
            writer.WriteStart(entry);
            foreach (IEdmTypeReference type in navigationProperties.Keys)
            {
                var entityContext      = new EntityInstanceContext(writeContext, expectedType.AsEntity(), graph);
                var navigationProperty = entityType.NavigationProperties().FirstOrDefault(p => p.Type.Equals(type));
                var navigationLink     = CreateNavigationLink(navigationProperty, entityContext);
                if (navigationLink != null)
                {
                    writer.WriteStart(navigationLink);
                    WriteDynamicTypeEntry(navigationProperties[type], writer, type, writeContext);
                    writer.WriteEnd();
                }
            }

            writer.WriteEnd();
        }
        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);
            }
        }
Example #8
0
        /// <summary>
        /// Constructs a new type reference with the specified nullable value
        /// </summary>
        /// <param name="typeReference">The original type reference</param>
        /// <param name="isNullable">The nullable value</param>
        /// <returns>A new type reference, with the specified nullable value</returns>
        public static IEdmTypeReference Nullable(this IEdmTypeReference typeReference, bool isNullable)
        {
            switch (typeReference.TypeKind())
            {
            case EdmTypeKind.Collection:
                var collection = typeReference.AsCollection();
                return(new EdmCollectionTypeReference(collection.CollectionDefinition()));

            case EdmTypeKind.Complex:
                var complex = typeReference.AsComplex();
                return(new EdmComplexTypeReference(complex.ComplexDefinition(), isNullable));

            case EdmTypeKind.Entity:
                var entity = typeReference.AsEntity();
                return(new EdmEntityTypeReference(entity.EntityDefinition(), isNullable));

            case EdmTypeKind.EntityReference:
                var entityRef = typeReference.AsEntityReference();
                return(new EdmEntityReferenceTypeReference(entityRef.EntityReferenceDefinition(), isNullable));

            case EdmTypeKind.Primitive:
                var primitive = (EdmPrimitiveTypeReference)typeReference.AsPrimitive();
                return(primitive.Nullable(isNullable));

            default:
                throw new TaupoInvalidOperationException("Unexpected Edm Type Kind: " + typeReference.TypeKind());
            }
        }
Example #9
0
        /// <summary>
        /// Given a target segment the method returns the text value of the property mapped to that segment to be used in EPM.
        /// </summary>
        /// <param name="targetSegment">The target segment to read the value for.</param>
        /// <param name="epmValueCache">EPM value cache to use to get property values, or a primitive value</param>
        /// <param name="typeReference">The type of the entry or collection item.</param>
        /// <returns>The test representation of the value, or the method throws if the text representation was not possible to obtain.</returns>
        private string GetPropertyValueAsText(
            EpmTargetPathSegment targetSegment,
            object epmValueCache,
            IEdmTypeReference typeReference)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");
            Debug.Assert(targetSegment.HasContent, "The target segment to read property for must have content.");
            Debug.Assert(targetSegment.EpmInfo != null, "The EPM info must be available on the target segment to read its property.");
            Debug.Assert(epmValueCache != null, "epmValueCache != null");
            Debug.Assert(typeReference != null, "typeReference != null");

            object propertyValue;
            EntryPropertiesValueCache entryPropertiesValueCache = epmValueCache as EntryPropertiesValueCache;

            if (entryPropertiesValueCache != null)
            {
                propertyValue = this.ReadEntryPropertyValue(
                    targetSegment.EpmInfo,
                    entryPropertiesValueCache,
                    typeReference.AsEntity());
            }
            else
            {
                propertyValue = epmValueCache;
                ValidationUtils.ValidateIsExpectedPrimitiveType(propertyValue, typeReference);
            }

            return(EpmWriterUtils.GetPropertyValueAsText(propertyValue));
        }
Example #10
0
        private static object ConvertResource(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference,
                                              ODataDeserializerContext readContext)
        {
            EdmEntitySet tempEntitySet = null;

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

            // TODO: Sam xu, can we use the parameter-less overload
            ODataReader resourceReader = oDataMessageReader.CreateODataUriParameterResourceReader(tempEntitySet,
                                                                                                  edmTypeReference.ToStructuredType());

            object item = resourceReader.ReadResourceOrResourceSet();

            ODataResourceWrapper topLevelResource = item as ODataResourceWrapper;

            Contract.Assert(topLevelResource != null);

            IODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider();

            ODataResourceDeserializer entityDeserializer =
                (ODataResourceDeserializer)deserializerProvider.GetEdmTypeDeserializer(edmTypeReference);

            return(entityDeserializer.ReadInline(topLevelResource, edmTypeReference, readContext));
        }
        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)
            {
                throw Error.ArgumentNull("item");
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.IsEntity())
            {
                throw Error.Argument("edmType", SRResources.ArgumentMustBeOfType, EdmTypeKind.Entity);
            }

            ODataEntryWithNavigationLinks entryWrapper = item as ODataEntryWithNavigationLinks;

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

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

            return(ReadEntry(entryWrapper, edmType.AsEntity(), readContext));
        }
Example #13
0
        /// <summary>
        /// Casts an <see cref="IEdmTypeReference"/> to a <see cref="IEdmEntityTypeReference"/> or returns null if this is not supported.
        /// </summary>
        /// <param name="typeReference">The type reference to convert.</param>
        /// <returns>An <see cref="IEdmComplexTypeReference"/> instance or null if the <paramref name="typeReference"/> cannot be converted.</returns>
        internal static IEdmEntityTypeReference AsEntityOrNull(this IEdmTypeReference typeReference)
        {
            if (typeReference == null)
            {
                return(null);
            }

            return(typeReference.TypeKind() == EdmTypeKind.Entity ? typeReference.AsEntity() : null);
        }
Example #14
0
        public void VisitTypeReference(IEdmTypeReference reference)
        {
            EdmTypeKind edmTypeKind = reference.TypeKind();

            switch (edmTypeKind)
            {
            case EdmTypeKind.None:
            {
                this.ProcessTypeReference(reference);
                return;
            }

            case EdmTypeKind.Primitive:
            {
                this.VisitPrimitiveTypeReference(reference.AsPrimitive());
                return;
            }

            case EdmTypeKind.Entity:
            {
                this.ProcessEntityTypeReference(reference.AsEntity());
                return;
            }

            case EdmTypeKind.Complex:
            {
                this.ProcessComplexTypeReference(reference.AsComplex());
                return;
            }

            case EdmTypeKind.Row:
            {
                this.ProcessRowTypeReference(reference.AsRow());
                return;
            }

            case EdmTypeKind.Collection:
            {
                this.ProcessCollectionTypeReference(reference.AsCollection());
                return;
            }

            case EdmTypeKind.EntityReference:
            {
                this.ProcessEntityReferenceTypeReference(reference.AsEntityReference());
                return;
            }

            case EdmTypeKind.Enum:
            {
                this.ProcessEnumTypeReference(reference.AsEnum());
                return;
            }
            }
            throw new InvalidOperationException(Strings.UnknownEnumVal_TypeKind(reference.TypeKind().ToString()));
        }
Example #15
0
        /// <summary>
        /// Casts an <see cref="IEdmTypeReference"/> to a <see cref="IEdmComplexTypeReference"/> or returns null if this is not supported.
        /// </summary>
        /// <param name="typeReference">The type reference to convert.</param>
        /// <returns>An <see cref="IEdmComplexTypeReference"/> instance or null if the <paramref name="typeReference"/> cannot be converted.</returns>
        internal static IEdmEntityTypeReference AsEntityOrNull(this IEdmTypeReference typeReference)
        {
            DebugUtils.CheckNoExternalCallers();

            if (typeReference == null)
            {
                return(null);
            }

            return(typeReference.TypeKind() == EdmTypeKind.Entity ? typeReference.AsEntity() : null);
        }
        /// <summary>
        /// Retrieve all bounding <see cref="IEdmOperation"/>.
        /// </summary>
        private void RetrieveBoundOperationPaths(OpenApiConvertSettings convertSettings)
        {
            foreach (var edmOperation in _model.GetAllElements().OfType <IEdmOperation>().Where(e => e.IsBound))
            {
                if (!CanFilter(edmOperation))
                {
                    continue;
                }

                IEdmOperationParameter bindingParameter = edmOperation.Parameters.First();
                IEdmTypeReference      bindingType      = bindingParameter.Type;

                bool isCollection = bindingType.IsCollection();
                if (isCollection)
                {
                    bindingType = bindingType.AsCollection().ElementType();
                }
                if (!bindingType.IsEntity())
                {
                    continue;
                }

                var firstEntityType = bindingType.AsEntity().EntityDefinition();

                bool filter(IEdmNavigationSource z) =>
                z.EntityType() != firstEntityType &&
                z.EntityType().FindAllBaseTypes().Contains(firstEntityType);

                var allEntitiesForOperation = new IEdmEntityType[] { firstEntityType }
                .Union(_model.EntityContainer.EntitySets()
                       .Where(filter).Select(x => x.EntityType()))      //Search all EntitySets
                .Union(_model.EntityContainer.Singletons()
                       .Where(filter).Select(x => x.EntityType()))      //Search all singletons
                .Distinct()
                .ToList();

                foreach (var bindingEntityType in allEntitiesForOperation)
                {
                    // 1. Search for corresponding navigation source path
                    AppendBoundOperationOnNavigationSourcePath(edmOperation, isCollection, bindingEntityType, convertSettings);

                    // 2. Search for generated navigation property
                    AppendBoundOperationOnNavigationPropertyPath(edmOperation, isCollection, bindingEntityType);

                    // 3. Search for derived
                    AppendBoundOperationOnDerived(edmOperation, isCollection, bindingEntityType, convertSettings);

                    // 4. Search for derived generated navigation property
                    AppendBoundOperationOnDerivedNavigationPropertyPath(edmOperation, isCollection, bindingEntityType, convertSettings);
                }
            }
        }
        private IEdmEntityType ComputeEntityType()
        {
            IEdmTypeReference edmTypeReference = CsdlSemanticsModel.WrapTypeReference(this.schema, this.entityTypeReference.EntityType);

            if (edmTypeReference.TypeKind() == EdmTypeKind.Entity)
            {
                return(edmTypeReference.AsEntity().EntityDefinition());
            }
            else
            {
                return(new UnresolvedEntityType(this.schema.UnresolvedName(edmTypeReference.FullName()), base.Location));
            }
        }
Example #18
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 #19
0
        private static IEdmEntityTypeReference GetEntityType(IEdmModel model, object entity)
        {
            IEdmTypeReference edmType = model.GetEdmTypeReference(entity);

            if (edmType == null)
            {
                throw Error.InvalidOperation(SRResources.ResourceTypeNotInModel, entity.GetType().FullName);
            }
            if (!edmType.IsEntity())
            {
                throw Error.InvalidOperation(SRResources.TypeMustBeEntity, edmType.FullName());
            }

            return(edmType.AsEntity());
        }
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
                               ODataSerializerContext writeContext)
        {
            IEdmEntityTypeReference elementType = null;

            if (feedType.IsCollection())
            {
                IEdmTypeReference refer = feedType.AsCollection().ElementType();
                if (refer.IsEntity())
                {
                    elementType = refer.AsEntity();
                }
            }
            Debug.Assert(elementType != null);

            ODataFeed feed = CreateODataFeed(enumerable, feedType.AsCollection(), writeContext);

            Debug.Assert(feed != null);

            ODataEdmTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType);

            Debug.Assert(entrySerializer is CustomEntrySerializer);

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

            feed.NextPageLink = null;

            writer.WriteStart(feed);

            foreach (object entry in enumerable)
            {
                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 #21
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()));
            }
        }
        private IEdmEntityTypeReference GetEntityType(object graph, ODataSerializerContext writeContext)
        {
            Contract.Assert(graph != null);

            IEdmTypeReference edmType = writeContext.GetEdmType(graph, graph.GetType());

            Contract.Assert(edmType != null);

            if (!edmType.IsEntity())
            {
                throw new SerializationException(
                          Error.Format(SRResources.CannotWriteType, GetType().Name, edmType.FullName()));
            }

            return(edmType.AsEntity());
        }
        private string GetPropertyValueAsText(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
        {
            object obj2;
            EntryPropertiesValueCache cache = epmValueCache as EntryPropertiesValueCache;

            if (cache != null)
            {
                obj2 = base.ReadEntryPropertyValue(targetSegment.EpmInfo, cache, typeReference.AsEntity());
            }
            else
            {
                obj2 = epmValueCache;
                ValidationUtils.ValidateIsExpectedPrimitiveType(obj2, typeReference);
            }
            return(EpmWriterUtils.GetPropertyValueAsText(obj2));
        }
Example #24
0
        public static IEdmStructuredTypeReference AsStructured(this IEdmTypeReference type)
        {
            string          str;
            List <EdmError> edmErrors;

            EdmUtil.CheckArgumentNull <IEdmTypeReference>(type, "type");
            IEdmStructuredTypeReference edmStructuredTypeReference = type as IEdmStructuredTypeReference;

            if (edmStructuredTypeReference == null)
            {
                EdmTypeKind edmTypeKind = type.TypeKind();
                switch (edmTypeKind)
                {
                case EdmTypeKind.Entity:
                {
                    return(type.AsEntity());
                }

                case EdmTypeKind.Complex:
                {
                    return(type.AsComplex());
                }

                case EdmTypeKind.Row:
                {
                    return(type.AsRow());
                }

                default:
                {
                    str       = type.FullName();
                    edmErrors = new List <EdmError>(type.TypeErrors());
                    if (edmErrors.Count != 0)
                    {
                        break;
                    }
                    edmErrors.AddRange(EdmTypeSemantics.ConversionError(type.Location(), str, "Structured"));
                    break;
                }
                }
                return(new BadEntityTypeReference(str, type.IsNullable, edmErrors));
            }
            else
            {
                return(edmStructuredTypeReference);
            }
        }
        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);
        }
Example #26
0
        /// <summary>
        /// Retrieve all bounding <see cref="IEdmOperation"/>.
        /// </summary>
        private void RetrieveBoundOperationPaths()
        {
            foreach (var edmOperation in _model.SchemaElements.OfType <IEdmOperation>().Where(e => e.IsBound))
            {
                if (!CanFilter(edmOperation))
                {
                    continue;
                }

                IEdmOperationParameter bindingParameter = edmOperation.Parameters.First();
                IEdmTypeReference      bindingType      = bindingParameter.Type;

                bool isCollection = bindingType.IsCollection();
                if (isCollection)
                {
                    bindingType = bindingType.AsCollection().ElementType();
                }
                if (!bindingType.IsEntity())
                {
                    continue;
                }
                IEdmEntityType bindingEntityType = bindingType.AsEntity().EntityDefinition();

                // 1. Search for corresponding navigation source path
                if (AppendBoundOperationOnNavigationSourcePath(edmOperation, isCollection, bindingEntityType))
                {
                    continue;
                }

                // 2. Search for generated navigation property
                if (AppendBoundOperationOnNavigationPropertyPath(edmOperation, isCollection, bindingEntityType))
                {
                    continue;
                }

                // 3. Search for derived
                if (AppendBoundOperationOnDerived(edmOperation, isCollection, bindingEntityType))
                {
                    continue;
                }
                AppendBoundOperation(edmOperation, isCollection, bindingEntityType);
            }
        }
Example #27
0
        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);
        }
        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 ODataRawValueDeserializer(edmType.AsPrimitive());

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

            return null;
        }
Example #29
0
        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 ODataRawValueDeserializer(edmType.AsPrimitive()));

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

            return(null);
        }
Example #30
0
        /// <inheritdoc />
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

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

            if (readContext.Path == null)
            {
                throw Error.Argument("readContext", SRResources.ODataPathMissing);
            }

            IEdmEntitySet entitySet = GetEntitySet(readContext.Path);

            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringDeserialization);
            }

            IEdmTypeReference edmType = readContext.GetEdmType(type);

            Contract.Assert(edmType != null);

            if (!edmType.IsEntity())
            {
                throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Entity);
            }

            IEdmEntityTypeReference entityType = edmType.AsEntity();

            ODataReader odataReader = messageReader.CreateODataEntryReader(entitySet, entityType.EntityDefinition());
            ODataEntryWithNavigationLinks topLevelEntry = ReadEntryOrFeed(odataReader) as ODataEntryWithNavigationLinks;

            Contract.Assert(topLevelEntry != null);

            return(ReadInline(topLevelEntry, entityType, readContext));
        }
Example #31
0
        /// <summary>
        /// Gets property for dynamic properties dictionary.
        /// </summary>
        /// <param name="openNode"></param>
        /// <returns>Returns CLR property for dynamic properties container.</returns>
        protected PropertyInfo GetDynamicPropertyContainer(SingleValueOpenPropertyAccessNode openNode)
        {
            IEdmStructuredType edmStructuredType;
            IEdmTypeReference  edmTypeReference = openNode.Source.TypeReference;

            if (edmTypeReference.IsEntity())
            {
                edmStructuredType = edmTypeReference.AsEntity().EntityDefinition();
            }
            else if (edmTypeReference.IsComplex())
            {
                edmStructuredType = edmTypeReference.AsComplex().ComplexDefinition();
            }
            else
            {
                throw Error.NotSupported(SRResources.QueryNodeBindingNotSupported, openNode.Kind, typeof(FilterBinder).Name);
            }

            return(EdmLibHelpers.GetDynamicPropertyDictionary(edmStructuredType, Model));
        }
Example #32
0
        private MetaType GetOrBuildType(IEdmTypeReference edmTypeReference)
        {
            switch (edmTypeReference.TypeKind())
            {
            case EdmTypeKind.Primitive:
                VisitPrimitiveTypeReference(edmTypeReference.AsPrimitive());
                break;

            case EdmTypeKind.Entity:
                VisitEntityType(edmTypeReference.AsEntity().EntityDefinition());
                break;

            case EdmTypeKind.Complex:
                VisitComplexType(edmTypeReference.AsComplex().ComplexDefinition());
                break;

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionTypeRef = edmTypeReference.AsCollection();
                return(GetOrBuildType(collectionTypeRef.ElementType()));

            case EdmTypeKind.Enum:
                VisitEnumType(edmTypeReference.AsEnum().EnumDefinition());
                break;

            case EdmTypeKind.TypeDefinition:
                VisitTypeDefinition(edmTypeReference.AsTypeDefinition().TypeDefinition());
                break;

            case EdmTypeKind.Path:
                VisitPathType(edmTypeReference.AsPath());
                break;

            case EdmTypeKind.EntityReference:
            case EdmTypeKind.None:
            case EdmTypeKind.Untyped:
            default:
                throw new InvalidOperationException($"Found an unknow type kind '{edmTypeReference.TypeKind()}'");
            }

            return(_types[edmTypeReference.FullName()]);
        }
        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);
        }
Example #34
0
        /// <summary>
        /// Build a SingleValueFunctionCallNode for a function that isn't bound to a BuiltInFunction
        /// </summary>
        /// <param name="functionCallTokenName">Name for the function</param>
        /// <param name="args">list of already bound query nodes for this function</param>
        /// <returns>A single value function call node bound to this function.</returns>
        private SingleValueNode CreateUnboundFunctionNode(string functionCallTokenName, List <QueryNode> args)
        {
            // need to figure out the return type and check the correct number of arguments based on the function name
            IEdmTypeReference returnType = null;

            switch (functionCallTokenName)
            {
            case ExpressionConstants.UnboundFunctionIsOf:
            {
                returnType = ValidateAndBuildIsOfArgs(state, ref args);
                break;
            }

            case ExpressionConstants.UnboundFunctionCast:
            {
                returnType = ValidateAndBuildCastArgs(state, ref args);
                if (returnType.IsEntity())
                {
                    IEdmEntityTypeReference returnEntityType = returnType.AsEntity();
                    SingleEntityNode        entityNode       = args.ElementAt(0) as SingleEntityNode;
                    if (entityNode != null)
                    {
                        return(new SingleEntityFunctionCallNode(functionCallTokenName, args, returnEntityType, entityNode.NavigationSource));
                    }
                }

                break;
            }

            default:
            {
                break;
            }
            }

            // we have everything else we need, so return the new SingleValueFunctionCallNode.
            return(new SingleValueFunctionCallNode(functionCallTokenName, args, returnType));
        }
Example #35
0
 private string GetPropertyValueAsText(EpmTargetPathSegment targetSegment, object epmValueCache, IEdmTypeReference typeReference)
 {
     object obj2;
     EntryPropertiesValueCache cache = epmValueCache as EntryPropertiesValueCache;
     if (cache != null)
     {
         obj2 = base.ReadEntryPropertyValue(targetSegment.EpmInfo, cache, typeReference.AsEntity());
     }
     else
     {
         obj2 = epmValueCache;
         ValidationUtils.ValidateIsExpectedPrimitiveType(obj2, typeReference);
     }
     return EpmWriterUtils.GetPropertyValueAsText(obj2);
 }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                throw Error.ArgumentNull("item");
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.IsEntity())
            {
                throw Error.Argument("edmType", SRResources.ArgumentMustBeOfType, EdmTypeKind.Entity);
            }

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

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

            return ReadEntry(entryWrapper, edmType.AsEntity(), readContext);
        }
Example #37
0
        private static IEdmTypeReference ResolveAndValidateTargetTypeStrictValidationDisabled(EdmTypeKind expectedTypeKind, IEdmTypeReference expectedTypeReference, IEdmType payloadType, string payloadTypeName, out SerializationTypeNameAnnotation serializationTypeNameAnnotation)
        {
            switch (expectedTypeKind)
            {
                case EdmTypeKind.Entity:
                {
                    if (((payloadType == null) || (expectedTypeKind != payloadType.TypeKind)) || !expectedTypeReference.AsEntity().EntityDefinition().IsAssignableFrom(((IEdmEntityType) payloadType)))
                    {
                        break;
                    }
                    IEdmTypeReference targetTypeReference = payloadType.ToTypeReference(true);
                    serializationTypeNameAnnotation = CreateSerializationTypeNameAnnotation(payloadTypeName, targetTypeReference);
                    return targetTypeReference;
                }
                case EdmTypeKind.Complex:
                    if ((payloadType != null) && (expectedTypeKind == payloadType.TypeKind))
                    {
                        VerifyComplexType(expectedTypeReference, payloadType, false);
                    }
                    break;

                case EdmTypeKind.Collection:
                    if ((payloadType != null) && (expectedTypeKind == payloadType.TypeKind))
                    {
                        VerifyCollectionComplexItemType(expectedTypeReference, payloadType);
                    }
                    break;

                default:
                    throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.ReaderValidationUtils_ResolveAndValidateTypeName_Strict_TypeKind));
            }
            serializationTypeNameAnnotation = CreateSerializationTypeNameAnnotation(payloadTypeName, expectedTypeReference);
            return expectedTypeReference;
        }
        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 void WriteDynamicTypeEntry(object graph, ODataWriter writer, IEdmTypeReference expectedType,
            ODataSerializerContext writeContext)
        {
            var navigationProperties = new Dictionary<IEdmTypeReference, object>();
            var entityType = expectedType.Definition as EdmEntityType;
            var entry = new ODataEntry()
            {
                TypeName = expectedType.FullName(),
                Properties = CreateODataPropertiesFromDynamicType(entityType, graph, navigationProperties)
            };

            entry.IsTransient = true;
            writer.WriteStart(entry);
            foreach (IEdmTypeReference type in navigationProperties.Keys)
            {
                var entityContext = new EntityInstanceContext(writeContext, expectedType.AsEntity(), graph);
                var navigationProperty = entityType.NavigationProperties().FirstOrDefault(p => p.Type.Equals(type));
                var navigationLink = CreateNavigationLink(navigationProperty, entityContext);
                if (navigationLink != null)
                {
                    writer.WriteStart(navigationLink);
                    WriteDynamicTypeEntry(navigationProperties[type], writer, type, writeContext);
                    writer.WriteEnd();
                }
            }

            writer.WriteEnd();
        }
        /// <summary>
        /// Given a target segment the method returns the text value of the property mapped to that segment to be used in EPM.
        /// </summary>
        /// <param name="targetSegment">The target segment to read the value for.</param>
        /// <param name="epmValueCache">EPM value cache to use to get property values, or a primitive value</param>
        /// <param name="typeReference">The type of the entry or collection item.</param>
        /// <returns>The test representation of the value, or the method throws if the text representation was not possible to obtain.</returns>
        private string GetPropertyValueAsText(
            EpmTargetPathSegment targetSegment,
            object epmValueCache,
            IEdmTypeReference typeReference)
        {
            Debug.Assert(targetSegment != null, "targetSegment != null");
            Debug.Assert(targetSegment.HasContent, "The target segment to read property for must have content.");
            Debug.Assert(targetSegment.EpmInfo != null, "The EPM info must be available on the target segment to read its property.");
            Debug.Assert(epmValueCache != null, "epmValueCache != null");
            Debug.Assert(typeReference != null, "typeReference != null");

            object propertyValue;
            EntryPropertiesValueCache entryPropertiesValueCache = epmValueCache as EntryPropertiesValueCache;

            if (entryPropertiesValueCache != null)
            {
                propertyValue = this.ReadEntryPropertyValue(
                    targetSegment.EpmInfo,
                    entryPropertiesValueCache,
                    typeReference.AsEntity());
            }
            else
            { 
                propertyValue = epmValueCache;
                ValidationUtils.ValidateIsExpectedPrimitiveType(propertyValue, typeReference);
            }

            return EpmWriterUtils.GetPropertyValueAsText(propertyValue);
        }
        /// <summary>
        /// Resolves the payload type versus the expected type and validates that such combination is allowed when the strict validation is disabled.
        /// </summary>
        /// <param name="expectedTypeKind">The expected type kind for the value.</param>
        /// <param name="expectedTypeReference">The expected type reference, or null if no expected type is available.</param>
        /// <param name="payloadType">The payload type, or null if the payload type was not specified, or it didn't resolve against the model.</param>
        /// <returns>The target type reference to use for parsing the value.</returns>
        private static IEdmTypeReference ResolveAndValidateTargetTypeStrictValidationDisabled(
            EdmTypeKind expectedTypeKind,
            IEdmTypeReference expectedTypeReference,
            IEdmType payloadType)
        {
            // Lax validation logic
            switch (expectedTypeKind)
            {
                case EdmTypeKind.Complex:
                    // if the expectedTypeKind is different from the payloadType.TypeKind the types are not related 
                    // in any way. In that case we will just use the expected type because we are in lax mode. 
                    if (payloadType != null && expectedTypeKind == payloadType.TypeKind)
                    {
                        // Verify if it's a derived complex type, in all other cases simply use the expected type.
                        VerifyComplexType(expectedTypeReference, payloadType, /* failIfNotRelated */ false);
                        if (EdmLibraryExtensions.IsAssignableFrom(expectedTypeReference.AsComplex().ComplexDefinition(), (IEdmComplexType)payloadType))
                        {
                            return payloadType.ToTypeReference(/*nullable*/ true);
                        }
                    }

                    break;
                case EdmTypeKind.Entity:
                    // if the expectedTypeKind is different from the payloadType.TypeKind the types are not related 
                    // in any way. In that case we will just use the expected type because we are in lax mode. 
                    if (payloadType != null && expectedTypeKind == payloadType.TypeKind)
                    {
                        // If the type is assignable (equal or derived) we will use the payload type, since we want to allow derived entities
                        if (EdmLibraryExtensions.IsAssignableFrom(expectedTypeReference.AsEntity().EntityDefinition(), (IEdmEntityType)payloadType))
                        {
                            IEdmTypeReference payloadTypeReference = payloadType.ToTypeReference(/*nullable*/ true);
                            return payloadTypeReference;
                        }
                    }

                    break;
                case EdmTypeKind.Collection:
                    // if the expectedTypeKind is different from the payloadType.TypeKind the types are not related 
                    // in any way. In that case we will just use the expected type because we are in lax mode. 
                    if (payloadType != null && expectedTypeKind == payloadType.TypeKind)
                    {
                        VerifyCollectionComplexItemType(expectedTypeReference, payloadType);
                    }

                    break;
                case EdmTypeKind.Enum: // enum: no validation

                    break;
                case EdmTypeKind.TypeDefinition: // type definition: no validation

                    break;
                default:
                    throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ReaderValidationUtils_ResolveAndValidateTypeName_Strict_TypeKind));
            }

            // Either there's no payload type, in which case use the expected one, or the payload one and the expected one are equal.
            return expectedTypeReference;
        }
            internal static object ConvertEntity(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference,
                ODataDeserializerContext readContext)
            {
                IEdmEntityTypeReference entityType = edmTypeReference.AsEntity();

                EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                    entityType.EntityDefinition());

                ODataReader entryReader = oDataMessageReader.CreateODataEntryReader(tempEntitySet,
                    entityType.EntityDefinition());

                object item = ODataEntityDeserializer.ReadEntryOrFeed(entryReader);

                ODataEntryWithNavigationLinks topLevelEntry = item as ODataEntryWithNavigationLinks;
                Contract.Assert(topLevelEntry != null);

                ODataEntityDeserializer entityDeserializer =
                    (ODataEntityDeserializer)DeserializerProvider.GetEdmTypeDeserializer(entityType);
                object entity = entityDeserializer.ReadInline(topLevelEntry, entityType, readContext);
                return CovertEntityId(entity, topLevelEntry.Entry, entityType, readContext);
            }