/// <summary> /// Sets the expected property for the top-level property instance. /// </summary> /// <param name="property">The property instance to set the expected property for.</param> /// <param name="owningType">The type owning the expected property.</param> /// <param name="expectedPropertyName">The name of the property to set as the expected property.</param> /// <returns>The <paramref name="property"/> after its expected property was set.</returns> public static PropertyInstance ExpectedProperty( this PropertyInstance property, NamedStructuralType owningType, string expectedPropertyName) { ExceptionUtilities.CheckArgumentNotNull(property, "property"); ExceptionUtilities.CheckArgumentNotNull(owningType, "owningType"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(expectedPropertyName, "expectedPropertyName"); ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(property); annotation.OwningType = owningType; MemberProperty memberProperty = owningType.GetProperty(expectedPropertyName); if (memberProperty != null) { annotation.MemberProperty = memberProperty; annotation.ExpectedType = memberProperty.PropertyType; } else { ExceptionUtilities.Assert(owningType.IsOpen, "For non-declared properties the owning type must be open."); annotation.OpenMemberPropertyName = expectedPropertyName; } return(property); }
/// <summary> /// Sets the expected base entity type for the top-level entity set. /// </summary> /// <param name="entitySetInstance">The entity set instance to set the expected set for.</param> /// <param name="entitySet">The entity set the entities belong to.</param> /// <param name="baseEntityType">The base entity type to set as the expected base entity type.</param> /// <returns>The <paramref name="entitySetInstance"/> after its expected type was set.</returns> public static EntitySetInstance ExpectedEntityType(this EntitySetInstance entitySetInstance, EntitySet entitySet, EntityDataType baseEntityType) { ExceptionUtilities.CheckArgumentNotNull(entitySetInstance, "entitySetInstance"); ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(entitySetInstance); EntityDataType entityType = baseEntityType ?? (entitySet == null ? null : DataTypes.EntityType.WithDefinition(entitySet.EntityType)); annotation.ExpectedType = entityType; annotation.EntitySet = entitySet; return(entitySetInstance); }
/// <summary> /// Sets the expected base entity type for the top-level entity set. /// </summary> /// <param name="entitySetInstance">The entity set instance to set the expected set for.</param> /// <param name="entitySet">The entity set the entities belong to.</param> /// <param name="baseEntityType">The base entity type to set as the expected base entity type.</param> /// <returns>The <paramref name="entitySetInstance"/> after its expected type was set.</returns> public static EntitySetInstance ExpectedEntityType(this EntitySetInstance entitySetInstance, IEdmTypeReference baseEntityType, IEdmEntitySet entitySet = null) { ExceptionUtilities.CheckArgumentNotNull(entitySetInstance, "entitySetInstance"); ExpectedTypeODataPayloadElementAnnotation annotation = ODataPayloadElementExtensions.AddExpectedTypeAnnotation(entitySetInstance); var entityType = baseEntityType ?? (entitySet == null ? null : entitySet.EntityType().ToTypeReference()); annotation.EdmExpectedType = entityType; annotation.EdmEntitySet = entitySet; return(entitySetInstance); }
/// <summary> /// Sets the expected function import for a top-level payload element. /// </summary> /// <param name="payloadElement">The payload element to set the expected function import for.</param> /// <param name="functionImport">The function import to set.</param> /// <returns>The <paramref name="payloadElement"/> after its expected function import was set.</returns> public static T ExpectedFunctionImport <T>( this T payloadElement, EdmOperationImport functionImport) where T : ODataPayloadElement { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(payloadElement); annotation.ProductFunctionImport = functionImport; return(payloadElement); }
/// <summary> /// Gets or adds the expected type annotation. /// </summary> /// <param name="payloadElement">The payload element to get or add the annotation to.</param> /// <returns>The expected type annotation to use.</returns> public static ExpectedTypeODataPayloadElementAnnotation AddExpectedTypeAnnotation(this ODataPayloadElement payloadElement) { Debug.Assert(payloadElement != null, "payloadElement != null"); var expectedTypeAnnotation = payloadElement.GetAnnotation <ExpectedTypeODataPayloadElementAnnotation>(); if (expectedTypeAnnotation == null) { expectedTypeAnnotation = new ExpectedTypeODataPayloadElementAnnotation(); payloadElement.SetAnnotation(expectedTypeAnnotation); } return(expectedTypeAnnotation); }
/// <summary> /// Gets or adds the expected type annotation. /// </summary> /// <param name="payloadElement">The payload element to get or add the annotation to.</param> /// <returns>The expected type annotation to use.</returns> public static ExpectedTypeODataPayloadElementAnnotation AddExpectedTypeAnnotation(this ODataPayloadElement payloadElement, IEdmType expectedType) { Debug.Assert(payloadElement != null, "payloadElement != null"); var expectedTypeAnnotation = payloadElement.GetAnnotation <ExpectedTypeODataPayloadElementAnnotation>(); if (expectedTypeAnnotation == null) { expectedTypeAnnotation = new ExpectedTypeODataPayloadElementAnnotation(); payloadElement.SetAnnotation(expectedTypeAnnotation); } expectedTypeAnnotation.EdmExpectedType = expectedType.ToTypeReference(); return(expectedTypeAnnotation); }
/// <summary> /// Sets the expected navigation property for a top-level entity reference links collection. /// </summary> /// <param name="entityReferenceLinks">The entity reference links collection to set the expected navigation property for.</param> /// <param name="owningType">The type owning the expected property.</param> /// <param name="navigationPropertyName">The name of the navigation property to set as the expected property.</param> /// <returns>The <paramref name="entityReferenceLinks"/> after its expected property was set.</returns> public static LinkCollection ExpectedNavigationProperty( this LinkCollection entityReferenceLinks, EntitySet entitySet, EntityType owningType, string navigationPropertyName) { ExceptionUtilities.CheckArgumentNotNull(entityReferenceLinks, "entityReferenceLinks"); ExceptionUtilities.CheckArgumentNotNull(owningType, "owningType"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(navigationPropertyName, "navigationProperty"); ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(entityReferenceLinks); annotation.EntitySet = entitySet; annotation.OwningType = owningType; annotation.NavigationProperty = owningType.GetNavigationProperty(navigationPropertyName); return(entityReferenceLinks); }
/// <summary> /// Sets the expected navigation property for a top-level entity reference link. /// </summary> /// <param name="entityReferenceLink">The entity reference link instance to set the expected navigation property for.</param> /// <param name="owningType">The type owning the expected property.</param> /// <param name="navigationPropertyName">The name of the navigation property to set as the expected property.</param> /// <returns>The <paramref name="entityReferenceLink"/> after its expected property was set.</returns> public static DeferredLink ExpectedNavigationProperty( this DeferredLink entityReferenceLink, IEdmEntitySet entitySet, IEdmEntityType owningType, string navigationPropertyName) { ExceptionUtilities.CheckArgumentNotNull(entityReferenceLink, "entityReferenceLink"); ExceptionUtilities.CheckArgumentNotNull(owningType, "owningType"); ExceptionUtilities.CheckStringArgumentIsNotNullOrEmpty(navigationPropertyName, "navigationPropertyName"); ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(entityReferenceLink); annotation.EdmEntitySet = entitySet; annotation.EdmOwningType = owningType; annotation.EdmNavigationProperty = owningType.FindProperty(navigationPropertyName); return(entityReferenceLink); }
/// <summary> /// Sets an expected type annotation. /// </summary> /// <param name="payloadElement">The payload element to set the annotation on.</param> /// <param name="annotation">The <see cref="ExpectedTypeODataPayloadElementAnnotation"/> to add to <paramref name="payloadElement"/>.</param> /// <returns>The annotated <paramref name="payloadElement"/> for composability.</returns> public static ODataPayloadElement AddExpectedTypeAnnotation(this ODataPayloadElement payloadElement, ExpectedTypeODataPayloadElementAnnotation annotation) { Debug.Assert(payloadElement != null, "payloadElement != null"); payloadElement.SetAnnotation(annotation); return(payloadElement); }
/// <summary> /// Returns the navigation property for the given payload element (only for entity reference links). /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the navigation property from.</param> /// <returns>The expected navigation property for the specified payload element.</returns> private static IEdmNavigationProperty GetExpectedNavigationProperty(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model) { ExceptionUtilities.Assert(model != null, "model != null"); if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.EdmNavigationProperty != null) { return expectedTypeAnnotation.EdmNavigationProperty as IEdmNavigationProperty; } NavigationProperty expectedNavigationProperty = expectedTypeAnnotation.NavigationProperty; if (expectedNavigationProperty != null) { NamedStructuralType expectedOwningType = expectedTypeAnnotation.OwningType; ExceptionUtilities.Assert(expectedOwningType != null, "Need an owning type if a navigation property is specified."); IEdmEntityType owningEntityType = model.FindType(expectedOwningType.FullName) as IEdmEntityType; ExceptionUtilities.Assert(owningEntityType != null, "Did not find expected entity type in the model."); IEdmNavigationProperty navigationProperty = owningEntityType.FindProperty(expectedNavigationProperty.Name) as IEdmNavigationProperty; ExceptionUtilities.Assert(navigationProperty != null, "Did not find expected navigation property in the model."); return navigationProperty; } } return null; }
/// <summary> /// Returns the structural property for the given payload element (only for properties). /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the structural property from.</param> /// <returns>The expected structural property for the specified payload element.</returns> private static IEdmStructuralProperty GetExpectedStructuralProperty(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model) { ExceptionUtilities.Assert(model != null, "model != null"); if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.EdmProperty != null) { return expectedTypeAnnotation.EdmProperty as IEdmStructuralProperty; } MemberProperty expectedStructuralProperty = expectedTypeAnnotation.MemberProperty; if (expectedStructuralProperty != null) { NamedStructuralType expectedOwningType = expectedTypeAnnotation.OwningType; ExceptionUtilities.Assert(expectedOwningType != null, "Need an owning type if a structural property is specified."); IEdmStructuredType owningType = model.FindType(expectedOwningType.FullName) as IEdmStructuredType; ExceptionUtilities.Assert(owningType != null, "Did not find expected structured type in the model."); IEdmStructuralProperty structuralProperty = owningType.FindProperty(expectedStructuralProperty.Name) as IEdmStructuralProperty; ExceptionUtilities.Assert(structuralProperty != null, "Did not find expected structural property in the model."); return structuralProperty; } } return null; }
/// <summary> /// Returns the entity set for the given payload element (only for entries and feeds). /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the type from.</param> /// <param name="payloadElement">The payload element to get the expected type for.</param> /// <returns>The expected type for the specified payload element.</returns> private static IEdmEntitySet GetExpectedEntitySet(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model, ODataPayloadElement payloadElement) { ExceptionUtilities.Assert(model != null, "model != null"); ExceptionUtilities.Assert(payloadElement != null, "payloadElement != null"); if (payloadElement.GetAnnotation<IgnoreEntitySetAnnotation>() != null) { // Entity set information is explicitly ignored return null; } if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.EdmEntitySet != null) { return expectedTypeAnnotation.EdmEntitySet; } EntitySet entitySet = expectedTypeAnnotation.EntitySet; if (entitySet != null) { return model.EntityContainersAcrossModels().Select(m => m.FindEntitySet(entitySet.Name)).FirstOrDefault(s => s != null); } } EntityModelTypeAnnotation typeAnnotation = payloadElement.GetAnnotation<EntityModelTypeAnnotation>(); if (typeAnnotation != null) { var edmEntityType = typeAnnotation.EdmModelType; return model.EntityContainersAcrossModels().First().EntitySets().SingleOrDefault(es => es.EntityType().FullName() == edmEntityType.FullName()); } return null; }
/// <summary> /// Returns the expected type for the given payload element. /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the type from.</param> /// <returns>The expected type for the specified payload element.</returns> private static IEdmTypeReference GetExpectedType(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model) { if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.EdmExpectedType != null) { return expectedTypeAnnotation.EdmExpectedType; } if (expectedTypeAnnotation.ExpectedType != null) { DataType expectedDataType = expectedTypeAnnotation.ExpectedType; return EdmModelUtils.ResolveEntityModelSchemaType(model, expectedDataType); } } return null; }
/// <summary> /// Returns the function import for a parameters payload. /// </summary> /// <param name="expectedTypeAnnotation">The expected type annotation.</param> /// <param name="model">The model to get the function import from.</param> /// <returns>Returns the function import for a parameters payload.</returns> private static IEdmOperationImport GetExpectedFunctionImport(ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, IEdmModel model) { ExceptionUtilities.Assert(model != null, "model != null"); if (expectedTypeAnnotation != null) { if (expectedTypeAnnotation.ProductFunctionImport != null) { return expectedTypeAnnotation.ProductFunctionImport; } FunctionImport functionImport = expectedTypeAnnotation.FunctionImport; if (functionImport != null) { var container = model.FindEntityContainer(functionImport.Container.FullName); var functionImports = container.FindOperationImports(functionImport.Name); if (functionImports != null && functionImports.Any()) { // Note that we don't support overload for Actions. Single() will throw if the model is invalid. return functionImports.Single(); } } } return null; }
/// <summary> /// Gets the data type of a property value specified in the property instance payload element. /// </summary> /// <param name="propertyInstance">The property instance payload element to inspect.</param> /// <returns>The data type of the property value (can be used to define the metadata for this property).</returns> public static IEdmTypeReference GetPayloadEdmElementPropertyValueType(PropertyInstance propertyInstance) { ExceptionUtilities.CheckArgumentNotNull(propertyInstance, "propertyInstance"); IEdmTypeReference result = GetEdmTypeFromEntityModelTypeAnnotation(propertyInstance); if (result == null) { switch (propertyInstance.ElementType) { case ODataPayloadElementType.NullPropertyInstance: NullPropertyInstance nullPropertyInstance = (NullPropertyInstance)propertyInstance; if (nullPropertyInstance.FullTypeName != null) { result = GetPrimitiveEdmType(nullPropertyInstance.FullTypeName); if (result == null) { result = CreateComplexTypeReference(nullPropertyInstance.FullTypeName); } } break; case ODataPayloadElementType.PrimitiveProperty: result = GetEdmTypeFromEntityModelTypeAnnotation(((PrimitiveProperty)propertyInstance).Value); if (result == null) { result = GetPrimitiveEdmType(((PrimitiveProperty)propertyInstance).Value.FullTypeName); } break; case ODataPayloadElementType.ComplexProperty: result = GetEdmTypeFromEntityModelTypeAnnotation(((ComplexProperty)propertyInstance).Value); if (result == null) { result = CreateComplexTypeReference(((ComplexProperty)propertyInstance).Value.FullTypeName); } break; case ODataPayloadElementType.NamedStreamInstance: result = EdmCoreModel.Instance.GetStream(isNullable: false); break; case ODataPayloadElementType.PrimitiveMultiValueProperty: PrimitiveMultiValue primitiveMultiValue = ((PrimitiveMultiValueProperty)propertyInstance).Value; result = GetEdmTypeFromEntityModelTypeAnnotation(primitiveMultiValue); if (result == null && primitiveMultiValue.FullTypeName != null) { string itemTypeName = EntityModelUtils.GetCollectionItemTypeName(primitiveMultiValue.FullTypeName); if (itemTypeName != null) { result = EdmCoreModel.GetCollection(GetPrimitiveEdmType(itemTypeName)); } } break; case ODataPayloadElementType.ComplexMultiValueProperty: ComplexMultiValue complexMultiValue = ((ComplexMultiValueProperty)propertyInstance).Value; result = GetEdmTypeFromEntityModelTypeAnnotation(complexMultiValue); if (result == null && complexMultiValue.FullTypeName != null) { string itemTypeName = EntityModelUtils.GetCollectionItemTypeName(complexMultiValue.FullTypeName); if (itemTypeName != null) { return(EdmCoreModel.GetCollection(CreateComplexTypeReference(itemTypeName))); } } break; case ODataPayloadElementType.PrimitiveCollection: case ODataPayloadElementType.ComplexInstanceCollection: ExceptionUtilities.Assert(false, "Primitive and complex collections cannot be used in properties but only at the top-level."); return(null); default: ExceptionUtilities.Assert(false, "GetPayloadElementPropertyValueType doesn't support '{0}' yet.", propertyInstance.ElementType); return(null); } } // Use the expected type if there's any since it also specifies metadata if (result == null) { ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation = propertyInstance.GetAnnotation <ExpectedTypeODataPayloadElementAnnotation>(); if (expectedTypeAnnotation != null && expectedTypeAnnotation.ExpectedType != null) { result = expectedTypeAnnotation.EdmExpectedType; } } return(result); }
private void AddExpectedFunctionImportToCollection(ODataPayloadElementCollection collection) { var expectedTypeAnnotation = collection.GetAnnotation<ExpectedTypeODataPayloadElementAnnotation>(); if (expectedTypeAnnotation == null) { expectedTypeAnnotation = new ExpectedTypeODataPayloadElementAnnotation(); collection.Add(expectedTypeAnnotation); } if (expectedTypeAnnotation.ProductFunctionImport == null) { var typeAnnotation = collection.GetAnnotation<EntityModelTypeAnnotation>(); var collectionType = typeAnnotation.EdmModelType; if (this.testDescriptor.PayloadEdmModel != null) { EdmModel model = this.testDescriptor.PayloadEdmModel as EdmModel; EdmEntityContainer container = model.EntityContainer as EdmEntityContainer; var functionImport = container.OperationImports().FirstOrDefault(f => { return f.Operation.ReturnType != null && f.Operation.ReturnType == collectionType; }); if (functionImport == null) { functionImport = container.OperationImports().FirstOrDefault(f => { return f.Operation.ReturnType != null && f.Operation.ReturnType.IsCollection(); }); if (functionImport == null) { var collectionNameAnnotation = collection.GetAnnotation<CollectionNameAnnotation>(); container.AddFunctionAndFunctionImport(model, collectionNameAnnotation == null ? "NewFunctionImport" : collectionNameAnnotation.Name, collectionType); this.testDescriptor.ResetCachedModel(); } } expectedTypeAnnotation.ProductFunctionImport = functionImport as EdmOperationImport; } } }