/// <summary>
        /// Create the dictionary of <see cref="OpenApiSchema"/> object.
        /// The name of each pair is the namespace-qualified name of the type. It uses the namespace instead of the alias.
        /// The value of each pair is a <see cref="OpenApiSchema"/>.
        /// </summary>
        /// <param name="context">The OData to Open API context.</param>
        /// <returns>The string/schema dictionary.</returns>
        public static IDictionary <string, OpenApiSchema> CreateSchemas(this ODataContext context)
        {
            Utils.CheckArgumentNull(context, nameof(context));

            IDictionary <string, OpenApiSchema> schemas = new Dictionary <string, OpenApiSchema>();

            // Each entity type, complex type, enumeration type, and type definition directly
            // or indirectly used in the paths field is represented as a name / value pair of the schemas map.
            foreach (var element in context.Model.SchemaElements.Where(c => !c.Namespace.StartsWith("Org.OData.")))
            {
                switch (element.SchemaElementKind)
                {
                case EdmSchemaElementKind.TypeDefinition:     // Type definition
                {
                    IEdmType reference = (IEdmType)element;
                    schemas.Add(reference.FullTypeName(), context.CreateSchemaTypeSchema(reference));
                }
                break;
                }
            }

            // append the Edm.Spatial
            foreach (var schema in context.CreateSpatialSchemas())
            {
                schemas[schema.Key] = schema.Value;
            }

            // append the OData errors
            foreach (var schema in context.CreateODataErrorSchemas())
            {
                schemas[schema.Key] = schema.Value;
            }

            return(schemas);
        }
        public void CreateSpatialSchemasThrowArgumentNullContext()
        {
            // Arrange
            ODataContext context = null;

            // Act & Assert
            Assert.Throws <ArgumentNullException>("context", () => context.CreateSpatialSchemas());
        }
        public void CreateSpatialSchemasReturnEmptyForCoreModel()
        {
            // Arrange
            ODataContext context = new ODataContext(EdmCoreModel.Instance);

            // Act
            var schemas = context.CreateSpatialSchemas();

            // Assert
            Assert.NotNull(schemas);
            Assert.Empty(schemas);
        }
        public void CreateSpatialSchemasReturnFullSpatialSchemasForModelWithEdmSpatialTypes()
        {
            // Arrange
            EdmModel       model   = new EdmModel();
            EdmComplexType complex = new EdmComplexType("NS", "Complex");

            complex.AddStructuralProperty("Location", EdmPrimitiveTypeKind.Geography);
            model.AddElement(complex);

            ODataContext context = new ODataContext(model);

            // Act
            var schemas = context.CreateSpatialSchemas();

            // Assert
            Assert.NotNull(schemas);
            Assert.NotEmpty(schemas);
            Assert.Equal(new string[]
            {
                "Edm.Geography",
                "Edm.GeographyPoint",
                "Edm.GeographyLineString",
                "Edm.GeographyPolygon",
                "Edm.GeographyMultiPoint",
                "Edm.GeographyMultiLineString",
                "Edm.GeographyMultiPolygon",
                "Edm.GeographyCollection",

                "Edm.Geometry",
                "Edm.GeometryPoint",
                "Edm.GeometryLineString",
                "Edm.GeometryPolygon",
                "Edm.GeometryMultiPoint",
                "Edm.GeometryMultiLineString",
                "Edm.GeometryMultiPolygon",
                "Edm.GeometryCollection",

                "GeoJSON.position"
            },
                         schemas.Select(s => s.Key));
        }
Exemple #5
0
        /// <summary>
        /// Create the dictionary of <see cref="OpenApiSchema"/> object.
        /// The name of each pair is the namespace-qualified name of the type. It uses the namespace instead of the alias.
        /// The value of each pair is a <see cref="OpenApiSchema"/>.
        /// </summary>
        /// <param name="context">The OData to Open API context.</param>
        /// <returns>The string/schema dictionary.</returns>
        public static IDictionary <string, OpenApiSchema> CreateSchemas(this ODataContext context)
        {
            Utils.CheckArgumentNull(context, nameof(context));

            IDictionary <string, OpenApiSchema> schemas = new Dictionary <string, OpenApiSchema>();

            // Each entity type, complex type, enumeration type, and type definition directly
            // or indirectly used in the paths field is represented as a name / value pair of the schemas map.
            // Ideally this would be driven off the types used in the paths, but in practice, it is simply
            // all of the types present in the model.
            IEnumerable <IEdmSchemaElement> elements = context.Model.GetAllElements();

            foreach (var element in elements)
            {
                switch (element.SchemaElementKind)
                {
                case EdmSchemaElementKind.TypeDefinition:     // Type definition
                {
                    IEdmType reference = (IEdmType)element;
                    schemas.Add(reference.FullTypeName(), context.CreateSchemaTypeSchema(reference));
                }
                break;
                }
            }

            // append the Edm.Spatial
            foreach (var schema in context.CreateSpatialSchemas())
            {
                schemas[schema.Key] = schema.Value;
            }

            // append the OData errors
            foreach (var schema in context.CreateODataErrorSchemas())
            {
                schemas[schema.Key] = schema.Value;
            }

            return(schemas);
        }
        /// <summary>
        /// Create the dictionary of <see cref="OpenApiSchema"/> object.
        /// The name of each pair is the namespace-qualified name of the type. It uses the namespace instead of the alias.
        /// The value of each pair is a <see cref="OpenApiSchema"/>.
        /// </summary>
        /// <param name="context">The OData to Open API context.</param>
        /// <returns>The string/schema dictionary.</returns>
        public static IDictionary <string, OpenApiSchema> CreateSchemas(this ODataContext context)
        {
            Utils.CheckArgumentNull(context, nameof(context));

            IDictionary <string, OpenApiSchema> schemas = new Dictionary <string, OpenApiSchema>();

            // Each entity type, complex type, enumeration type, and type definition directly
            // or indirectly used in the paths field is represented as a name / value pair of the schemas map.
            // Ideally this would be driven off the types used in the paths, but in practice, it is simply
            // all of the types present in the model.
            IEnumerable <IEdmSchemaElement> elements = context.Model.GetAllElements();

            foreach (var element in elements)
            {
                switch (element.SchemaElementKind)
                {
                case EdmSchemaElementKind.TypeDefinition:     // Type definition
                {
                    IEdmType reference    = (IEdmType)element;
                    var      fullTypeName = reference.FullTypeName();
                    if (reference is IEdmComplexType &&
                        fullTypeName.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)
                        .Last()
                        .Equals(context.Settings.InnerErrorComplexTypeName, StringComparison.Ordinal))
                    {
                        continue;
                    }

                    schemas.Add(fullTypeName, context.CreateSchemaTypeSchema(reference));
                }
                break;
                }
            }

            // append the Edm.Spatial
            foreach (var schema in context.CreateSpatialSchemas())
            {
                schemas[schema.Key] = schema.Value;
            }

            // append the OData errors
            foreach (var schema in context.CreateODataErrorSchemas())
            {
                schemas[schema.Key] = schema.Value;
            }

            if (context.Settings.EnableDollarCountPath)
            {
                schemas[Constants.DollarCountSchemaName] = new OpenApiSchema {
                    Type   = "integer",
                    Format = "int32"
                }
            }
            ;

            schemas = schemas.Concat(context.GetAllCollectionEntityTypes()
                                     .Select(x => new KeyValuePair <string, OpenApiSchema>(
                                                 $"{(x is IEdmEntityType eType ? eType.FullName() : x.FullTypeName())}{Constants.CollectionSchemaSuffix}",
                                                 CreateCollectionSchema(context, x)))
                                     .Where(x => !schemas.ContainsKey(x.Key)))
                      .Concat(context.GetAllCollectionComplexTypes()
                              .Select(x => new KeyValuePair <string, OpenApiSchema>(
                                          $"{x.FullTypeName()}{Constants.CollectionSchemaSuffix}",
                                          CreateCollectionSchema(context, x)))
                              .Where(x => !schemas.ContainsKey(x.Key)))
                      .ToDictionary(x => x.Key, x => x.Value);

            if (context.HasAnyNonContainedCollections())
            {
                schemas[$"String{Constants.CollectionSchemaSuffix}"] = CreateCollectionSchema(context, new OpenApiSchema {
                    Type = "string"
                }, "string");
            }

            schemas[Constants.ReferenceUpdateSchemaName] = new()
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>
                {
                    { Constants.OdataId, new OpenApiSchema {
                          Type = "string", Nullable = false
                      } },
                    { Constants.OdataType, new OpenApiSchema {
                          Type = "string", Nullable = true
                      } },
                }
            };

            schemas[Constants.ReferenceCreateSchemaName] = new()
            {
                Type       = "object",
                Properties = new Dictionary <string, OpenApiSchema>
                {
                    { Constants.OdataId, new OpenApiSchema {
                          Type = "string", Nullable = false
                      } }
                },
                AdditionalProperties = new OpenApiSchema {
                    Type = "object"
                }
            };

            return(schemas);
        }

        internal static bool HasAnyNonContainedCollections(this ODataContext context)