/// <summary>
        /// Validates the type of an entry in a top-level feed.
        /// </summary>
        /// <param name="entityType">The type of the entry.</param>
        internal void ValidateEntry(IEdmEntityType entityType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entityType != null, "entityType != null");

            // If we don't have a type, store the type of the first item.
            if (this.itemType == null)
            {
                this.itemType = entityType;
            }

            // Validate the expected and actual types.
            if (this.itemType.IsEquivalentTo(entityType))
            {
                return;
            }

            // If the types are not equivalent, make sure they have a common base type.
            IEdmType commonBaseType = EdmLibraryExtensions.GetCommonBaseType(this.itemType, entityType);
            if (commonBaseType == null)
            {
                throw new ODataException(Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName()));
            }

            this.itemType = (IEdmEntityType)commonBaseType;
        }
Пример #2
0
 internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model)
 {
     ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);
     if ((epmCache != null) && (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion))
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_EpmVersionNotSupported(entityType.ODataFullName(), ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion), ODataUtils.ODataVersionToString(version)));
     }
 }
 internal void ValidateEntry(IEdmEntityType entityType)
 {
     if (this.itemType == null)
     {
         this.itemType = entityType;
     }
     if (!((IEdmType) this.itemType).IsEquivalentTo(((IEdmType) entityType)))
     {
         IEdmType commonBaseType = this.itemType.GetCommonBaseType(entityType);
         if (commonBaseType == null)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName()));
         }
         this.itemType = (IEdmEntityType) commonBaseType;
     }
 }
Пример #4
0
        private static void LoadEpmAnnotations(IEdmModel model, IEdmEntityType entityType)
        {
            string typeName = entityType.ODataFullName();
            ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection();

            model.LoadEpmAnnotations(entityType, mappings, typeName, null);
            IEnumerable <IEdmProperty> declaredProperties = entityType.DeclaredProperties;

            if (declaredProperties != null)
            {
                foreach (IEdmProperty property in declaredProperties)
                {
                    model.LoadEpmAnnotations(property, mappings, typeName, property);
                }
            }
            model.SetAnnotationValue <ODataEntityPropertyMappingCollection>(entityType, mappings);
        }
Пример #5
0
        /// <summary>
        /// If an entity type name is found in the payload this method is called to apply it to the current scope.
        /// This method should be called even if the type name was not found in which case a null should be passed in.
        /// The method validates that some type will be available as the current entity type after it returns (if we are parsing using metadata).
        /// </summary>
        /// <param name="entityTypeNameFromPayload">The entity type name found in the payload or null if no type was specified in the payload.</param>
        protected void ApplyEntityTypeNameFromPayload(string entityTypeNameFromPayload)
        {
            Debug.Assert(
                this.scopes.Count > 0 && this.scopes.Peek().Item is ODataEntry,
                "Entity type can be applied only when in entry scope.");

            SerializationTypeNameAnnotation serializationTypeNameAnnotation;
            EdmTypeKind             targetTypeKind;
            IEdmEntityTypeReference targetEntityTypeReference =
                (IEdmEntityTypeReference)ReaderValidationUtils.ResolvePayloadTypeNameAndComputeTargetType(
                    EdmTypeKind.Entity,
                    /*defaultPrimitivePayloadType*/ null,
                    this.CurrentEntityType.ToTypeReference(),
                    entityTypeNameFromPayload,
                    this.inputContext.Model,
                    this.inputContext.MessageReaderSettings,
                    this.inputContext.Version,
                    () => EdmTypeKind.Entity,
                    out targetTypeKind,
                    out serializationTypeNameAnnotation);

            IEdmEntityType targetEntityType = null;
            ODataEntry     entry            = this.CurrentEntry;

            if (targetEntityTypeReference != null)
            {
                targetEntityType = targetEntityTypeReference.EntityDefinition();
                entry.TypeName   = targetEntityType.ODataFullName();

                if (serializationTypeNameAnnotation != null)
                {
                    entry.SetAnnotation(serializationTypeNameAnnotation);
                }
            }
            else if (entityTypeNameFromPayload != null)
            {
                entry.TypeName = entityTypeNameFromPayload;
            }

            // Set the current entity type since the type from payload might be more derived than
            // the expected one.
            this.CurrentEntityType = targetEntityType;
        }
Пример #6
0
        /// <summary>
        /// Check whether the EPM on the specified entity type is supported in the specified version.
        /// </summary>
        /// <param name="version">The version to check.</param>
        /// <param name="entityType">The entity type to check.</param>
        /// <param name="model">The model containing annotations for the entity type.</param>
        internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entityType != null, "entityType != null");
            Debug.Assert(model != null, "model != null");

            ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);

            if (epmCache != null)
            {
                Debug.Assert(epmCache.EpmTargetTree != null, "If the EPM annotation is present the EPM tree must already be initialized.");
                if (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion)
                {
                    throw new ODataException(
                              Strings.ODataVersionChecker_EpmVersionNotSupported(
                                  entityType.ODataFullName(),
                                  ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion),
                                  ODataUtils.ODataVersionToString(version)));
                }
            }
        }
Пример #7
0
        protected void ApplyEntityTypeNameFromPayload(string entityTypeNameFromPayload)
        {
            SerializationTypeNameAnnotation annotation;
            EdmTypeKind             kind;
            IEdmEntityTypeReference reference = (IEdmEntityTypeReference)ReaderValidationUtils.ResolvePayloadTypeNameAndComputeTargetType(EdmTypeKind.Entity, null, this.CurrentEntityType.ToTypeReference(), entityTypeNameFromPayload, this.inputContext.Model, this.inputContext.MessageReaderSettings, this.inputContext.Version, () => EdmTypeKind.Entity, out kind, out annotation);
            IEdmEntityType          type      = null;
            ODataEntry currentEntry           = this.CurrentEntry;

            if (reference != null)
            {
                type = reference.EntityDefinition();
                currentEntry.TypeName = type.ODataFullName();
                if (annotation != null)
                {
                    currentEntry.SetAnnotation <SerializationTypeNameAnnotation>(annotation);
                }
            }
            else if (entityTypeNameFromPayload != null)
            {
                currentEntry.TypeName = entityTypeNameFromPayload;
            }
            this.CurrentEntityType = type;
        }
Пример #8
0
            /// <summary>
            /// Returns the fully qualified name of <paramref name="entityType"/> if it is a derived type of the <paramref name="entitySet"/>;
            /// returns null if <paramref name="entityType"/> is the root type of <paramref name="entitySet"/>.
            /// </summary>
            /// <param name="entitySet">The entity set in question.</param>
            /// <param name="entityType">The eneity type in question.</param>
            /// <returns>
            /// Returns the fully qualified name of <paramref name="entityType"/> if it is a derived type of the <paramref name="entitySet"/>;
            /// returns null if <paramref name="entityType"/> is the root type of <paramref name="entitySet"/>.
            /// </returns>
            private static string GetTypecast(IEdmEntitySet entitySet, IEdmEntityType entityType)
            {
                DebugUtils.CheckNoExternalCallers();
                if (entitySet == null || entityType == null)
                {
                    return(null);
                }

                // The client type resolver is not necessary for writes, ResolveEntitySetElementType() will return entitySet.ElementType when model is null
                // and we don't need to look up the type in the model.
                IEdmEntityType entitySetElementType = EdmTypeWriterResolver.Instance.GetElementType(entitySet);

                if (entitySetElementType.IsEquivalentTo(entityType))
                {
                    return(null);
                }

                if (!entitySetElementType.IsAssignableFrom(entityType))
                {
                    throw new ODataException(OData.Strings.ODataJsonLightMetadataUriBuilder_ValidateDerivedType(entitySetElementType.FullName(), entityType.FullName()));
                }

                return(entityType.ODataFullName());
            }
        /// <summary>
        /// Validates that a navigation property with the specified name exists on a given entity type.
        /// The entity type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param>
        /// <param name="messageReaderSettings">The message reader settings being used.</param>
        /// <returns>The <see cref="IEdmNavigationProperty"/> instance representing the navigation property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(
            string propertyName,
            IEdmEntityType owningEntityType,
            ODataMessageReaderSettings messageReaderSettings)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");
            Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null");

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

            IEdmProperty property = ValidateLinkPropertyDefined(propertyName, owningEntityType, messageReaderSettings);
            if (property == null)
            {
                if (owningEntityType.IsOpen && !messageReaderSettings.ReportUndeclaredLinkProperties)
                {
                    // We don't support open navigation properties
                    throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
                }
            }
            else if (property.PropertyKind != EdmPropertyKind.Navigation)
            {
                // The property must be a navigation property
                throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
            }

            return (IEdmNavigationProperty)property;
        }
Пример #10
0
        /// <summary>
        /// Check whether the EPM on the specified entity type is supported in the specified version.
        /// </summary>
        /// <param name="version">The version to check.</param>
        /// <param name="entityType">The entity type to check.</param>
        /// <param name="model">The model containing annotations for the entity type.</param>
        internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entityType != null, "entityType != null");
            Debug.Assert(model != null, "model != null");

            ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);
            if (epmCache != null)
            {
                Debug.Assert(epmCache.EpmTargetTree != null, "If the EPM annotation is present the EPM tree must already be initialized.");
                if (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion)
                {
                    throw new ODataException(
                        Strings.ODataVersionChecker_EpmVersionNotSupported(
                            entityType.ODataFullName(),
                            ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion),
                            ODataUtils.ODataVersionToString(version)));
                }
            }
        }
Пример #11
0
 private static void LoadEpmAnnotations(IEdmModel model, IEdmEntityType entityType)
 {
     string typeName = entityType.ODataFullName();
     ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection();
     model.LoadEpmAnnotations(entityType, mappings, typeName, null);
     IEnumerable<IEdmProperty> declaredProperties = entityType.DeclaredProperties;
     if (declaredProperties != null)
     {
         foreach (IEdmProperty property in declaredProperties)
         {
             model.LoadEpmAnnotations(property, mappings, typeName, property);
         }
     }
     model.SetAnnotationValue<ODataEntityPropertyMappingCollection>(entityType, mappings);
 }
Пример #12
0
        /// <summary>
        /// Loads the serializable EPM annotations on the given <paramref name="entityType"/> into their in-memory representation.
        /// </summary>
        /// <param name="model">The model the entity type belongs to.</param>
        /// <param name="entityType">The <see cref="IEdmEntityType"/> to load the EPM annotations for.</param>
        private static void LoadEpmAnnotations(IEdmModel model, IEdmEntityType entityType)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entityType != null, "entityType != null");

            string entityTypeName = entityType.ODataFullName();
            ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection();

            // Load the annotations from the type (these are the mappings for properties not explicitly declared on this type)
            model.LoadEpmAnnotations(entityType, mappings, entityTypeName, null /*property*/);

            IEnumerable<IEdmProperty> declaredProperties = entityType.DeclaredProperties;
            if (declaredProperties != null)
            {
                foreach (IEdmProperty property in declaredProperties)
                {
                    // Load the EPM annotations for all properties independent of their kind in order to fail on invalid property kinds.
                    model.LoadEpmAnnotations(property, mappings, entityTypeName, property);
                }
            }

            // Set the new EPM annotation on the entity type only at the very end to not leave a 
            // inconsistent annotation if building it fails.
            model.SetAnnotationValue(entityType, mappings);
        }
Пример #13
0
        /// <summary>
        /// Validates that the specified <paramref name="entry"/> is a valid entry as per the specified type.
        /// </summary>
        /// <param name="entry">The entry to validate.</param>
        /// <param name="entityType">Optional entity type to validate the entry against.</param>
        /// <param name="model">Model containing the entity type.</param>
        /// <param name="validateMediaResource">true if the validation of the default MediaResource should be done; false otherwise.</param>
        /// <remarks>If the <paramref name="entityType"/> is available only entry-level tests are performed, properties and such are not validated.</remarks>
        internal static void ValidateEntryMetadataResource(ODataEntry entry, IEdmEntityType entityType, IEdmModel model, bool validateMediaResource)
        {
            Debug.Assert(entry != null, "entry != null");

            if (entityType != null)
            {
                Debug.Assert(model != null, "model != null");
                Debug.Assert(model.IsUserModel(), "model.IsUserModel()");

                if (validateMediaResource)
                {
                    if (entry.MediaResource == null)
                    {
                        if (entityType.HasStream)
                        {
                            throw new ODataException(Strings.ValidationUtils_EntryWithoutMediaResourceAndMLEType(entityType.ODataFullName()));
                        }
                    }
                    else
                    {
                        if (!entityType.HasStream)
                        {
                            throw new ODataException(Strings.ValidationUtils_EntryWithMediaResourceAndNonMLEType(entityType.ODataFullName()));
                        }
                    }
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Validates that the specified <paramref name="entry"/> is a valid entry as per the specified type.
        /// </summary>
        /// <param name="entry">The entry to validate.</param>
        /// <param name="entityType">Optional entity type to validate the entry against.</param>
        /// <param name="model">Model containing the entity type.</param>
        /// <param name="validateMediaResource">true if the validation of the default MediaResource should be done; false otherwise.</param>
        /// <remarks>If the <paramref name="entityType"/> is available only entry-level tests are performed, properties and such are not validated.</remarks>
        internal static void ValidateEntryMetadataResource(ODataEntry entry, IEdmEntityType entityType, IEdmModel model, bool validateMediaResource)
        {
            Debug.Assert(entry != null, "entry != null");

            if (entityType != null)
            {
                Debug.Assert(model != null, "model != null");
                Debug.Assert(model.IsUserModel(), "model.IsUserModel()");

                if (validateMediaResource)
                {
                    if (entry.MediaResource == null)
                    {
                        if (entityType.HasStream)
                        {
                            throw new ODataException(Strings.ValidationUtils_EntryWithoutMediaResourceAndMLEType(entityType.ODataFullName()));
                        }
                    }
                    else
                    {
                        if (!entityType.HasStream)
                        {
                            throw new ODataException(Strings.ValidationUtils_EntryWithMediaResourceAndNonMLEType(entityType.ODataFullName()));
                        }
                    }
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Validates that a navigation property with the specified name exists on a given entity type.
        /// The entity type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the navigation property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

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

            IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType);
            if (property == null)
            {
                // We don't support open navigation properties
                Debug.Assert(owningEntityType.IsOpen, "We should have already failed on non-existing property on a closed type.");
                throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
            }

            if (property.PropertyKind != EdmPropertyKind.Navigation)
            {
                // The property must be a navigation property
                throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
            }

            return (IEdmNavigationProperty)property;
        }
Пример #16
0
        internal static void CheckEntityPropertyMapping(ODataVersion version, IEdmEntityType entityType, IEdmModel model)
        {
            ODataEntityPropertyMappingCache epmCache = model.GetEpmCache(entityType);

            if ((epmCache != null) && (version < epmCache.EpmTargetTree.MinimumODataProtocolVersion))
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ODataVersionChecker_EpmVersionNotSupported(entityType.ODataFullName(), ODataUtils.ODataVersionToString(epmCache.EpmTargetTree.MinimumODataProtocolVersion), ODataUtils.ODataVersionToString(version)));
            }
        }
Пример #17
0
        /// <summary>
        /// Validates that a navigation property with the specified name exists on a given entity type.
        /// The entity type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the navigation property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType)
        {
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

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

            IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType);

            if (property == null)
            {
                // We don't support open navigation properties
                Debug.Assert(owningEntityType.IsOpen, "We should have already failed on non-existing property on a closed type.");
                throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
            }

            if (property.PropertyKind != EdmPropertyKind.Navigation)
            {
                // The property must be a navigation property
                throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
            }

            return((IEdmNavigationProperty)property);
        }
Пример #18
0
        /// <summary>
        /// Binds a key property value.
        /// </summary>
        /// <param name="namedValue">The named value to bind.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <returns>The bound key property value node.</returns>
        private KeyPropertyValue BindKeyPropertyValue(NamedValue namedValue, IEdmEntityType collectionItemEntityType)
        {
            // These are exception checks because the data comes directly from the potentially user specified tree.
            ExceptionUtils.CheckArgumentNotNull(namedValue, "namedValue");
            ExceptionUtils.CheckArgumentNotNull(namedValue.Value, "namedValue.Value");
            Debug.Assert(collectionItemEntityType != null, "collectionItemType != null");

            IEdmProperty keyProperty = null;
            if (namedValue.Name == null)
            {
                foreach (IEdmProperty p in collectionItemEntityType.Key())
                {
                    if (keyProperty == null)
                    {
                        keyProperty = p;
                    }
                    else
                    {
                        throw new ODataException(Strings.MetadataBinder_UnnamedKeyValueOnTypeWithMultipleKeyProperties(collectionItemEntityType.ODataFullName()));
                    }
                }
            }
            else
            {
                keyProperty = collectionItemEntityType.Key().Where(k => string.CompareOrdinal(k.Name, namedValue.Name) == 0).SingleOrDefault();

                if (keyProperty == null)
                {
                    throw new ODataException(Strings.MetadataBinder_PropertyNotDeclaredOrNotKeyInKeyValue(namedValue.Name, collectionItemEntityType.ODataFullName()));
                }
            }

            IEdmTypeReference keyPropertyType = keyProperty.Type;

            SingleValueQueryNode value = (SingleValueQueryNode)this.Bind(namedValue.Value);

            // TODO: Check that the value is of primitive type
            value = ConvertToType(value, keyPropertyType);

            Debug.Assert(keyProperty != null, "keyProperty != null");
            return new KeyPropertyValue()
            {
                KeyProperty = keyProperty,
                KeyValue = value
            };
        }
Пример #19
0
 internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType)
 {
     if (parentNavigationPropertyType != null)
     {
         IEdmEntityType baseType = (parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection) ? ((IEdmEntityType) ((IEdmCollectionType) parentNavigationPropertyType).ElementType.Definition) : ((IEdmEntityType) parentNavigationPropertyType);
         if (!baseType.IsAssignableFrom(entryEntityType))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), baseType.ODataFullName()));
         }
     }
 }
Пример #20
0
 internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType)
 {
     if (parentNavigationPropertyType != null)
     {
         IEdmEntityType baseType = (parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection) ? ((IEdmEntityType)((IEdmCollectionType)parentNavigationPropertyType).ElementType.Definition) : ((IEdmEntityType)parentNavigationPropertyType);
         if (!baseType.IsAssignableFrom(entryEntityType))
         {
             throw new ODataException(Microsoft.Data.OData.Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), baseType.ODataFullName()));
         }
     }
 }
Пример #21
0
        internal static IEdmProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType)
        {
            if (owningEntityType == null)
            {
                return(null);
            }
            IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType);

            if (property == null)
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
            }
            if (property.PropertyKind != EdmPropertyKind.Navigation)
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
            }
            return(property);
        }
Пример #22
0
 internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings)
 {
     if (owningEntityType == null)
     {
         return null;
     }
     IEdmProperty property = ValidateLinkPropertyDefined(propertyName, owningEntityType, messageReaderSettings);
     if (property == null)
     {
         if (owningEntityType.IsOpen)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
         }
     }
     else if (property.PropertyKind != EdmPropertyKind.Navigation)
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
     }
     return (IEdmNavigationProperty) property;
 }
Пример #23
0
 internal static IEdmProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType)
 {
     if (owningEntityType == null)
     {
         return null;
     }
     IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType);
     if (property == null)
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
     }
     if (property.PropertyKind != EdmPropertyKind.Navigation)
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
     }
     return property;
 }
Пример #24
0
        /// <summary>
        /// Validates an entry in an expanded link to make sure the entity types match.
        /// </summary>
        /// <param name="entryEntityType">The <see cref="IEdmEntityType"/> of the entry.</param>
        /// <param name="parentNavigationPropertyType">The type of the parent navigation property.</param>
        internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType)
        {
            DebugUtils.CheckNoExternalCallers();

            if (parentNavigationPropertyType == null)
            {
                return;
            }

            Debug.Assert(entryEntityType != null, "If we have a parent navigation property type we should also have an entry type.");

            bool           navPropIsCollection = parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection;
            IEdmEntityType parentNavigationPropertyEntityType = (IEdmEntityType)(navPropIsCollection
                ? ((IEdmCollectionType)parentNavigationPropertyType).ElementType.Definition
                : parentNavigationPropertyType);

            // Make sure the entity types are compatible
            if (!parentNavigationPropertyEntityType.IsAssignableFrom(entryEntityType))
            {
                throw new ODataException(Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), parentNavigationPropertyEntityType.ODataFullName()));
            }
        }
Пример #25
0
        /// <summary>
        /// Validates that a navigation property with the specified name exists on a given entity type.
        /// The entity type can be null if no metadata is available.
        /// </summary>
        /// <param name="propertyName">The name of the property to validate.</param>
        /// <param name="owningEntityType">The owning entity type or null if no metadata is available.</param>
        /// <param name="undeclaredPropertyBehaviorKinds">Value of UndeclaredPropertyBehaviorKinds in message settings.</param>
        /// <returns>The <see cref="IEdmProperty"/> instance representing the navigation property with name <paramref name="propertyName"/>
        /// or null if no metadata is available.</returns>
        internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType, ODataUndeclaredPropertyBehaviorKinds undeclaredPropertyBehaviorKinds)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(!string.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

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

            IEdmProperty property = ValidatePropertyDefined(propertyName, owningEntityType, undeclaredPropertyBehaviorKinds);

            if (property == null)
            {
                // .None / .LinkProperty
                bool throwErr = !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty) &&
                                !undeclaredPropertyBehaviorKinds.HasFlag(ODataUndeclaredPropertyBehaviorKinds.SupportUndeclaredValueProperty);

                // We don't support open navigation properties
                // when writing undeclared property is supported, shouldn't throw exception
                if (throwErr)
                {
                    Debug.Assert(owningEntityType.IsOpen, "We should have already failed on non-existing property on a closed type.");
                }

                throw new ODataException(Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
            }

            if (property.PropertyKind != EdmPropertyKind.Navigation)
            {
                // The property must be a navigation property
                throw new ODataException(Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
            }

            return((IEdmNavigationProperty)property);
        }
Пример #26
0
        /// <summary>
        /// Binds a key property value.
        /// </summary>
        /// <param name="namedValue">The named value to bind.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <returns>The bound key property value node.</returns>
        private KeyPropertyValue BindKeyPropertyValue(NamedValue namedValue, IEdmEntityType collectionItemEntityType)
        {
            // These are exception checks because the data comes directly from the potentially user specified tree.
            ExceptionUtils.CheckArgumentNotNull(namedValue, "namedValue");
            ExceptionUtils.CheckArgumentNotNull(namedValue.Value, "namedValue.Value");
            Debug.Assert(collectionItemEntityType != null, "collectionItemType != null");

            IEdmProperty keyProperty = null;

            if (namedValue.Name == null)
            {
                foreach (IEdmProperty p in collectionItemEntityType.Key())
                {
                    if (keyProperty == null)
                    {
                        keyProperty = p;
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.MetadataBinder_UnnamedKeyValueOnTypeWithMultipleKeyProperties(collectionItemEntityType.ODataFullName()));
                    }
                }
            }
            else
            {
                keyProperty = collectionItemEntityType.Key().Where(k => string.CompareOrdinal(k.Name, namedValue.Name) == 0).SingleOrDefault();

                if (keyProperty == null)
                {
                    throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyNotDeclaredOrNotKeyInKeyValue(namedValue.Name, collectionItemEntityType.ODataFullName()));
                }
            }

            IEdmTypeReference keyPropertyType = keyProperty.Type;

            SingleValueNode value = (SingleValueNode)this.keyValueBindMethod(namedValue.Value);

            // TODO: Check that the value is of primitive type
            Debug.Assert(keyPropertyType.IsODataPrimitiveTypeKind(), "The key's type must be primitive.");
            value = MetadataBindingUtils.ConvertToTypeIfNeeded(value, keyPropertyType);

            Debug.Assert(keyProperty != null, "keyProperty != null");
            return(new KeyPropertyValue()
            {
                KeyProperty = keyProperty,
                KeyValue = value
            });
        }
Пример #27
0
        /// <summary>
        /// Binds a key property value.
        /// </summary>
        /// <param name="namedValue">The named value to bind.</param>
        /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param>
        /// <param name="keys">Dictionary of alias to keys.</param>
        /// <param name="keyPropertyValue">The bound key property value node.</param>
        /// <returns>The bound key property value node.</returns>
        private bool TryBindKeyPropertyValue(NamedValue namedValue, IEdmEntityType collectionItemEntityType, IDictionary<string, IEdmProperty> keys, out KeyPropertyValue keyPropertyValue)
        {
            // These are exception checks because the data comes directly from the potentially user specified tree.
            ExceptionUtils.CheckArgumentNotNull(namedValue, "namedValue");
            ExceptionUtils.CheckArgumentNotNull(namedValue.Value, "namedValue.Value");
            Debug.Assert(collectionItemEntityType != null, "collectionItemType != null");

            IEdmProperty keyProperty = null;
            if (namedValue.Name == null)
            {
                foreach (IEdmProperty p in keys.Values)
                {
                    if (keyProperty == null)
                    {
                        keyProperty = p;
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.MetadataBinder_UnnamedKeyValueOnTypeWithMultipleKeyProperties(collectionItemEntityType.ODataFullName()));
                    }
                }
            }
            else
            {
                keyProperty = keys.SingleOrDefault(k => string.CompareOrdinal(k.Key, namedValue.Name) == 0).Value;

                if (keyProperty == null)
                {
                    keyPropertyValue = null;
                    return false;
                }
            }

            IEdmTypeReference keyPropertyType = keyProperty.Type;

            SingleValueNode value = (SingleValueNode)this.keyValueBindMethod(namedValue.Value);

            // TODO: Check that the value is of primitive type
            Debug.Assert(keyPropertyType.IsODataPrimitiveTypeKind(), "The key's type must be primitive.");
            value = MetadataBindingUtils.ConvertToTypeIfNeeded(value, keyPropertyType);

            Debug.Assert(keyProperty != null, "keyProperty != null");
            keyPropertyValue = new KeyPropertyValue()
            {
                KeyProperty = keyProperty,
                KeyValue = value
            };

            return true;
        }
Пример #28
0
        /// <summary>
        /// Validates an entry in an expanded link to make sure the entity types match.
        /// </summary>
        /// <param name="entryEntityType">The <see cref="IEdmEntityType"/> of the entry.</param>
        /// <param name="parentNavigationPropertyType">The type of the parent navigation property.</param>
        internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmEntityType parentNavigationPropertyType)
        {
            if (parentNavigationPropertyType == null)
            {
                return;
            }

            Debug.Assert(entryEntityType != null, "If we have a parent navigation property type we should also have an entry type.");

            // Make sure the entity types are compatible
            if (!parentNavigationPropertyType.IsAssignableFrom(entryEntityType))
            {
                throw new ODataException(Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), parentNavigationPropertyType.ODataFullName()));
            }
        }
Пример #29
0
 internal static void ValidateEntryMetadata(ODataEntry entry, IEdmEntityType entityType, IEdmModel model, bool validateMediaResource)
 {
     if ((entityType != null) && validateMediaResource)
     {
         bool flag = model.HasDefaultStream(entityType);
         if (entry.MediaResource == null)
         {
             if (flag)
             {
                 throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryWithoutMediaResourceAndMLEType(entityType.ODataFullName()));
             }
         }
         else if (!flag)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryWithMediaResourceAndNonMLEType(entityType.ODataFullName()));
         }
     }
 }
Пример #30
0
        internal static IEdmNavigationProperty ValidateNavigationPropertyDefined(string propertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings)
        {
            if (owningEntityType == null)
            {
                return(null);
            }
            IEdmProperty property = ValidateLinkPropertyDefined(propertyName, owningEntityType, messageReaderSettings);

            if (property == null)
            {
                if (owningEntityType.IsOpen)
                {
                    throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_OpenNavigationProperty(propertyName, owningEntityType.ODataFullName()));
                }
            }
            else if (property.PropertyKind != EdmPropertyKind.Navigation)
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_NavigationPropertyExpected(propertyName, owningEntityType.ODataFullName(), property.PropertyKind.ToString()));
            }
            return((IEdmNavigationProperty)property);
        }
Пример #31
0
 internal static void ValidateEntryMetadata(ODataEntry entry, IEdmEntityType entityType, IEdmModel model, bool validateMediaResource)
 {
     if ((entityType != null) && validateMediaResource)
     {
         bool flag = model.HasDefaultStream(entityType);
         if (entry.MediaResource == null)
         {
             if (flag)
             {
                 throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryWithoutMediaResourceAndMLEType(entityType.ODataFullName()));
             }
         }
         else if (!flag)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_EntryWithMediaResourceAndNonMLEType(entityType.ODataFullName()));
         }
     }
 }
Пример #32
0
        /// <summary>
        /// Validates an entry in an expanded link to make sure the entity types match.
        /// </summary>
        /// <param name="entryEntityType">The <see cref="IEdmEntityType"/> of the entry.</param>
        /// <param name="parentNavigationPropertyType">The type of the parent navigation property.</param>
        internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmEntityType parentNavigationPropertyType)
        {
            if (parentNavigationPropertyType == null)
            {
                return;
            }

            Debug.Assert(entryEntityType != null, "If we have a parent navigation property type we should also have an entry type.");

            // Make sure the entity types are compatible
            if (!parentNavigationPropertyType.IsAssignableFrom(entryEntityType))
            {
                throw new ODataException(Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), parentNavigationPropertyType.ODataFullName()));
            }
        }
Пример #33
0
        /// <summary>
        /// Validates an entry in an expanded link to make sure the entity types match.
        /// </summary>
        /// <param name="entryEntityType">The <see cref="IEdmEntityType"/> of the entry.</param>
        /// <param name="parentNavigationPropertyType">The type of the parent navigation property.</param>
        internal static void ValidateEntryInExpandedLink(IEdmEntityType entryEntityType, IEdmType parentNavigationPropertyType)
        {
            DebugUtils.CheckNoExternalCallers();

            if (parentNavigationPropertyType == null)
            {
                return;
            }

            Debug.Assert(entryEntityType != null, "If we have a parent navigation property type we should also have an entry type.");

            bool navPropIsCollection = parentNavigationPropertyType.TypeKind == EdmTypeKind.Collection;
            IEdmEntityType parentNavigationPropertyEntityType = (IEdmEntityType)(navPropIsCollection
                ? ((IEdmCollectionType)parentNavigationPropertyType).ElementType.Definition
                : parentNavigationPropertyType);

            // Make sure the entity types are compatible
            if (!parentNavigationPropertyEntityType.IsAssignableFrom(entryEntityType))
            {
                throw new ODataException(Strings.WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType(entryEntityType.ODataFullName(), parentNavigationPropertyEntityType.ODataFullName()));
            }
        }
Пример #34
0
        /// <summary>
        /// Validates the type of an entry in a top-level feed.
        /// </summary>
        /// <param name="entityType">The type of the entry.</param>
        internal void ValidateEntry(IEdmEntityType entityType)
        {
            Debug.Assert(entityType != null, "entityType != null");

            // If we don't have a type, store the type of the first item.
            if (this.itemType == null)
            {
                this.itemType = entityType;
            }

            // Validate the expected and actual types.
            if (this.itemType.IsEquivalentTo(entityType))
            {
                return;
            }

            // If the types are not equivalent, make sure they have a common base type.
            IEdmType commonBaseType = EdmLibraryExtensions.GetCommonBaseType(this.itemType, entityType);

            if (commonBaseType == null)
            {
                throw new ODataException(Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName()));
            }

            this.itemType = (IEdmEntityType)commonBaseType;
        }
Пример #35
0
 internal void ValidateEntry(IEdmEntityType entityType)
 {
     if (this.itemType == null)
     {
         this.itemType = entityType;
     }
     if (!((IEdmType)this.itemType).IsEquivalentTo(((IEdmType)entityType)))
     {
         IEdmType commonBaseType = this.itemType.GetCommonBaseType(entityType);
         if (commonBaseType == null)
         {
             throw new ODataException(Microsoft.Data.OData.Strings.FeedWithoutExpectedTypeValidator_IncompatibleTypes(entityType.ODataFullName(), this.itemType.ODataFullName()));
         }
         this.itemType = (IEdmEntityType)commonBaseType;
     }
 }