Пример #1
0
 public EntityPropertyMappingInfo(EntityPropertyMappingAttribute attribute, Type definingType, ClientTypeAnnotation actualPropertyType)
 {
     this.attribute = attribute;
     this.definingType = definingType;
     this.actualPropertyType = actualPropertyType;
     this.propertyValuePath = attribute.SourcePath.Split(new char[] { '/' });
     this.isSyndicationMapping = this.attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
 }
Пример #2
0
        /// <summary>
        /// Creates instance of EntityPropertyMappingInfo class.
        /// </summary>
        /// <param name="attribute">The <see cref="EntityPropertyMappingAttribute"/> corresponding to this object</param>
        /// <param name="definingType">Type the <see cref="EntityPropertyMappingAttribute"/> was defined on.</param>
        /// <param name="actualPropertyType">ClientType whose property is to be read.</param>
        public EntityPropertyMappingInfo(EntityPropertyMappingAttribute attribute, Type definingType, ClientTypeAnnotation actualPropertyType)
        {
#endif
            Debug.Assert(attribute != null, "attribute != null");
            Debug.Assert(definingType != null, "definingType != null");
            Debug.Assert(actualPropertyType != null, "actualPropertyType != null");

            this.attribute          = attribute;
            this.definingType       = definingType;
            this.actualPropertyType = actualPropertyType;

            Debug.Assert(!string.IsNullOrEmpty(attribute.SourcePath), "Invalid source path");
            this.propertyValuePath = attribute.SourcePath.Split('/');

            // Infer the mapping type from the attribute
            this.isSyndicationMapping = this.attribute.TargetSyndicationItem != SyndicationItemProperty.CustomProperty;
        }
Пример #3
0
        /// <summary>Validates the specified segment and all its subsegments.</summary>
        /// <param name="pathSegment">The path segment to validate.</param>
        /// <param name="resourceType">The resource type of the property represented by this segment (null for open properties).</param>
        /// <param name="declaredPropertiesLookup">The dictionary to lookup and add declaredProperties associated with resourceTypes.</param>
        private static void Validate(EpmSourcePathSegment pathSegment, ClientTypeOrResourceType_Alias resourceType, Dictionary <ResourceType, IEnumerable <ResourceProperty> > declaredPropertiesLookup)
#endif
        {
            Debug.Assert(pathSegment != null, "pathSegment != null");
            foreach (EpmSourcePathSegment subSegment in pathSegment.SubProperties)
            {
#if ASTORIA_CLIENT
                ClientTypeOrResourceType_Alias subSegmentResourceType = GetPropertyType(resourceType, subSegment.PropertyName);

                // sometimes the previous call returns null,  WHY do we even bother
                // to continue on after we can't find a resourceType?
                Validate(subSegment, subSegmentResourceType);
#else
                ClientTypeOrResourceType_Alias subSegmentResourceType = GetPropertyType(resourceType, subSegment.PropertyName, declaredPropertiesLookup);

                // sometimes the previous call returns null,  WHY do we even bother
                // to continue on after we can't find a resourceType?
                Validate(subSegment, subSegmentResourceType, declaredPropertiesLookup);
#endif
            }
        }
Пример #4
0
 private static ClientTypeAnnotation GetPropertyType(ClientTypeAnnotation clientType, string propertyName)
 {
     ClientPropertyAnnotation property = clientType.GetProperty(propertyName, true);
     if (property == null)
     {
         throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.EpmSourceTree_InaccessiblePropertyOnType(propertyName, clientType.ElementTypeName));
     }
     if (property.IsStreamLinkProperty)
     {
         throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.EpmSourceTree_NamedStreamCannotBeMapped(propertyName, clientType.ElementTypeName));
     }
     if (property.IsSpatialType)
     {
         throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.EpmSourceTree_SpatialTypeCannotBeMapped(propertyName, clientType.ElementTypeName));
     }
     if (property.IsPrimitiveOrComplexCollection)
     {
         throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.EpmSourceTree_CollectionPropertyCannotBeMapped(propertyName, clientType.ElementTypeName));
     }
     ClientEdmModel model = ClientEdmModel.GetModel(clientType.MaxProtocolVersion);
     IEdmType orCreateEdmType = model.GetOrCreateEdmType(property.PropertyType);
     return model.GetClientTypeAnnotation(orCreateEdmType);
 }
Пример #5
0
 /// <summary>
 /// Sets the single instance of <see cref="ClientTypeAnnotation"/> on the given instance of <paramref name="edmType"/>.
 /// </summary>
 /// <param name="model">The model the <paramref name="edmType"/> belongs to.</param>
 /// <param name="edmType">IEdmType instance to set the annotation on.</param>
 /// <param name="annotation">The annotation to set</param>
 internal static void SetClientTypeAnnotation(this IEdmModel model, IEdmType edmType, ClientTypeAnnotation annotation)
 {
     Debug.Assert(model != null, "model != null");
     Debug.Assert(edmType != null, "edmType != null");
     Debug.Assert(annotation != null, "annotation != null");
     model.SetAnnotationValue <ClientTypeAnnotation>(edmType, annotation);
 }
Пример #6
0
 /// <summary>
 /// Builds the EntityPropertyMappingInfo corresponding to an EntityPropertyMappingAttribute, also builds the delegate to
 /// be invoked in order to retrieve the property provided in the <paramref name="epmAttr"/>
 /// </summary>
 /// <param name="epmAttr">Source EntityPropertyMappingAttribute</param>
 /// <param name="definingType">ResourceType on which to look for the property</param>
 /// <param name="clientTypeAnnotation">The ClientTypeAnnotation to refer to</param>
 /// <param name="sourceTree">The source tree to populate.</param>
 private static void BuildEpmInfo(EntityPropertyMappingAttribute epmAttr, Type definingType, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
 {
     sourceTree.Add(new System.Data.Services.Client.Serializers.EntityPropertyMappingInfo(epmAttr, definingType, clientTypeAnnotation));
 }
Пример #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);
         }
     }
 }
Пример #8
0
 internal EpmLazyLoader(ClientTypeAnnotation clientTypeAnnotation)
 {
     this.clientTypeAnnotation = clientTypeAnnotation;
 }
Пример #9
0
 internal IEnumerable<ODataProperty> PopulateProperties(ClientTypeAnnotation type, object resource, List<object> visitedComplexTypeObjects)
 {
     List<ODataProperty> list = new List<ODataProperty>();
     foreach (ClientPropertyAnnotation annotation in from p in type.Properties()
         orderby p.PropertyName
         select p)
     {
         if (((!annotation.IsDictionary && (annotation != type.MediaDataMember)) && !annotation.IsStreamLinkProperty) && ((type.MediaDataMember == null) || (type.MediaDataMember.MimeTypeProperty != annotation)))
         {
             object propertyValue = annotation.GetValue(resource);
             if (annotation.IsKnownType)
             {
                 ODataProperty item = new ODataProperty {
                     Name = annotation.EdmProperty.Name,
                     Value = GetPrimitiveValue(propertyValue, annotation.PropertyType)
                 };
                 list.Add(item);
             }
             else if (annotation.IsPrimitiveOrComplexCollection)
             {
                 ODataProperty property2 = new ODataProperty {
                     Name = annotation.EdmProperty.Name,
                     Value = this.CreateODataCollectionPropertyValue(annotation, propertyValue, visitedComplexTypeObjects)
                 };
                 list.Add(property2);
             }
             else if (!annotation.IsEntityCollection && !ClientTypeUtil.TypeIsEntity(annotation.PropertyType, this.requestInfo.MaxProtocolVersion))
             {
                 ODataProperty property3 = new ODataProperty {
                     Name = annotation.EdmProperty.Name,
                     Value = this.CreateODataComplexPropertyValue(annotation, propertyValue, visitedComplexTypeObjects)
                 };
                 list.Add(property3);
             }
         }
     }
     return list;
 }
Пример #10
0
 internal static void SetClientTypeAnnotation(this IEdmType edmType, ClientTypeAnnotation annotation)
 {
     ClientEdmModel.GetModel(annotation.MaxProtocolVersion).SetAnnotationValue<ClientTypeAnnotation>(edmType, annotation);
 }
Пример #11
0
 private ClientTypeAnnotation GetOrCreateClientTypeAnnotation(IEdmType edmType, Type type)
 {
     string key = type.ToString();
     if ((edmType.TypeKind == EdmTypeKind.Complex) || (edmType.TypeKind == EdmTypeKind.Entity))
     {
         lock (this.typeNameToClientTypeAnnotationCache)
         {
             ClientTypeAnnotation annotation;
             if (this.typeNameToClientTypeAnnotationCache.TryGetValue(key, out annotation) && (annotation.ElementType != type))
             {
                 key = type.AssemblyQualifiedName;
                 if (this.typeNameToClientTypeAnnotationCache.TryGetValue(key, out annotation) && (annotation.ElementType != type))
                 {
                     throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.ClientType_MultipleTypesWithSameName(key));
                 }
             }
             if (annotation == null)
             {
                 annotation = new ClientTypeAnnotation(edmType, type, key, this.protocolVersion);
                 this.typeNameToClientTypeAnnotationCache.Add(key, annotation);
             }
             return annotation;
         }
     }
     return new ClientTypeAnnotation(edmType, type, key, this.protocolVersion);
 }
Пример #12
0
 internal string GetServerTypeName(ClientTypeAnnotation clientTypeAnnotation)
 {
     return this.ResolveNameFromType(clientTypeAnnotation.ElementType);
 }
Пример #13
0
 private static void Validate(EpmSourcePathSegment pathSegment, ClientTypeAnnotation resourceType)
 {
     foreach (EpmSourcePathSegment segment in pathSegment.SubProperties)
     {
         ClientTypeAnnotation propertyType = GetPropertyType(resourceType, segment.PropertyName);
         Validate(segment, propertyType);
     }
 }
Пример #14
0
 internal void Validate(ClientTypeAnnotation resourceType)
 {
     Validate(this.Root, resourceType);
 }
Пример #15
0
 private static Version DetermineRequestVersion(ClientTypeAnnotation clientType, EntityStates state)
 {
     if (state == EntityStates.Deleted)
     {
         return Util.DataServiceVersion1;
     }
     Version version = Util.DataServiceVersion1;
     WebUtil.RaiseVersion(ref version, clientType.GetMetadataVersion());
     WebUtil.RaiseVersion(ref version, clientType.EpmMinimumDataServiceProtocolVersion.ToVersion());
     return version;
 }
Пример #16
0
 /// <summary>Validates the source tree.</summary>
 /// <param name="resourceType">The resource type for which the validation is performed.</param>
 internal void Validate(ClientTypeOrResourceType_Alias resourceType)
 {
     Validate(this.Root, resourceType);
 }
Пример #17
0
 /// <summary>Validates the specified segment and all its subsegments.</summary>
 /// <param name="pathSegment">The path segment to validate.</param>
 /// <param name="resourceType">The resource type of the property represented by this segment (null for open properties).</param>
 private static void Validate(EpmSourcePathSegment pathSegment, ClientTypeOrResourceType_Alias resourceType)
Пример #18
0
 protected static void ApplyDataValues(ClientTypeAnnotation type, IEnumerable<ODataProperty> properties, bool ignoreMissingProperties, System.Data.Services.Client.ResponseInfo responseInfo, object instance)
 {
     foreach (ODataProperty property in properties)
     {
         ApplyDataValue(type, property, ignoreMissingProperties, responseInfo, instance);
     }
 }
Пример #19
0
        internal void Add(EntityPropertyMappingInfo epmInfo, IEnumerable <ResourceProperty> declaredProperties)
        {
            Dictionary <ResourceType, IEnumerable <ResourceProperty> > declaredPropertiesLookup = new Dictionary <ResourceType, IEnumerable <ResourceProperty> >(EqualityComparer <ResourceType> .Default);

            declaredPropertiesLookup.Add(epmInfo.ActualPropertyType, declaredProperties);
#endif
            EpmSourcePathSegment           currentSourceSegment = this.Root;
            EpmSourcePathSegment           foundSourceSegment   = null;
            ClientTypeOrResourceType_Alias currentType          = epmInfo.ActualPropertyType;

            Debug.Assert(epmInfo.PropertyValuePath != null && epmInfo.PropertyValuePath.Length > 0, "Must have been validated during EntityPropertyMappingAttribute construction");
            for (int sourcePropertyIndex = 0; sourcePropertyIndex < epmInfo.PropertyValuePath.Length; sourcePropertyIndex++)
            {
                string propertyName = epmInfo.PropertyValuePath[sourcePropertyIndex];

                if (propertyName.Length == 0)
                {
                    throw new InvalidOperationException(c.Strings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.Name, epmInfo.Attribute.SourcePath));
                }

#if ASTORIA_CLIENT
                currentType = GetPropertyType(currentType, propertyName);
#else
                currentType = GetPropertyType(currentType, propertyName, declaredPropertiesLookup);
#endif

                foundSourceSegment = currentSourceSegment.SubProperties.SingleOrDefault(e => e.PropertyName == propertyName);
                if (foundSourceSegment != null)
                {
                    currentSourceSegment = foundSourceSegment;
                }
                else
                {
                    EpmSourcePathSegment newSourceSegment = new EpmSourcePathSegment(propertyName);
                    currentSourceSegment.SubProperties.Add(newSourceSegment);
                    currentSourceSegment = newSourceSegment;
                }
            }

            // The last segment is the one being mapped from by the user specified attribute.
            // It must be a primitive type - we don't allow mappings of anything else than primitive properties directly.
            // Note that we can only verify this for non-open properties, for open properties we must assume it's a primitive type
            //   and we will make this check later during serialization again when we actually have the value of the property.
            if (currentType != null)
            {
#if ASTORIA_CLIENT
                if (!PrimitiveType.IsKnownNullableType(currentType.ElementType))
#else
                if (currentType.ResourceTypeKind != ResourceTypeKind.Primitive)
#endif
                {
                    throw new InvalidOperationException(c.Strings.EpmSourceTree_EndsWithNonPrimitiveType(currentSourceSegment.PropertyName));
                }
            }

            // Note that once we're here the EpmInfo we have is never the collection property itself, it's always either a non-collection property
            //   or collection item property.
            Debug.Assert(foundSourceSegment == null || foundSourceSegment.EpmInfo != null, "Can't have a leaf node in the tree without EpmInfo.");

            // Two EpmAttributes with same PropertyName in the same ResourceType, this could be a result of inheritance
            if (foundSourceSegment != null)
            {
                Debug.Assert(Object.ReferenceEquals(foundSourceSegment, currentSourceSegment), "currentSourceSegment variable should have been updated already to foundSourceSegment");

                // Check for duplicates on the same entity type
                Debug.Assert(foundSourceSegment.SubProperties.Count == 0, "If non-leaf, it means we allowed complex type to be a leaf node");
                if (foundSourceSegment.EpmInfo.DefiningTypesAreEqual(epmInfo))
                {
                    throw new InvalidOperationException(c.Strings.EpmSourceTree_DuplicateEpmAttrsWithSameSourceName(epmInfo.Attribute.SourcePath, epmInfo.DefiningType.Name));
                }

                // In case of inheritance, we need to remove the node from target tree which was mapped to base type property
                this.epmTargetTree.Remove(foundSourceSegment.EpmInfo);
            }

            currentSourceSegment.EpmInfo = epmInfo;

            this.epmTargetTree.Add(epmInfo);
        }
Пример #20
0
 protected static void MaterializeDataValues(ClientTypeAnnotation actualType, IEnumerable<ODataProperty> values, bool ignoreMissingProperties)
 {
     foreach (ODataProperty property in values)
     {
         if (!(property.Value is ODataStreamReferenceValue))
         {
             string name = property.Name;
             ClientPropertyAnnotation annotation = actualType.GetProperty(name, ignoreMissingProperties);
             if (annotation != null)
             {
                 if (ClientTypeUtil.TypeOrElementTypeIsEntity(annotation.PropertyType))
                 {
                     throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidEntityType(annotation.EntityCollectionItemType ?? annotation.PropertyType));
                 }
                 if (annotation.IsKnownType)
                 {
                     MaterializePrimitiveDataValue(annotation.NullablePropertyType, property);
                 }
             }
         }
     }
 }
Пример #21
0
 internal static void SetClientTypeAnnotation(this IEdmType edmType, ClientTypeAnnotation annotation)
 {
     ClientEdmModel.GetModel(annotation.MaxProtocolVersion).SetAnnotationValue <ClientTypeAnnotation>(edmType, annotation);
 }
Пример #22
0
 protected static void ApplyDataValue(ClientTypeAnnotation type, ODataProperty property, bool ignoreMissingProperties, System.Data.Services.Client.ResponseInfo responseInfo, object instance)
 {
     ClientPropertyAnnotation annotation = type.GetProperty(property.Name, ignoreMissingProperties);
     if (annotation != null)
     {
         if (annotation.IsPrimitiveOrComplexCollection)
         {
             if (property.Value == null)
             {
                 throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Collection_NullCollectionNotSupported(property.Name));
             }
             if (property.Value is string)
             {
                 throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_MixedTextWithComment);
             }
             if (property.Value is ODataComplexValue)
             {
                 throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidCollectionItem(property.Name));
             }
             object obj2 = annotation.GetValue(instance);
             if (obj2 == null)
             {
                 obj2 = CreateCollectionInstance(property, annotation.PropertyType, responseInfo);
                 annotation.SetValue(instance, obj2, property.Name, false);
             }
             else
             {
                 annotation.ClearBackingICollectionInstance(obj2);
             }
             ApplyCollectionDataValues(property, ignoreMissingProperties, responseInfo, obj2, annotation.PrimitiveOrComplexCollectionItemType, new Action<object, object>(annotation.AddValueToBackingICollectionInstance));
         }
         else
         {
             object obj3 = property.Value;
             ODataComplexValue value2 = obj3 as ODataComplexValue;
             if ((obj3 != null) && (value2 != null))
             {
                 if (!annotation.EdmProperty.Type.IsComplex())
                 {
                     throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Deserialize_ExpectingSimpleValue);
                 }
                 bool flag = false;
                 ClientEdmModel model = ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion);
                 ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(annotation.PropertyType));
                 object obj4 = annotation.GetValue(instance);
                 if (obj4 == null)
                 {
                     obj4 = clientTypeAnnotation.CreateInstance();
                     flag = true;
                 }
                 MaterializeDataValues(clientTypeAnnotation, value2.Properties, ignoreMissingProperties);
                 ApplyDataValues(clientTypeAnnotation, value2.Properties, ignoreMissingProperties, responseInfo, obj4);
                 if (flag)
                 {
                     annotation.SetValue(instance, obj4, property.Name, true);
                 }
             }
             else
             {
                 MaterializePrimitiveDataValue(annotation.NullablePropertyType, property);
                 annotation.SetValue(instance, property.GetMaterializedValue(), property.Name, true);
             }
         }
     }
 }
Пример #23
0
 private static void BuildEpmInfo(ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
 {
     BuildEpmInfo(clientTypeAnnotation.ElementType, clientTypeAnnotation, sourceTree);
 }
Пример #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EpmLazyLoader"/> class.
 /// </summary>
 /// <param name="clientTypeAnnotation">The client type annotation.</param>
 internal EpmLazyLoader(ClientTypeAnnotation clientTypeAnnotation)
 {
     this.clientTypeAnnotation = clientTypeAnnotation;
 }
Пример #25
0
 private static void BuildEpmInfo(EntityPropertyMappingAttribute epmAttr, Type definingType, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
 {
     sourceTree.Add(new System.Data.Services.Client.Serializers.EntityPropertyMappingInfo(epmAttr, definingType, clientTypeAnnotation));
 }
Пример #26
0
 /// <summary>
 /// By going over EntityPropertyMappingInfoAttribute(s) defined on the ElementType
 /// builds the corresponding EntityPropertyMappingInfo
 /// </summary>
 /// <param name="clientTypeAnnotation">The ClientTypeAnnotation to refer to</param>
 /// <param name="sourceTree">The source tree to populate.</param>
 /// <remarks>This method should be called after all properties are set on the edm type.</remarks>
 private static void BuildEpmInfo(ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree)
 {
     BuildEpmInfo(clientTypeAnnotation.ElementType, clientTypeAnnotation, sourceTree);
 }