/// <summary>
        /// Creates a new instance of the <see cref="VisitorCollection"/> class by scanning the current assembly for <see cref="IVisitor"/>.
        /// </summary>
        /// <remarks>
        /// There is an expectation that the <see cref="IVisitor"/> implementation has a constructor that takes a <see cref="VisitorCollection"/> as the only parameter.
        /// </remarks>
        /// <returns>Returns the <see cref="VisitorCollection"/> instance.</returns>
        public static VisitorCollection CreateInstance()
        {
            var collection = new VisitorCollection();

            collection.Visitors = typeof(IVisitor).Assembly
                                  .GetTypes()
                                  .Where(p => p.Name.EndsWith("Visitor") && p.IsClass && !p.IsAbstract)
                                  .Select(p => (IVisitor)Activator.CreateInstance(p, collection)).ToList();          // NOTE: there is no direct enforcement on the constructor arguments of the visitors
            return(collection);
        }
        /// <inheritdoc />
        public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy)
        {
            type.IsOpenApiNullable(out var underlyingType);
            var collection = VisitorCollection.CreateInstance();
            var schema     = collection.ParameterVisit(underlyingType, namingStrategy);

            schema.Nullable = true;

            return(schema);
        }
Exemple #3
0
        /// <summary>
        /// Creates a new instance of the <see cref="VisitorCollection"/> class.
        /// </summary>
        /// <returns>Returns the <see cref="VisitorCollection"/> instance.</returns>
        public static VisitorCollection CreateInstance()
        {
            var visitors = typeof(IVisitor).Assembly
                           .GetTypes()
                           .Where(p => p.Name.EndsWith("Visitor") && p.IsClass && !p.IsAbstract)
                           .Select(p => (IVisitor)Activator.CreateInstance(p))
                           .ToList();
            var collection = new VisitorCollection(visitors);

            return(collection);
        }
Exemple #4
0
        /// <inheritdoc />
        public override OpenApiSchema ParameterVisit(Type type, NamingStrategy namingStrategy)
        {
            var schema = this.ParameterVisit(dataType: "array", dataFormat: null);

            var underlyingType = type.GetElementType() ?? type.GetGenericArguments()[0];
            var collection     = VisitorCollection.CreateInstance();
            var items          = collection.ParameterVisit(underlyingType, namingStrategy);

            schema.Items = items;

            return(schema);
        }
        /// <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);
        }
Exemple #6
0
        /// <inheritdoc />
        public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy)
        {
            var schema = this.PayloadVisit(dataType: "array", dataFormat: null);

            // Gets the schema for the underlying type.
            var underlyingType = type.GetElementType() ?? type.GetGenericArguments()[0];
            var collection     = VisitorCollection.CreateInstance();
            var items          = collection.PayloadVisit(underlyingType, namingStrategy);

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

            items.Reference = reference;

            schema.Items = items;

            return(schema);
        }
Exemple #7
0
        /// <inheritdoc />
        public void Accept(VisitorCollection collection, NamingStrategy namingStrategy)
        {
            // Checks the properties only.
            if (this.Properties.Any())
            {
                foreach (var property in this.Properties)
                {
                    var visibilityAttribute = property.Value.GetCustomAttribute <OpenApiSchemaVisibilityAttribute>(inherit: false);

                    foreach (var visitor in collection.Visitors)
                    {
                        if (!visitor.IsVisitable(property.Value.PropertyType))
                        {
                            continue;
                        }

                        var type = new KeyValuePair <string, Type>(property.Key, property.Value.PropertyType);
                        visitor.Visit(this, type, namingStrategy, visibilityAttribute);
                    }
                }

                return;
            }

            // Checks the types only.
            foreach (var type in this.Types)
            {
                foreach (var visitor in collection.Visitors)
                {
                    if (!visitor.IsVisitable(type.Value))
                    {
                        continue;
                    }

                    visitor.Visit(this, type, namingStrategy);
                }
            }
        }
 /// <inheritdoc />
 public Int16TypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
Exemple #9
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;
        }
Exemple #10
0
 /// <inheritdoc />
 public SingleTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public Int64EnumTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public StringEnumTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public GuidObjectTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
Exemple #14
0
 /// <inheritdoc />
 public UriTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public DoubleTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public BooleanTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public DateTimeTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public DateTimeOffsetObjectTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public RecursiveObjectTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
Exemple #20
0
 /// <inheritdoc />
 public DictionaryObjectTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TypeVisitor"/> class.
 /// </summary>
 /// <param name="visitorCollection"><see cref="VisitorCollection"/> instance.</param>
 protected TypeVisitor(VisitorCollection visitorCollection)
 {
     this.VisitorCollection = visitorCollection.ThrowIfNullOrDefault();
 }
 /// <inheritdoc />
 public ListObjectTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
Exemple #23
0
        /// <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.GetElementType() ?? type.Value.GetGenericArguments()[0];
            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,
            };

            var collection = VisitorCollection.CreateInstance();

            subAcceptor.Accept(collection, 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);
            }
        }
 /// <inheritdoc />
 public NullableObjectTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }
 /// <inheritdoc />
 public DecimalTypeVisitor(VisitorCollection visitorCollection)
     : base(visitorCollection)
 {
 }