Exemplo n.º 1
0
            /// <summary>
            /// By going over EntityPropertyMappingInfoAttribute(s) defined on <paramref name="type"/>
            /// builds the corresponding EntityPropertyMappingInfo
            /// </summary>
            /// <param name="type">Type being looked at</param>
            /// <param name="clientTypeAnnotation">The ClientTypeAnnotation to refer to</param>
            /// <param name="sourceTree">The source tree to populate.</param>
            private static void BuildEpmInfo(Type type, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
            {
                // EPM is only allowed on entity types.  Note that we can't throw now if the EPM attribute is on a complex type since we didn't throw when we ship V2.
                if (clientTypeAnnotation.IsEntityType)
                {
                    Type baseType = c.PlatformHelper.GetBaseType(type);
                    ClientTypeAnnotation baseClientTypeAnnotation = null;
                    ClientEdmModel       clientEdmModel           = clientTypeAnnotation.model;
                    ODataEntityPropertyMappingCollection mappings = null;

                    if (baseType != null && baseType != typeof(object))
                    {
                        // have CLR base type
                        if (((EdmStructuredType)clientTypeAnnotation.EdmType).BaseType == null)
                        {
                            // CLR base type is not an entity type - append its EPM onto the current type annotation
                            BuildEpmInfo(baseType, clientTypeAnnotation, sourceTree);

                            // we should not create a new mapping in this case
                            mappings = clientEdmModel.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType);
                        }
                        else
                        {
                            // CLR base type is an entity type, build EPM onto the base type annotation
                            baseClientTypeAnnotation = clientEdmModel.GetClientTypeAnnotation(baseType);
                            BuildEpmInfo(baseType, baseClientTypeAnnotation, sourceTree);
                        }
                    }

                    foreach (EntityPropertyMappingAttribute epmAttr in type.GetCustomAttributes(typeof(EntityPropertyMappingAttribute), false))
                    {
                        BuildEpmInfo(epmAttr, type, clientTypeAnnotation, sourceTree);

                        // Add these mappings to the ODataEntityPropertyMapping class so that
                        // ODataLib can consume them
                        if (mappings == null)
                        {
                            mappings = new ODataEntityPropertyMappingCollection();
                        }

                        mappings.Add(epmAttr);
                    }

                    if (mappings != null)
                    {
                        ODataEntityPropertyMappingCollection oldMappings = clientEdmModel.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType);
                        if (oldMappings != null)
                        {
                            List <EntityPropertyMappingAttribute> exclusiveMappings = oldMappings.Where(oldM => !mappings.Any(newM => oldM.SourcePath == newM.SourcePath)).ToList();
                            foreach (EntityPropertyMappingAttribute epmAttr in exclusiveMappings)
                            {
                                mappings.Add(epmAttr);
                            }
                        }

                        clientEdmModel.SetAnnotationValue(clientTypeAnnotation.EdmType, mappings);
                    }
                }
            }
 internal bool IsDirty(ODataEntityPropertyMappingCollection propertyMappings)
 {
     if ((this.mappings == null) && (propertyMappings == null))
     {
         return false;
     }
     return (!object.ReferenceEquals(this.mappings, propertyMappings) || (this.mappings.Count != propertyMappings.Count));
 }
 internal ODataEntityPropertyMappingCache(ODataEntityPropertyMappingCollection mappings, IEdmModel model, int totalMappingCount)
 {
     this.mappings = mappings;
     this.model = model;
     this.totalMappingCount = totalMappingCount;
     this.mappingsForInheritedProperties = new List<EntityPropertyMappingAttribute>();
     this.mappingsForDeclaredProperties = (mappings == null) ? new List<EntityPropertyMappingAttribute>() : new List<EntityPropertyMappingAttribute>(mappings);
     this.epmTargetTree = new Microsoft.Data.OData.Metadata.EpmTargetTree();
     this.epmSourceTree = new Microsoft.Data.OData.Metadata.EpmSourceTree(this.epmTargetTree);
 }
Exemplo n.º 4
0
        internal static void ConvertEntityPropertyMappings(MetadataProviderEdmModel model, ResourceType resourceType, EdmEntityType entityType)
        {
            IEnumerable <EntityPropertyMappingAttribute> allEpmInfo = resourceType.AllEpmInfo;

            if (allEpmInfo != null)
            {
                ODataEntityPropertyMappingCollection mappings = new ODataEntityPropertyMappingCollection();
                foreach (EntityPropertyMappingAttribute attribute in allEpmInfo)
                {
                    mappings.Add(attribute);
                }
                model.SetAnnotationValue <ODataEntityPropertyMappingCollection>(entityType, mappings);
            }
        }
Exemplo n.º 5
0
 private static void BuildEpmInfo(Type type, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
 {
     if (clientTypeAnnotation.IsEntityType)
     {
         Func <EntityPropertyMappingAttribute, bool> predicate = null;
         Type baseType = type.BaseType;
         ClientTypeAnnotation annotation = null;
         ClientEdmModel       model      = ClientEdmModel.GetModel(clientTypeAnnotation.MaxProtocolVersion);
         ODataEntityPropertyMappingCollection mappings = null;
         if ((baseType != null) && (baseType != typeof(object)))
         {
             if (((EdmStructuredType)clientTypeAnnotation.EdmType).BaseType == null)
             {
                 BuildEpmInfo(baseType, clientTypeAnnotation, sourceTree);
                 mappings = model.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType);
             }
             else
             {
                 annotation = model.GetClientTypeAnnotation(baseType);
                 BuildEpmInfo(baseType, annotation, sourceTree);
             }
         }
         foreach (EntityPropertyMappingAttribute attribute in type.GetCustomAttributes(typeof(EntityPropertyMappingAttribute), false))
         {
             BuildEpmInfo(attribute, type, clientTypeAnnotation, sourceTree);
             if (mappings == null)
             {
                 mappings = new ODataEntityPropertyMappingCollection();
             }
             mappings.Add(attribute);
         }
         if (mappings != null)
         {
             ODataEntityPropertyMappingCollection annotationValue = model.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType);
             if (annotationValue != null)
             {
                 if (predicate == null)
                 {
                     predicate = oldM => !mappings.Any <EntityPropertyMappingAttribute>(newM => (oldM.SourcePath == newM.SourcePath));
                 }
                 foreach (EntityPropertyMappingAttribute attribute2 in annotationValue.Where <EntityPropertyMappingAttribute>(predicate).ToList <EntityPropertyMappingAttribute>())
                 {
                     mappings.Add(attribute2);
                 }
             }
             model.SetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType, mappings);
         }
     }
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="mappings">The EPM mappings to create the cache for.</param>
        /// <param name="model">The EDM model.</param>
        /// <param name="totalMappingCount">The total number of entity property mappings 
        /// for the entity type that this cache is created for (on the type itself and all its base types).</param>
        internal ODataEntityPropertyMappingCache(ODataEntityPropertyMappingCollection mappings, IEdmModel model, int totalMappingCount)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(model.IsUserModel(), "model.IsUserModel()");

            this.mappings = mappings;
            this.model = model;
            this.totalMappingCount = totalMappingCount;

            // Note that we new up everything here eagerly because we will only create the EPM annotation for types
            // for which we know for sure that they have EPM and thus we will need all of these anyway.
            this.mappingsForInheritedProperties = new List<EntityPropertyMappingAttribute>();
            this.mappingsForDeclaredProperties = mappings == null
                ? new List<EntityPropertyMappingAttribute>()
                : new List<EntityPropertyMappingAttribute>(mappings);
            this.epmTargetTree = new EpmTargetTree();
            this.epmSourceTree = new EpmSourceTree(this.epmTargetTree);
        }
Exemplo n.º 7
0
 private static void BuildEpmInfo(Type type, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
 {
     if (clientTypeAnnotation.IsEntityType)
     {
         Func<EntityPropertyMappingAttribute, bool> predicate = null;
         Type baseType = type.BaseType;
         ClientTypeAnnotation annotation = null;
         ClientEdmModel model = ClientEdmModel.GetModel(clientTypeAnnotation.MaxProtocolVersion);
         ODataEntityPropertyMappingCollection mappings = null;
         if ((baseType != null) && (baseType != typeof(object)))
         {
             if (((EdmStructuredType) clientTypeAnnotation.EdmType).BaseType == null)
             {
                 BuildEpmInfo(baseType, clientTypeAnnotation, sourceTree);
                 mappings = model.GetAnnotationValue<ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType);
             }
             else
             {
                 annotation = model.GetClientTypeAnnotation(baseType);
                 BuildEpmInfo(baseType, annotation, sourceTree);
             }
         }
         foreach (EntityPropertyMappingAttribute attribute in type.GetCustomAttributes(typeof(EntityPropertyMappingAttribute), false))
         {
             BuildEpmInfo(attribute, type, clientTypeAnnotation, sourceTree);
             if (mappings == null)
             {
                 mappings = new ODataEntityPropertyMappingCollection();
             }
             mappings.Add(attribute);
         }
         if (mappings != null)
         {
             ODataEntityPropertyMappingCollection annotationValue = model.GetAnnotationValue<ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType);
             if (annotationValue != null)
             {
                 if (predicate == null)
                 {
                     predicate = oldM => !mappings.Any<EntityPropertyMappingAttribute>(newM => (oldM.SourcePath == newM.SourcePath));
                 }
                 foreach (EntityPropertyMappingAttribute attribute2 in annotationValue.Where<EntityPropertyMappingAttribute>(predicate).ToList<EntityPropertyMappingAttribute>())
                 {
                     mappings.Add(attribute2);
                 }
             }
             model.SetAnnotationValue<ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType, mappings);
         }
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Loads the serializable EPM annotations on the given <paramref name="annotatable"/> into their in-memory representation.
        /// </summary>
        /// <param name="model">The model the annotatable belongs to.</param>
        /// <param name="annotatable">The <see cref="IEdmElement"/> to load the EPM annotations for.</param>
        /// <param name="mappings">The collection of EPM annotations to add newly loaded annotations to.</param>
        /// <param name="typeName">The name of the type for which to load the annotations or that declares the <paramref name="property"/>. Only used in error messages.</param>
        /// <param name="property">The property to parse the EPM annotations for.</param>
        private static void LoadEpmAnnotations(this IEdmModel model, IEdmElement annotatable, ODataEntityPropertyMappingCollection mappings, string typeName, IEdmProperty property)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(model != null, "model != null");
            Debug.Assert(annotatable != null, "annotatable != null");
            Debug.Assert(mappings != null, "mappings != null");
            Debug.Assert(!string.IsNullOrEmpty(typeName), "!string.IsNullOrEmpty(typeName)");

            IEnumerable<EpmAnnotationValues> allAnnotationValues = ParseSerializableEpmAnnotations(model, annotatable, typeName, property);

            if (allAnnotationValues != null)
            {
                foreach (EpmAnnotationValues annotationValues in allAnnotationValues)
                {
                    // check whether we found a valid EPM configuration
                    EntityPropertyMappingAttribute mapping = ValidateAnnotationValues(annotationValues, typeName, property);
                    mappings.Add(mapping);
                }
            }
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
 internal static int ValidateTotalEntityPropertyMappingCount(ODataEntityPropertyMappingCache baseCache, ODataEntityPropertyMappingCollection mappings, int maxMappingCount)
 {
     int num = (baseCache == null) ? 0 : baseCache.TotalMappingCount;
     int num2 = (mappings == null) ? 0 : mappings.Count;
     int num3 = num + num2;
     if (num3 > maxMappingCount)
     {
         throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_MaxNumberOfEntityPropertyMappingsExceeded(num3, maxMappingCount));
     }
     return num3;
 }
Exemplo n.º 11
0
        internal static int ValidateTotalEntityPropertyMappingCount(ODataEntityPropertyMappingCache baseCache, ODataEntityPropertyMappingCollection mappings, int maxMappingCount)
        {
            int num  = (baseCache == null) ? 0 : baseCache.TotalMappingCount;
            int num2 = (mappings == null) ? 0 : mappings.Count;
            int num3 = num + num2;

            if (num3 > maxMappingCount)
            {
                throw new ODataException(Microsoft.Data.OData.Strings.ValidationUtils_MaxNumberOfEntityPropertyMappingsExceeded(num3, maxMappingCount));
            }
            return(num3);
        }
Exemplo n.º 12
0
 private static void LoadEpmAnnotations(this IEdmModel model, IEdmElement annotatable, ODataEntityPropertyMappingCollection mappings, string typeName, IEdmProperty property)
 {
     IEnumerable<EpmAnnotationValues> enumerable = model.ParseSerializableEpmAnnotations(annotatable, typeName, property);
     if (enumerable != null)
     {
         foreach (EpmAnnotationValues values in enumerable)
         {
             EntityPropertyMappingAttribute mapping = ValidateAnnotationValues(values, typeName, property);
             mappings.Add(mapping);
         }
     }
 }
Exemplo n.º 13
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);
 }
Exemplo n.º 14
0
        /// <summary>
        /// Validates that the total number of entity property mapping attributes on the base entity type and the current
        /// entity type does not exceed the specified security limit.
        /// </summary>
        /// <param name="baseCache">The EPM cache of the base entity type or null if no base entity type exists.</param>
        /// <param name="mappings">The EPM collection of the current entity type.</param>
        /// <param name="maxMappingCount">The maximum number of mappings allowed for an entity type (on the type itself and all its base types).</param>
        /// <returns>The total number of entity property mappings for the current entity type.</returns>
        internal static int ValidateTotalEntityPropertyMappingCount(ODataEntityPropertyMappingCache baseCache, ODataEntityPropertyMappingCollection mappings, int maxMappingCount)
        {
            DebugUtils.CheckNoExternalCallers();

            int countOfMappingsOnBaseTypes   = baseCache == null ? 0 : baseCache.TotalMappingCount;
            int countOfMappingsOnCurrentType = mappings == null ? 0 : mappings.Count;
            int totalMappingCount            = countOfMappingsOnBaseTypes + countOfMappingsOnCurrentType;

            if (totalMappingCount > maxMappingCount)
            {
                throw new ODataException(Strings.ValidationUtils_MaxNumberOfEntityPropertyMappingsExceeded(totalMappingCount, maxMappingCount));
            }

            return(totalMappingCount);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Validates that the total number of entity property mapping attributes on the base entity type and the current
        /// entity type does not exceed the specified security limit.
        /// </summary>
        /// <param name="baseCache">The EPM cache of the base entity type or null if no base entity type exists.</param>
        /// <param name="mappings">The EPM collection of the current entity type.</param>
        /// <param name="maxMappingCount">The maximum number of mappings allowed for an entity type (on the type itself and all its base types).</param>
        /// <returns>The total number of entity property mappings for the current entity type.</returns>
        internal static int ValidateTotalEntityPropertyMappingCount(ODataEntityPropertyMappingCache baseCache, ODataEntityPropertyMappingCollection mappings, int maxMappingCount)
        {
            DebugUtils.CheckNoExternalCallers();

            int countOfMappingsOnBaseTypes = baseCache == null ? 0 : baseCache.TotalMappingCount;
            int countOfMappingsOnCurrentType = mappings == null ? 0 : mappings.Count;
            int totalMappingCount = countOfMappingsOnBaseTypes + countOfMappingsOnCurrentType;
            if (totalMappingCount > maxMappingCount)
            {
                throw new ODataException(Strings.ValidationUtils_MaxNumberOfEntityPropertyMappingsExceeded(totalMappingCount, maxMappingCount));
            }

            return totalMappingCount;
        }
        /// <summary>
        /// Checks whether the current cache is dirty with respect to the <paramref name="propertyMappings"/>.
        /// </summary>
        /// <param name="propertyMappings">The EPM mappings to check this cache against.</param>
        /// <returns>true if the <paramref name="propertyMappings"/> are not the same as the ones the cache has been created for (or have changed).</returns>
        internal bool IsDirty(ODataEntityPropertyMappingCollection propertyMappings)
        {
            DebugUtils.CheckNoExternalCallers();
         
            // NOTE: we only allow adding more mappings to an existing collection; so if the 
            // references of the collections are the same and the counts are the same there has been no change.
            if (this.mappings == null && propertyMappings == null)
            {
                return false;
            }

            if (!object.ReferenceEquals(this.mappings, propertyMappings))
            {
                return true;
            }

            return this.mappings.Count != propertyMappings.Count;
        }