예제 #1
0
        /// <summary>
        /// Generates schema for the provided list of types and store them in the provided dictionary.
        /// </summary>
        /// <param name="allListedTypes">The listed types to fetch schema for.</param>
        /// <param name="crefSchemaMap">The cref to <see cref="InternalSchemaGenerationInfo"/> map.</param>
        /// <param name="typeFetcher">The type fetcher used to fetch type information using reflection.</param>
        /// <param name="schemaReferenceRegistry"><see cref="SchemaReferenceRegistry"/>.</param>
        private void BuildCrefSchemaMap(
            IList <string> allListedTypes,
            Dictionary <string, InternalSchemaGenerationInfo> crefSchemaMap,
            TypeFetcher typeFetcher,
            SchemaReferenceRegistry schemaReferenceRegistry)
        {
            var key = allListedTypes.ToCrefKey();

            var schemaInfo = new InternalSchemaGenerationInfo();

            try
            {
                var type   = typeFetcher.LoadTypeFromCrefValues(allListedTypes);
                var schema = schemaReferenceRegistry.FindOrAddReference(type);
                schemaInfo.Schema = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            }
            catch (Exception e)
            {
                var error = new GenerationError
                {
                    ExceptionType = e.GetType().Name,
                    Message       = e.Message
                };

                schemaInfo.Error = error;
            }

            if (!crefSchemaMap.ContainsKey(key))
            {
                crefSchemaMap.Add(key, schemaInfo);
            }
        }
예제 #2
0
        public void TypeFetcherShouldReturnCorrectTypeData(
            string testCaseName,
            IList <string> inputBinaryFiles,
            IList <string> crefValues,
            string expectedTypeAsString)
        {
            _output.WriteLine(testCaseName);

            var typeFetcher = new TypeFetcher(inputBinaryFiles);
            var type        = typeFetcher.LoadTypeFromCrefValues(crefValues);

            type.ToString().Should().Be(expectedTypeAsString);
        }
예제 #3
0
        /// <summary>
        /// Provided a field cref value, fetches the field value using reflection.
        /// </summary>
        /// <param name="crefValue">The cref value for the field.</param>
        /// <param name="crefFieldMap">The cref value to <see cref="FieldValueInfo"/> map.</param>
        /// <param name="typeFetcher">The type fetcher used to fetch field value from the loaded assemblies.</param>
        private void BuildCrefFieldValueMap(
            string crefValue,
            Dictionary <string, FieldValueInfo> crefFieldMap,
            TypeFetcher typeFetcher)
        {
            if (string.IsNullOrWhiteSpace(crefValue) || crefFieldMap.ContainsKey(crefValue))
            {
                return;
            }

            var fieldValueInfo = new FieldValueInfo();

            try
            {
                var typeName = crefValue.ExtractTypeNameFromFieldCref();
                var type     = typeFetcher.LoadTypeFromCrefValues(new List <string> {
                    typeName
                });
                var fieldName = crefValue.ExtractFieldNameFromCref();

                var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
                var field  = fields.FirstOrDefault(f => f.Name == fieldName);

                if (field == null)
                {
                    var errorMessage = string.Format(
                        SpecificationGenerationMessages.FieldNotFound,
                        fieldName,
                        typeName);

                    throw new TypeLoadException(errorMessage);
                }

                fieldValueInfo.Value = field.GetValue(null).ToString();
            }
            catch (Exception e)
            {
                var error = new GenerationError
                {
                    ExceptionType = e.GetType().Name,
                    Message       = e.Message
                };

                fieldValueInfo.Error = error;
            }

            crefFieldMap.Add(crefValue, fieldValueInfo);
        }
예제 #4
0
        /// <summary>
        /// Processes the "header" tag child elements of the provide XElement
        /// and generates a map of string to OpenApiHeader.
        /// </summary>
        /// <param name="xElement">The XElement to process.</param>
        /// <param name="typeFetcher">The type fetcher.</param>
        /// <param name="schemaReferenceRegistry">The schema reference registry.</param>
        /// <returns>The map of string to OpenApiHeader.</returns>
        internal static Dictionary <string, OpenApiHeader> ToOpenApiHeaders(
            this XElement xElement,
            TypeFetcher typeFetcher,
            SchemaReferenceRegistry schemaReferenceRegistry)
        {
            var headerElements = xElement.Elements()
                                 .Where(
                p => p.Name == KnownXmlStrings.Header)
                                 .ToList();

            var openApiHeaders = new Dictionary <string, OpenApiHeader>();

            foreach (var headerElement in headerElements)
            {
                var name = headerElement.Attribute(KnownXmlStrings.Name)?.Value.Trim();
                if (string.IsNullOrWhiteSpace(name))
                {
                    throw new InvalidHeaderException(
                              string.Format(SpecificationGenerationMessages.UndocumentedName, "header"));
                }

                var description = headerElement
                                  .Elements()
                                  .FirstOrDefault(p => p.Name == KnownXmlStrings.Description)?.Value.Trim().RemoveBlankLines();

                var listedTypes = headerElement.GetListedTypes();
                var type        = typeFetcher.LoadTypeFromCrefValues(listedTypes);

                var schema = schemaReferenceRegistry.FindOrAddReference(type);
                openApiHeaders.Add(
                    name,
                    new OpenApiHeader
                {
                    Description = description,
                    Schema      = schema
                });
            }

            return(openApiHeaders);
        }
예제 #5
0
        private static OpenApiExample ToOpenApiExample(this XElement element, TypeFetcher typeFetcher)
        {
            var exampleChildElements = element.Elements();

            if (!exampleChildElements.Any())
            {
                return(null);
            }

            var summaryElement = exampleChildElements.FirstOrDefault(p => p.Name == KnownXmlStrings.Summary);

            var openApiExample = new OpenApiExample();

            if (summaryElement != null)
            {
                openApiExample.Summary = summaryElement.Value;
            }

            var valueElement = exampleChildElements.FirstOrDefault(p => p.Name == KnownXmlStrings.Value);
            var urlElement   = exampleChildElements.FirstOrDefault(p => p.Name == KnownXmlStrings.Url);

            if (valueElement != null && urlElement != null)
            {
                throw new InvalidExampleException(SpecificationGenerationMessages.ProvideEitherValueOrUrlTag);
            }

            IOpenApiAny exampleValue = null;

            if (valueElement != null)
            {
                var seeNodes  = element.Descendants(KnownXmlStrings.See);
                var crefValue = seeNodes
                                .Select(node => node.Attribute(KnownXmlStrings.Cref)?.Value)
                                .FirstOrDefault(crefVal => crefVal != null);

                if (string.IsNullOrWhiteSpace(valueElement.Value) && string.IsNullOrWhiteSpace(crefValue))
                {
                    throw new InvalidExampleException(SpecificationGenerationMessages.ProvideValueForExample);
                }

                if (!string.IsNullOrWhiteSpace(crefValue))
                {
                    var typeName = crefValue.ExtractTypeNameFromFieldCref();
                    var type     = typeFetcher.LoadTypeFromCrefValues(new List <string> {
                        typeName
                    });
                    var fieldName = crefValue.ExtractFieldNameFromCref();

                    var fields = type.GetFields(BindingFlags.Public
                                                | BindingFlags.Static);
                    var field = fields.FirstOrDefault(f => f.Name == fieldName);

                    if (field == null)
                    {
                        var errorMessage = string.Format(
                            SpecificationGenerationMessages.FieldNotFound,
                            fieldName,
                            typeName);

                        throw new TypeLoadException(errorMessage);
                    }

                    exampleValue = new OpenApiStringReader().ReadFragment <IOpenApiAny>(
                        field.GetValue(null).ToString(),
                        OpenApiSpecVersion.OpenApi3_0,
                        out OpenApiDiagnostic _);
                }

                if (!string.IsNullOrWhiteSpace(valueElement.Value))
                {
                    exampleValue = new OpenApiStringReader()
                                   .ReadFragment <IOpenApiAny>(
                        valueElement.Value,
                        OpenApiSpecVersion.OpenApi3_0,
                        out OpenApiDiagnostic _);
                }

                openApiExample.Value = exampleValue;
            }

            if (urlElement != null)
            {
                openApiExample.ExternalValue = urlElement.Value;
            }

            return(openApiExample);
        }