internal static IEdmCollectionType GetCollectionType(IEdmType itemType) { if (!itemType.IsODataPrimitiveTypeKind() && !itemType.IsODataComplexTypeKind()) { throw new ODataException(Microsoft.Data.OData.Strings.EdmLibraryExtensions_CollectionItemCanBeOnlyPrimitiveOrComplex); } return(new EdmCollectionType(itemType.ToTypeReference())); }
internal void Add(EntityPropertyMappingInfo epmInfo) { List <EpmSourcePathSegment> list = new List <EpmSourcePathSegment>(); EpmSourcePathSegment root = this.Root; EpmSourcePathSegment segment2 = null; IEdmType actualPropertyType = epmInfo.ActualPropertyType; string[] strArray = epmInfo.Attribute.SourcePath.Split(new char[] { '/' }); int length = strArray.Length; for (int i = 0; i < length; i++) { string propertyName = strArray[i]; if (propertyName.Length == 0) { throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath)); } IEdmTypeReference propertyType = GetPropertyType(actualPropertyType, propertyName); IEdmType type2 = (propertyType == null) ? null : propertyType.Definition; if ((type2 == null) && (i < (length - 1))) { throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_OpenComplexPropertyCannotBeMapped(propertyName, actualPropertyType.ODataFullName())); } actualPropertyType = type2; segment2 = root.SubProperties.SingleOrDefault <EpmSourcePathSegment>(e => e.PropertyName == propertyName); if (segment2 != null) { root = segment2; } else { EpmSourcePathSegment item = new EpmSourcePathSegment(propertyName); root.SubProperties.Add(item); root = item; } list.Add(root); } if ((actualPropertyType != null) && !actualPropertyType.IsODataPrimitiveTypeKind()) { throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_EndsWithNonPrimitiveType(root.PropertyName)); } if (segment2 != null) { if (segment2.EpmInfo.DefiningTypesAreEqual(epmInfo)) { throw new ODataException(Microsoft.Data.OData.Strings.EpmSourceTree_DuplicateEpmAttributesWithSameSourceName(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath)); } this.epmTargetTree.Remove(segment2.EpmInfo); } epmInfo.SetPropertyValuePath(list.ToArray()); root.EpmInfo = epmInfo; this.epmTargetTree.Add(epmInfo); }
/// <summary> /// Returns the IEdmCollectionType implementation with the given IEdmTypeReference as element type. /// </summary> /// <param name="itemType">IEdmTypeReference instance which is the element type.</param> /// <returns>An <see cref="IEdmCollectionType"/> instance using the <paramref name="itemType"/> as Collection item type.</returns> internal static IEdmCollectionType GetCollectionType(IEdmType itemType) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(itemType != null, "itemType != null"); IEdmTypeReference itemTypeReference; if (itemType.IsODataPrimitiveTypeKind() || itemType.IsODataComplexTypeKind()) { itemTypeReference = itemType.ToTypeReference(); } else { throw new ODataException(Strings.EdmLibraryExtensions_CollectionItemCanBeOnlyPrimitiveOrComplex); } return new EdmCollectionType(itemTypeReference); }
/// <summary> /// Adds a path to the source and target tree which is obtained by looking at the EntityPropertyMappingAttribute in the <paramref name="epmInfo"/> /// </summary> /// <param name="epmInfo">EnitityPropertyMappingInfo holding the source path</param> internal void Add(EntityPropertyMappingInfo epmInfo) { DebugUtils.CheckNoExternalCallers(); List <EpmSourcePathSegment> pathToCurrentSegment = new List <EpmSourcePathSegment>(); EpmSourcePathSegment currentSourceSegment = this.Root; EpmSourcePathSegment foundSourceSegment = null; IEdmType currentType = epmInfo.ActualPropertyType; Debug.Assert(!string.IsNullOrEmpty(epmInfo.Attribute.SourcePath), "Invalid source path"); string[] propertyPath = epmInfo.Attribute.SourcePath.Split('/'); int propertyPathLength = propertyPath.Length; Debug.Assert(propertyPathLength > 0, "Must have been validated during EntityPropertyMappingAttribute construction"); for (int sourcePropertyIndex = 0; sourcePropertyIndex < propertyPathLength; sourcePropertyIndex++) { string propertyName = propertyPath[sourcePropertyIndex]; if (propertyName.Length == 0) { throw new ODataException(ODataErrorStrings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath)); } IEdmTypeReference nextPropertyTypeReference = GetPropertyType(currentType, propertyName); IEdmType nextPropertyType = nextPropertyTypeReference == null ? null : nextPropertyTypeReference.Definition; // If we don't find a property type this is an open property; check whether this is the last segment in the path // since otherwise this would not be an open primitive property and only open primitive properties are allowed. if (nextPropertyType == null && sourcePropertyIndex < propertyPathLength - 1) { throw new ODataException(ODataErrorStrings.EpmSourceTree_OpenComplexPropertyCannotBeMapped(propertyName, currentType.ODataFullName())); } currentType = nextPropertyType; 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; } pathToCurrentSegment.Add(currentSourceSegment); } // 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 (!currentType.IsODataPrimitiveTypeKind()) { throw new ODataException(ODataErrorStrings.EpmSourceTree_EndsWithNonPrimitiveType(currentSourceSegment.PropertyName)); } } 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 type, 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 ODataException(ODataErrorStrings.EpmSourceTree_DuplicateEpmAttributesWithSameSourceName(epmInfo.DefiningType.ODataFullName(), epmInfo.Attribute.SourcePath)); } // 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); } epmInfo.SetPropertyValuePath(pathToCurrentSegment.ToArray()); currentSourceSegment.EpmInfo = epmInfo; this.epmTargetTree.Add(epmInfo); }
internal static IEdmCollectionType GetCollectionType(IEdmType itemType) { if (!itemType.IsODataPrimitiveTypeKind() && !itemType.IsODataComplexTypeKind()) { throw new ODataException(Microsoft.Data.OData.Strings.EdmLibraryExtensions_CollectionItemCanBeOnlyPrimitiveOrComplex); } return new EdmCollectionType(itemType.ToTypeReference()); }