/// <inheritdoc />
        public override void Visit(IAcceptor acceptor, KeyValuePair <string, Type> type, NamingStrategy namingStrategy, params Attribute[] attributes)
        {
            var instance = acceptor as OpenApiSchemaAcceptor;

            if (instance.IsNullOrDefault())
            {
                return;
            }

            // Gets the schema for the underlying type.
            type.Value.IsOpenApiNullable(out var underlyingType);

            var types = new Dictionary <string, Type>()
            {
                { type.Key, underlyingType }
            };
            var schemas = new Dictionary <string, OpenApiSchema>();

            var subAcceptor = new OpenApiSchemaAcceptor()
            {
                Types   = types,
                Schemas = schemas,
            };

            var collection = VisitorCollection.CreateInstance();

            subAcceptor.Accept(collection, namingStrategy);

            // Adds the schema for the underlying type.
            var name   = subAcceptor.Schemas.First().Key;
            var schema = subAcceptor.Schemas.First().Value;

            schema.Nullable = true;

            // Adds the visibility property.
            if (attributes.Any())
            {
                var visibilityAttribute = attributes.OfType <OpenApiSchemaVisibilityAttribute>().SingleOrDefault();
                if (!visibilityAttribute.IsNullOrDefault())
                {
                    var extension = new OpenApiString(visibilityAttribute.Visibility.ToDisplayName());

                    schema.Extensions.Add("x-ms-visibility", extension);
                }
            }

            instance.Schemas.Add(name, schema);
        }
        /// <inheritdoc />
        public override void Visit(IAcceptor acceptor, KeyValuePair <string, Type> type, NamingStrategy namingStrategy, params Attribute[] attributes)
        {
            var name = this.Visit(acceptor, name: type.Key, title: null, dataType: "array", dataFormat: null, attributes: attributes);

            if (name.IsNullOrWhiteSpace())
            {
                return;
            }

            var instance = acceptor as OpenApiSchemaAcceptor;

            if (instance.IsNullOrDefault())
            {
                return;
            }

            // Gets the schema for the underlying type.
            var underlyingType = type.Value.GetUnderlyingType();
            var types          = new Dictionary <string, Type>()
            {
                { underlyingType.GetOpenApiTypeName(namingStrategy), underlyingType }
            };
            var schemas = new Dictionary <string, OpenApiSchema>();

            var subAcceptor = new OpenApiSchemaAcceptor()
            {
                Types       = types,
                RootSchemas = instance.RootSchemas,
                Schemas     = schemas,
            };

            subAcceptor.Accept(this.VisitorCollection, namingStrategy);

            var items = subAcceptor.Schemas.First().Value;

            // Adds the reference to the schema for the underlying type.
            if (this.IsReferential(underlyingType))
            {
                var reference = new OpenApiReference()
                {
                    Type = ReferenceType.Schema,
                    Id   = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
                };

                items.Reference = reference;
            }

            instance.Schemas[name].Items = items;

            // Adds schemas to the root.
            var schemasToBeAdded = subAcceptor.Schemas
                                   .Where(p => !instance.Schemas.Keys.Contains(p.Key))
                                   .Where(p => p.Value.Type == "object" &&
                                          p.Value.Format.IsNullOrWhiteSpace() &&
                                          p.Value.Items.IsNullOrDefault() &&
                                          p.Value.AdditionalProperties.IsNullOrDefault())
                                   .ToDictionary(p => p.Key, p => p.Value);

            if (!schemasToBeAdded.Any())
            {
                return;
            }

            foreach (var schema in schemasToBeAdded)
            {
                if (instance.RootSchemas.ContainsKey(schema.Key))
                {
                    continue;
                }

                instance.RootSchemas.Add(schema.Key, schema.Value);
            }
        }
Beispiel #3
0
        private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary <string, PropertyInfo> properties, NamingStrategy namingStrategy)
        {
            var schemas = new Dictionary <string, OpenApiSchema>();

            var subAcceptor = new OpenApiSchemaAcceptor()
            {
                Properties  = properties,
                RootSchemas = instance.RootSchemas,
                Schemas     = schemas,
            };

            var collection = VisitorCollection.CreateInstance();

            subAcceptor.Accept(collection, namingStrategy);

            // Add required properties to schema.
            var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute <JsonPropertyAttribute>(inherit: false).IsNullOrDefault())
                                         .Select(p => new KeyValuePair <string, JsonPropertyAttribute>(p.Key, p.Value.GetCustomAttribute <JsonPropertyAttribute>(inherit: false)))
                                         .Where(p => p.Value.Required == Required.Always || p.Value.Required == Required.DisallowNull);

            foreach (var attribute in jsonPropertyAttributes)
            {
                instance.Schemas[schemaName].Required.Add(attribute.Key);
            }

            var jsonRequiredAttributes = properties.Where(p => !p.Value.GetCustomAttribute <JsonRequiredAttribute>(inherit: false).IsNullOrDefault())
                                         .Select(p => new KeyValuePair <string, JsonRequiredAttribute>(p.Key, p.Value.GetCustomAttribute <JsonRequiredAttribute>(inherit: false)));

            foreach (var attribute in jsonRequiredAttributes)
            {
                var attributeName = namingStrategy.GetPropertyName(attribute.Key, hasSpecifiedName: false);
                if (instance.Schemas[schemaName].Required.Contains(attributeName))
                {
                    continue;
                }

                instance.Schemas[schemaName].Required.Add(attributeName);
            }

            instance.Schemas[schemaName].Properties = subAcceptor.Schemas;

            // Adds schemas to the root.
            var schemasToBeAdded = subAcceptor.Schemas
                                   .Where(p => !instance.Schemas.Keys.Contains(p.Key))
                                   .Where(p => p.Value.Type == "object" &&
                                          p.Value.Format.IsNullOrWhiteSpace() &&
                                          p.Value.Items.IsNullOrDefault() &&
                                          p.Value.AdditionalProperties.IsNullOrDefault())
                                   .ToDictionary(p => p.Value.Title, p => p.Value);

            foreach (var schema in schemasToBeAdded.Where(p => p.Key != "jObject" && p.Key != "jToken"))
            {
                if (instance.RootSchemas.ContainsKey(schema.Key))
                {
                    continue;
                }

                instance.RootSchemas.Add(schema.Key, schema.Value);
            }

            // Removes title of each property.
            var subSchemas = instance.Schemas[schemaName].Properties;

            subSchemas = subSchemas.Select(p =>
            {
                p.Value.Title = null;
                return(new KeyValuePair <string, OpenApiSchema>(p.Key, p.Value));
            })
                         .ToDictionary(p => p.Key, p => p.Value);

            instance.Schemas[schemaName].Properties = subSchemas;
        }