Esempio n. 1
0
 private static JToken GetComponentExampleCore(IOpenApiAny example)
 {
     if (example.AnyType == AnyType.Object)
     {
         var     exampleObject = (OpenApiObject)example;
         JObject jObject       = new JObject();
         foreach (var eo in exampleObject)
         {
             var value = GetComponentExampleCore(eo.Value);
             jObject.Add(new JProperty(eo.Key, value));
         }
         return(jObject);
     }
     else if (example.AnyType == AnyType.Array)
     {
         var    exampleArray = (OpenApiArray)example;
         JArray jArray       = new JArray();
         foreach (var ea in exampleArray)
         {
             jArray.Add(GetComponentExampleCore(ea));
         }
         return(jArray);
     }
     else
     {
         return(TransformHelper.GetValueFromPrimitiveType(example));
     }
 }
Esempio n. 2
0
        protected virtual EnumMemberDeclarationSyntax?CreateEnumMember(
            ILocatedOpenApiElement <OpenApiSchema> schemaElement,
            IOpenApiAny value,
            INameFormatter nameFormatter,
            NamingContext namingContext)
        {
            if (value.AnyType != AnyType.Primitive)
            {
                return(null);
            }

            var primitive = (IOpenApiPrimitive)value;

            if (primitive.PrimitiveType != PrimitiveType.String)
            {
                return(null);
            }

            var stringPrimitive = (OpenApiPrimitive <string>)primitive;

            string memberName = namingContext.RegisterName(nameFormatter.Format(stringPrimitive.Value));

            return(SyntaxFactory.EnumMemberDeclaration(memberName)
                   .AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(
                                          CreateEnumMemberAttribute(stringPrimitive.Value))));
        }
Esempio n. 3
0
 private static void CompareOpenApiExampleValue(List <Change> changes, IOpenApiAny before, IOpenApiAny after, ChangeType changeType)
 {
     if ((before == null) && (after == null))
     {
         // No change.  Ignore.
     }
     else if (before == null)
     {
         changes.Add(new Change()
         {
             ActionType    = ActionType.Added,
             ChangeType    = changeType,
             Compatibility = Compatibility.Backwards,
             Before        = before,
             After         = after,
         });
     }
     else if (after == null)
     {
         changes.Add(new Change()
         {
             ActionType    = ActionType.Removed,
             ChangeType    = changeType,
             Compatibility = Compatibility.Backwards,
             Before        = before,
             After         = after,
         });
     }
     else
     {
         // TODO: Compare values.
     }
 }
Esempio n. 4
0
    public static OpenApiPagingExtension Parse(IOpenApiAny source)
    {
        if (source is not OpenApiObject rawObject)
        {
            throw new ArgumentOutOfRangeException(nameof(source));
        }
        var extension = new OpenApiPagingExtension();

        if (rawObject.TryGetValue(nameof(NextLinkName).ToFirstCharacterLowerCase(), out var nextLinkName) && nextLinkName is OpenApiString nextLinkNameStr)
        {
            extension.NextLinkName = nextLinkNameStr.Value;
        }

        if (rawObject.TryGetValue(nameof(OperationName).ToFirstCharacterLowerCase(), out var opName) && opName is OpenApiString opNameStr)
        {
            extension.OperationName = opNameStr.Value;
        }

        if (rawObject.TryGetValue(nameof(ItemName).ToFirstCharacterLowerCase(), out var itemName) && itemName is OpenApiString itemNameStr)
        {
            extension.ItemName = itemNameStr.Value;
        }

        return(extension);
    }
Esempio n. 5
0
        public static string GetJsonValue(IOpenApiAny value)
        {
            StringBuilder builder = new StringBuilder();

            value.Write(new OpenApiJsonWriter(new StringWriter(builder)), OpenApiDocumentParser.Version);
            return(builder.ToString());
        }
Esempio n. 6
0
 public void AddMap<T1, T2>(IOpenApiAny example)
 {
     Maps.Add(typeof(T1), new TypedExample{
         Type = typeof(T2),
         OpenApiExample = example
     });
 }
Esempio n. 7
0
        private void FillSchema(OpenApiSchema schema, SchemaFilterContext context, IPropertySet propertySet)
        {
            schema.Type       = "object";
            schema.Items      = null;
            schema.Properties = new Dictionary <string, OpenApiSchema>();

            foreach (IProperty property in propertySet.GetProperties())
            {
                OpenApiSchema?propertySchema = context.SchemaGenerator.GenerateSchema(property.Type, context.SchemaRepository);
                propertySchema.Description = property.Description ?? propertySchema.Description;

                if (property.GetOrEvaluateNullability() is { } allowNull)
                {
                    propertySchema.Nullable = allowNull.IsNullAllowed;
                }

                if (property.GetAllowedValuesUntyped() is { } allowedValues)
                {
                    propertySchema.Enum = new List <IOpenApiAny>();
                    foreach (object allowedValue in allowedValues.ValuesUntyped)
                    {
                        string      jsonValue  = JsonConverterFunc(allowedValue);
                        IOpenApiAny openApiAny = OpenApiAnyFactory.CreateFromJson(jsonValue);
                        propertySchema.Enum.Add(openApiAny);
                    }
                }

                string?propertyName = _options.ResolvePropertyName !(property.Name);
                schema.Properties.Add(propertyName, propertySchema);
            }
        }
        private static IOpenApiAny CreateStructuredTypePropertiesExample(ODataContext context, IEdmStructuredType structuredType)
        {
            OpenApiObject example = new OpenApiObject();

            IEdmEntityType entityType = structuredType as IEdmEntityType;

            // properties
            foreach (var property in structuredType.Properties())
            {
                // IOpenApiAny item;
                IEdmTypeReference propertyType = property.Type;

                IOpenApiAny item = GetTypeNameForExample(context, propertyType);

                EdmTypeKind typeKind = propertyType.TypeKind();
                if (typeKind == EdmTypeKind.Primitive && item is OpenApiString)
                {
                    OpenApiString stringAny = item as OpenApiString;
                    string        value     = stringAny.Value;
                    if (entityType != null && entityType.Key().Any(k => k.Name == property.Name))
                    {
                        value += " (identifier)";
                    }
                    if (propertyType.IsDateTimeOffset() || propertyType.IsDate() || propertyType.IsTimeOfDay())
                    {
                        value += " (timestamp)";
                    }
                    item = new OpenApiString(value);
                }

                example.Add(property.Name, item);
            }

            return(example);
        }
        private OpenApiSchema ConvertToOpenApiSchema(JSchema jsonSchema)
        {
            IOpenApiAny defaultValue2 = null;

            //            if (jsonSchema.Default != null && ConvertObjectToOpenApi.ContainsKey(DefaultValue.GetType()))
            //              defaultValue2 = ConvertObjectToOpenApi[DefaultValue.GetType()](DefaultValue);
            if (this.HasModel)
            {
                var objectSchema = new OpenApiSchema
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.Schema,
                        Id   = this.TypeName
                    }
                };

                if (this.IsArray)
                {
                    return(new OpenApiSchema
                    {
                        Type = JSchemaType.Array.ToString().ToLower(),
                        Items = objectSchema
                    });
                }
                else
                {
                    return(objectSchema);
                }
            }
            else
            {
                return(new OpenApiSchema
                {
                    Description = jsonSchema.Description,
                    Type = jsonSchema.Type.ToString().ToLower(),
                    Items = jsonSchema.Items.Select(x => new OpenApiSchema {
                        Type = x.Type.ToString().ToLower()
                    }).FirstOrDefault(),
                    Default = defaultValue2,
                    //MultipleOf = (decimal?)jsonSchema.MultipleOf; // -> N/A in PowerShell Attribute
                    Minimum = (decimal?)jsonSchema.Minimum, // -> ValidateRange
                    Maximum = (decimal?)jsonSchema.Maximum, // -> ValidateRange
                    //ExclusiveMinimum = (bool)jsonSchema.ExclusiveMinimum; // -> N/A in PowerShell Attribute
                    //ExclusiveMaximum = (bool)jsonSchema.ExclusiveMaximum; // -> N/A in PowerShell Attribute
                    MaxLength = (int?)jsonSchema.MaximumLength, // -> ValidateLength
                    MinLength = (int?)jsonSchema.MinimumLength, // -> ValidateLength
                    Pattern = jsonSchema.Pattern,               // -> ValidatePattern
                    MinItems = (int?)jsonSchema.MinimumItems,   // -> ValidateCount
                    MaxItems = (int?)jsonSchema.MaximumItems,   // -> ValidateCount
                    //UniqueItems = (bool)jsonSchema.UniqueItems; // -> N/A in PowerShell Attribute
                    //MaxProperties = (int?)jsonSchema.MaximumProperties; // -> N/A in PowerShell Attribute
                    //MinProperties = (int?)jsonSchema.MaximumProperties; // -> N/A in PowerShell Attribute
                    Enum = _jsonSchema.Enum.Values <string>().ToList().Select(x => (IOpenApiAny) new OpenApiString(x)).ToList(), // -> ValidateSet
                    Title = _jsonSchema.Title,
                    Nullable = this.AllowNull,
                });
            }
        }
Esempio n. 10
0
        public static string GetPrimitiveValue(IOpenApiAny value)
        {
            IOpenApiPrimitive primitive = (IOpenApiPrimitive)value;

            switch (primitive.PrimitiveType)
            {
            case PrimitiveType.String:
                OpenApiString stringValue = (OpenApiString)primitive;
                return(stringValue.Value);

            case PrimitiveType.Boolean:
                OpenApiBoolean booleanValue = (OpenApiBoolean)primitive;
                return(booleanValue.Value.ToString());

            case PrimitiveType.Integer:
                OpenApiInteger integerValue = (OpenApiInteger)primitive;
                return(integerValue.Value.ToString());

            case PrimitiveType.Long:
                OpenApiLong longValue = (OpenApiLong)primitive;
                return(longValue.Value.ToString());

            case PrimitiveType.Float:
                OpenApiFloat floatValue = (OpenApiFloat)primitive;
                return(floatValue.Value.ToString(CultureInfo.InvariantCulture));

            case PrimitiveType.Double:
                OpenApiDouble doubleValue = (OpenApiDouble)primitive;
                return(doubleValue.Value.ToString(CultureInfo.InvariantCulture));

            case PrimitiveType.Byte:
                OpenApiByte byteValue = (OpenApiByte)primitive;
                return(Encoding.Default.GetString(byteValue.Value));

            case PrimitiveType.Binary:
                OpenApiBinary binaryValue = (OpenApiBinary)primitive;
                StringBuilder builder     = new StringBuilder();
                foreach (byte byteVal in binaryValue.Value)
                {
                    builder.Append(Convert.ToString(byteVal, 2).PadLeft(8, '0'));
                }
                return(builder.ToString());

            case PrimitiveType.Date:
                OpenApiDate dateValue = (OpenApiDate)primitive;
                return(dateValue.Value.ToString(CultureInfo.InvariantCulture));

            case PrimitiveType.DateTime:
                OpenApiDateTime dateTimeValue = (OpenApiDateTime)primitive;
                return(dateTimeValue.Value.ToString(CultureInfo.InvariantCulture));

            case PrimitiveType.Password:
                OpenApiPassword passwordValue = (OpenApiPassword)primitive;
                return(passwordValue.Value);

            default:
                throw new NotImplementedException("This data example type is not supported yet!");
            }
        }
        public static bool TryCreateFrom(object value, out IOpenApiAny openApiAny)
        {
            openApiAny = FactoryMethodMap.TryGetValue(value.GetType(), out Func <object, IOpenApiAny> factoryMethod)
                ? factoryMethod(value)
                : null;

            return(openApiAny != null);
        }
        public static string AsString(this IOpenApiAny openApiAny)
        {
            if (openApiAny is OpenApiString openApiString)
            {
                return(openApiString.Value);
            }

            return(openApiAny.ToString());
        }
Esempio n. 13
0
        /// <summary>
        /// Visits <see cref="IOpenApiAny"/> and child objects
        /// </summary>
        internal void Walk(IOpenApiAny example)
        {
            if (example == null)
            {
                return;
            }

            _visitor.Visit(example);
        }
Esempio n. 14
0
        public static string ToJson(this IOpenApiAny openApiAny)
        {
            var stringWriter = new StringWriter();
            var jsonWriter   = new OpenApiJsonWriter(stringWriter);

            openApiAny.Write(jsonWriter, OpenApiSpecVersion.OpenApi3_0);

            return(stringWriter.ToString());
        }
Esempio n. 15
0
        private static JToken ConvertAny(IOpenApiAny any)
        {
            if (any == null)
            {
                return(null);
            }

            var json = OpenApiSerializer.Serialize(x => any.Write(x, OpenApiSpecVersion.OpenApi3_0));

            return(JToken.Parse(json));
        }
        public IOpenApiExtension Parse([NotNull] IOpenApiAny data, OpenApiSpecVersion specVersion)
        {
            if (!(data is OpenApiObject objData))
            {
                throw new FormatException($"{EndpointList.ExtensionKey} is not an object.");
            }

            var result = new EndpointList();

            result.Parse(objData, this);
            return(result);
        }
Esempio n. 17
0
        private JToken MapOpenApiAnyToJToken(IOpenApiAny any)
        {
            if (any == null)
            {
                return(null);
            }

            using var outputString = new StringWriter();
            var writer = new OpenApiJsonWriter(outputString);

            any.Write(writer, OpenApiSpecVersion.OpenApi3_0);

            return(JObject.Parse(outputString.ToString()));
        }
Esempio n. 18
0
        public static bool TryCreateFor(OpenApiSchema schema, object value, out IOpenApiAny openApiAny)
        {
            openApiAny = null;

            if (schema.Type == "boolean" && TryCast(value, out bool boolValue))
            {
                openApiAny = new OpenApiBoolean(boolValue);
            }

            else if (schema.Type == "integer" && schema.Format == "int16" && TryCast(value, out short shortValue))
            {
                openApiAny = new OpenApiInteger(shortValue); // preliminary unboxing is required; simply casting to int won't suffice
            }
            else if (schema.Type == "integer" && schema.Format == "int32" && TryCast(value, out int intValue))
            {
                openApiAny = new OpenApiInteger(intValue);
            }

            else if (schema.Type == "integer" && schema.Format == "int64" && TryCast(value, out long longValue))
            {
                openApiAny = new OpenApiLong(longValue);
            }

            else if (schema.Type == "number" && schema.Format == "float" && TryCast(value, out float floatValue))
            {
                openApiAny = new OpenApiFloat(floatValue);
            }

            else if (schema.Type == "number" && schema.Format == "double" && TryCast(value, out double doubleValue))
            {
                openApiAny = new OpenApiDouble(doubleValue);
            }

            else if (schema.Type == "string" && value.GetType().IsEnum)
            {
                openApiAny = new OpenApiString(Enum.GetName(value.GetType(), value));
            }

            else if (schema.Type == "string" && schema.Format == "date-time" && TryCast(value, out DateTime dateTimeValue))
            {
                openApiAny = new OpenApiDate(dateTimeValue);
            }

            else if (schema.Type == "string")
            {
                openApiAny = new OpenApiString(value.ToString());
            }

            return(openApiAny != null);
        }
        /// <summary>
        /// 获取或创建接口初始类
        /// </summary>
        /// <param name="type"></param>
        /// <param name="innerModel">处理内部模型</param>
        /// <returns></returns>
        public static IOpenApiAny GetOrNullFor(this Type type, bool innerModel = true)
        {
            if (CacheExtention.OpenApiObjectDic.ContainsKey(type.FullName))
            {
                return(CacheExtention.OpenApiObjectDic[type.FullName]);
            }

            var example = new OpenApiObject();

            var propertyDic = type.GetPropertysOfTypeDic(false);

            type.FilterModel((_type, prop) =>
            {
                IOpenApiAny any = prop.PropertyType.IsArray ||
                                  prop.PropertyType.IsGenericType ?
                                  new OpenApiArray {
                    prop.CreateFor(innerModel)
                } :
                prop.CreateFor(innerModel);

                example.Add(prop.Name, any);

                if (!propertyDic.ContainsKey(_type.FullName))
                {
                    propertyDic.Add(_type.FullName, new List <string>()
                    {
                        prop.Name
                    });
                }
                else
                {
                    propertyDic[_type.FullName].Add(prop.Name);
                }

                if (!CacheExtention.AssemblyOfTypeDic.ContainsKey(_type.FullName))
                {
                    CacheExtention.AssemblyOfTypeDic.AddOrUpdate(_type.FullName, _type.Assembly.FullName, (key, old) => _type.Assembly.FullName);
                }
            });

            //type.SetPropertysOfTypeDic(propertyDic);

            if (!CacheExtention.OpenApiObjectDic.ContainsKey(type.FullName))
            {
                CacheExtention.OpenApiObjectDic.AddOrUpdate(type.FullName, example, (key, old) => example);
            }

            return(example);
        }
Esempio n. 20
0
        static string GetStringFromAnyType(IOpenApiAny value)
        {
            switch (value.AnyType)
            {
            case AnyType.Primitive:
                return(OpenApiAnyConvertor.GetPrimitiveValue(value));

            case AnyType.Object:
            case AnyType.Array:
                return(OpenApiAnyConvertor.GetJsonValue(value));

            default:
                throw new NotImplementedException("This data example type is not supported yet!");
            }
        }
Esempio n. 21
0
 public static string GetValueFromPrimitiveType(IOpenApiAny anyPrimitive)
 {
     if (anyPrimitive is OpenApiInteger integerValue)
     {
         return integerValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiLong longValue)
     {
         return longValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiFloat floatValue)
     {
         return floatValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiDouble doubleValue)
     {
         return doubleValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiString stringValue)
     {
         return stringValue.Value;
     }
     if (anyPrimitive is OpenApiByte byteValue)
     {
         return byteValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiBinary binaryValue)
     {
         return binaryValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiBoolean boolValue)
     {
         return boolValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiDate dateValue)
     {
         return dateValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiDateTime dateTimeValue)
     {
         return dateTimeValue.Value.ToString();
     }
     if (anyPrimitive is OpenApiPassword passwordValue)
     {
         return passwordValue.Value.ToString();
     }
     return string.Empty;
 }
 protected static string RenderOpenApiObject(IOpenApiAny item)
 {
     using (var stream = new MemoryStream())
     {
         using (var writer = new StreamWriter(stream, System.Text.Encoding.ASCII, 1024, true))
         {
             var openApiWriter = new OpenApiJsonWriter(writer);
             item.Write(openApiWriter, Microsoft.OpenApi.OpenApiSpecVersion.OpenApi2_0);
         }
         stream.Seek(0, SeekOrigin.Begin);
         using (var reader = new StreamReader(stream))
         {
             return(reader.ReadToEnd());
         }
     }
 }
Esempio n. 23
0
        private void TransformRec(string key, IOpenApiAny property, dynamic node)
        {
            if (property.AnyType == AnyType.Array)
            {
                var list = new List <dynamic>();
                foreach (var item in ((OpenApiArray)property))
                {
                    dynamic p = new ExpandoObject();

                    if (item.AnyType == AnyType.Primitive)
                    {
                        p = ((dynamic)item).Value;
                    }
                    else
                    {
                        foreach (var(s, value) in (OpenApiObject)item)
                        {
                            TransformRec(s, value, p);
                        }
                    }

                    list.Add(p);
                }
                ((IDictionary <string, object>)node).Add(key, list);
            }
            else if (property.AnyType == AnyType.Object)
            {
                dynamic p = new ExpandoObject();
                foreach (var(s, value) in (OpenApiObject)property)
                {
                    TransformRec(s, value, p);
                }

                ((IDictionary <string, object>)node).Add(key, p);
            }
            else if (property.AnyType == AnyType.Null)
            {
                ((IDictionary <string, object>)node).Add(key, null);
            }
            else
            {
                var value = ((dynamic)property).Value;
                ((IDictionary <string, object>)node).Add(key, value);
            }
        }
        private static string WriteAsJson(IOpenApiAny any)
        {
            // Arrange (continued)
            var            stream = new MemoryStream();
            IOpenApiWriter writer = new OpenApiJsonWriter(new StreamWriter(stream));

            writer.WriteAny(any);
            writer.Flush();
            stream.Position = 0;

            // Act
            var value = new StreamReader(stream).ReadToEnd();

            if (any.AnyType == AnyType.Primitive || any.AnyType == AnyType.Null)
            {
                return(value);
            }

            return(value.MakeLineBreaksEnvironmentNeutral());
        }
Esempio n. 25
0
        /// <summary>
        /// Add extension into the Extensions
        /// </summary>
        /// <typeparam name="T"><see cref="IOpenApiExtensible"/>.</typeparam>
        /// <param name="element">The extensible Open API element. </param>
        /// <param name="name">The extension name.</param>
        /// <param name="any">The extension value.</param>
        public static void AddExtension <T>(this T element, string name, IOpenApiAny any)
            where T : IOpenApiExtensible
        {
            if (element == null)
            {
                throw Error.ArgumentNull(nameof(element));
            }

            if (string.IsNullOrWhiteSpace(name))
            {
                throw Error.ArgumentNullOrWhiteSpace(nameof(name));
            }

            if (!name.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix))
            {
                throw new OpenApiException(string.Format(SRResource.ExtensionFieldNameMustBeginWithXDash, name));
            }

            element.Extensions[name] = any ?? throw Error.ArgumentNull(nameof(any));
        }
        private static OpenApiExample CreateStructuredTypeExample(IEdmStructuredType structuredType)
        {
            OpenApiExample example = new OpenApiExample();

            OpenApiObject value = new OpenApiObject();

            IEdmEntityType entityType = structuredType as IEdmEntityType;

            // properties
            foreach (var property in structuredType.DeclaredProperties.OrderBy(p => p.Name))
            {
                // IOpenApiAny item;
                IEdmTypeReference propertyType = property.Type;

                IOpenApiAny item = GetTypeNameForExample(propertyType);

                EdmTypeKind typeKind = propertyType.TypeKind();
                if (typeKind == EdmTypeKind.Primitive && item is OpenApiString)
                {
                    OpenApiString stringAny     = item as OpenApiString;
                    string        propertyValue = stringAny.Value;
                    if (entityType != null && entityType.Key().Any(k => k.Name == property.Name))
                    {
                        propertyValue += " (identifier)";
                    }
                    if (propertyType.IsDateTimeOffset() || propertyType.IsDate() || propertyType.IsTimeOfDay())
                    {
                        propertyValue += " (timestamp)";
                    }
                    item = new OpenApiString(propertyValue);
                }

                value.Add(property.Name, item);
            }
            example.Value = value;
            return(example);
        }
Esempio n. 27
0
        private static OpenApiExample ToOpenApiExample(
            this XElement element,
            Dictionary <string, FieldValueInfo> crefFieldValueMap,
            List <GenerationError> generationErrors)
        {
            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)
            {
                generationErrors.Add(
                    new GenerationError
                {
                    ExceptionType = nameof(InvalidExampleException),
                    Message       = SpecificationGenerationMessages.ProvideEitherValueOrUrlTag
                });

                return(null);
            }

            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))
                {
                    generationErrors.Add(
                        new GenerationError
                    {
                        ExceptionType = nameof(InvalidExampleException),
                        Message       = SpecificationGenerationMessages.ProvideValueForExample
                    });

                    return(null);
                }

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

                if (!string.IsNullOrWhiteSpace(crefValue) && crefFieldValueMap.ContainsKey(crefValue))
                {
                    var fieldValueInfo = crefFieldValueMap[crefValue];

                    if (fieldValueInfo.Error != null)
                    {
                        generationErrors.Add(fieldValueInfo.Error);

                        return(null);
                    }

                    exampleValue = new OpenApiStringReader().ReadFragment <IOpenApiAny>(
                        fieldValueInfo.Value,
                        OpenApiSpecVersion.OpenApi3_0,
                        out OpenApiDiagnostic _);
                }

                openApiExample.Value = exampleValue;
            }

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

            return(openApiExample);
        }
        private static OpenApiSchema CreateStructuredTypeSchema(this ODataContext context, IEdmStructuredType structuredType, bool processBase, bool processExample,
                                                                IEnumerable <IEdmStructuredType> derivedTypes = null)
        {
            Debug.Assert(context != null);
            Debug.Assert(structuredType != null);

            IOpenApiAny example = null;

            if (context.Settings.ShowSchemaExamples)
            {
                example = CreateStructuredTypePropertiesExample(context, structuredType);
            }

            if (context.Settings.EnableDiscriminatorValue && derivedTypes == null)
            {
                derivedTypes = context.Model.FindAllDerivedTypes(structuredType);
            }

            if (processBase && structuredType.BaseType != null)
            {
                // The x-ms-discriminator-value extension is added to structured types which are derived types.
                Dictionary <string, IOpenApiExtension> extension = null;
                if (context.Settings.EnableDiscriminatorValue && !derivedTypes.Any())
                {
                    extension = new Dictionary <string, IOpenApiExtension>
                    {
                        { Constants.xMsDiscriminatorValue, new OpenApiString("#" + structuredType.FullTypeName()) }
                    };
                }

                // A structured type with a base type is represented as a Schema Object
                // that contains the keyword allOf whose value is an array with two items:
                return(new OpenApiSchema
                {
                    Extensions = extension,

                    AllOf = new List <OpenApiSchema>
                    {
                        // 1. a JSON Reference to the Schema Object of the base type
                        new OpenApiSchema
                        {
                            UnresolvedReference = true,
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.Schema,
                                Id = structuredType.BaseType.FullTypeName()
                            }
                        },

                        // 2. a Schema Object describing the derived type
                        context.CreateStructuredTypeSchema(structuredType, false, false, derivedTypes)
                    },

                    AnyOf = null,
                    OneOf = null,
                    Properties = null,
                    Example = example
                });
            }
            else
            {
                // The discriminator object is added to structured types which have derived types.
                OpenApiDiscriminator discriminator = null;
                if (context.Settings.EnableDiscriminatorValue && derivedTypes.Any())
                {
                    Dictionary <string, string> mapping = derivedTypes
                                                          .ToDictionary(x => $"#{x.FullTypeName()}", x => new OpenApiSchema
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.Schema,
                            Id   = x.FullTypeName()
                        }
                    }.Reference.ReferenceV3);

                    discriminator = new OpenApiDiscriminator
                    {
                        PropertyName = Constants.OdataType,
                        Mapping      = mapping
                    };
                }

                // A structured type without a base type is represented as a Schema Object of type object
                OpenApiSchema schema = new()
                {
                    Title = (structuredType as IEdmSchemaElement)?.Name,

                    Type = "object",

                    Discriminator = discriminator,

                    // Each structural property and navigation property is represented
                    // as a name/value pair of the standard OpenAPI properties object.
                    Properties = context.CreateStructuredTypePropertiesSchema(structuredType),

                    // make others null
                    AllOf = null,
                    OneOf = null,
                    AnyOf = null
                };

                if (context.Settings.EnableDiscriminatorValue)
                {
                    if (!schema.Properties.TryAdd(Constants.OdataType, new OpenApiSchema()
                    {
                        Type = "string",
                        Default = new OpenApiString("#" + structuredType.FullTypeName()),
                    }))
                    {
                        throw new InvalidOperationException(
                                  $"Property {Constants.OdataType} is already present in schema {structuredType.FullTypeName()}; verify CSDL.");
                    }
                    schema.Required.Add(Constants.OdataType);
                }

                // It optionally can contain the field description,
                // whose value is the value of the unqualified annotation Core.Description of the structured type.
                if (structuredType.TypeKind == EdmTypeKind.Complex)
                {
                    IEdmComplexType complex = (IEdmComplexType)structuredType;
                    schema.Description = context.Model.GetDescriptionAnnotation(complex);
                }
                else if (structuredType.TypeKind == EdmTypeKind.Entity)
                {
                    IEdmEntityType entity = (IEdmEntityType)structuredType;
                    schema.Description = context.Model.GetDescriptionAnnotation(entity);
                }

                if (processExample)
                {
                    schema.Example = example;
                }

                return(schema);
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Converts the <see cref="OpenApiString"/>s in the given <see cref="IOpenApiAny"/>
        /// into the appropriate <see cref="IOpenApiPrimitive"/> type based on the given <see cref="OpenApiSchema"/>.
        /// For those strings that the schema does not specify the type for, convert them into
        /// the most specific type based on the value.
        /// </summary>
        public static IOpenApiAny GetSpecificOpenApiAny(IOpenApiAny openApiAny, OpenApiSchema schema)
        {
            if (openApiAny is OpenApiArray openApiArray)
            {
                var newArray = new OpenApiArray();
                foreach (var element in openApiArray)
                {
                    newArray.Add(GetSpecificOpenApiAny(element, schema?.Items));
                }

                return(newArray);
            }

            if (openApiAny is OpenApiObject openApiObject)
            {
                var newObject = new OpenApiObject();

                foreach (var key in openApiObject.Keys.ToList())
                {
                    if (schema != null && schema.Properties != null && schema.Properties.ContainsKey(key))
                    {
                        newObject[key] = GetSpecificOpenApiAny(openApiObject[key], schema.Properties[key]);
                    }
                    else
                    {
                        newObject[key] = GetSpecificOpenApiAny(openApiObject[key], schema?.AdditionalProperties);
                    }
                }

                return(newObject);
            }

            if (!(openApiAny is OpenApiString))
            {
                return(openApiAny);
            }

            if (schema?.Type == null)
            {
                return(GetSpecificOpenApiAny(openApiAny));
            }

            var type   = schema.Type;
            var format = schema.Format;

            var value = ((OpenApiString)openApiAny).Value;

            if (value == null || value == "null")
            {
                return(new OpenApiNull());
            }

            if (type == "integer" && format == "int32")
            {
                if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
                {
                    return(new OpenApiInteger(intValue));
                }
            }

            if (type == "integer" && format == "int64")
            {
                if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longValue))
                {
                    return(new OpenApiLong(longValue));
                }
            }

            if (type == "integer")
            {
                if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
                {
                    return(new OpenApiInteger(intValue));
                }
            }

            if (type == "number" && format == "float")
            {
                if (float.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var floatValue))
                {
                    return(new OpenApiFloat(floatValue));
                }
            }

            if (type == "number" && format == "double")
            {
                if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue))
                {
                    return(new OpenApiDouble(doubleValue));
                }
            }

            if (type == "number")
            {
                if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue))
                {
                    return(new OpenApiDouble(doubleValue));
                }
            }

            if (type == "string" && format == "byte")
            {
                if (byte.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var byteValue))
                {
                    return(new OpenApiByte(byteValue));
                }
            }

            // TODO: Parse byte array to OpenApiBinary type.

            if (type == "string" && format == "date")
            {
                if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateValue))
                {
                    return(new OpenApiDate(dateValue.Date));
                }
            }

            if (type == "string" && format == "date-time")
            {
                if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
                {
                    return(new OpenApiDateTime(dateTimeValue));
                }
            }

            if (type == "string" && format == "password")
            {
                return(new OpenApiPassword(value));
            }

            if (type == "string")
            {
                return(new OpenApiString(value));
            }

            if (type == "boolean")
            {
                if (bool.TryParse(value, out var booleanValue))
                {
                    return(new OpenApiBoolean(booleanValue));
                }
            }

            // If data conflicts with the given type, return a string.
            // This converter is used in the parser, so it does not perform any validations,
            // but the validator can be used to validate whether the data and given type conflicts.
            return(new OpenApiString(value));
        }
Esempio n. 30
0
        /// <summary>
        /// Converts the <see cref="OpenApiString"/>s in the given <see cref="IOpenApiAny"/>
        /// into the most specific <see cref="IOpenApiPrimitive"/> type based on the value.
        /// </summary>
        public static IOpenApiAny GetSpecificOpenApiAny(IOpenApiAny openApiAny)
        {
            if (openApiAny is OpenApiArray openApiArray)
            {
                var newArray = new OpenApiArray();
                foreach (var element in openApiArray)
                {
                    newArray.Add(GetSpecificOpenApiAny(element));
                }

                return(newArray);
            }

            if (openApiAny is OpenApiObject openApiObject)
            {
                var newObject = new OpenApiObject();

                foreach (var key in openApiObject.Keys.ToList())
                {
                    newObject[key] = GetSpecificOpenApiAny(openApiObject[key]);
                }

                return(newObject);
            }

            if (!(openApiAny is OpenApiString))
            {
                return(openApiAny);
            }

            var value = ((OpenApiString)openApiAny).Value;

            if (value == null || value == "null")
            {
                return(new OpenApiNull());
            }

            if (value == "true")
            {
                return(new OpenApiBoolean(true));
            }

            if (value == "false")
            {
                return(new OpenApiBoolean(false));
            }

            if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
            {
                return(new OpenApiInteger(intValue));
            }

            if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var longValue))
            {
                return(new OpenApiLong(longValue));
            }

            if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var doubleValue))
            {
                return(new OpenApiDouble(doubleValue));
            }

            if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTimeValue))
            {
                return(new OpenApiDateTime(dateTimeValue));
            }

            // if we can't identify the type of value, return it as string.
            return(new OpenApiString(value));
        }