private static void ReplaceRefsInSchemaArray(SchemaArray array, JSONSchema root) { if (array?.Count > 0) { for (int i = 0; i < array.Count; i++) { if (array[i]?.Ref != null) { array[i] = convertRefToSchema(array[i].Ref, root); } else { ReplaceRefs(array[i], root); } } } }
public static JSONSchema MergeSchemas(SchemaArray schemas) { JSONSchema result = new JSONSchema(); //handle recursivity schemas = new SchemaArray( schemas.Where(x => x.AllOf == null || !x.AllOf.Any()) .Union( schemas.Where(x => x.AllOf != null && x.AllOf.Any()) .Select(x => MergeSchemas(x.AllOf))).ToList()); //This won't raise an exception if different (incompatible) types are defined result.Type = schemas.Where(x => x.Type != null).Select(x => x.Type).FirstOrDefault(); var multiples = schemas.Where(x => x.MultipleOf.HasValue).Select(x => x.MultipleOf.Value); if (multiples.Any()) { result.MultipleOf = multiples.Aggregate((uint)1, (lcm, next) => LCM(lcm, next)); } var max = schemas.Where(x => x.Maximum.HasValue).Select(x => x.Maximum); if (max.Any()) { result.Maximum = max.Min(); result.ExclusiveMaximum = schemas.Where(x => x.ExclusiveMaximum.HasValue && x.Maximum == result.Maximum).Select(x => x.ExclusiveMaximum).FirstOrDefault(); } var min = schemas.Where(x => x.Mininum.HasValue).Select(x => x.Mininum); if (min.Any()) { result.Mininum = min.Max(); result.ExclusiveMinimum = schemas.Where(x => x.ExclusiveMinimum.HasValue && x.Mininum == result.Mininum).Select(x => x.ExclusiveMinimum).FirstOrDefault(); } var maxLength = schemas.Where(x => x.MaxLength.HasValue).Select(x => x.MaxLength); if (maxLength.Any()) { result.MaxLength = maxLength.Min(); } var minLength = schemas.Where(x => x.MinLength.HasValue).Select(x => x.MinLength); if (minLength.Count() > 0) { result.MinLength = minLength.Max(); } var patterns = schemas.Where(x => !string.IsNullOrEmpty(x.Pattern)).Select(x => x.Pattern); if (patterns.Any()) { result.Pattern = string.Concat(patterns.Select(x => string.Format("(?={0})", x))); } //TODO: items var maxItems = schemas.Where(x => x.MaxItems.HasValue).Select(x => x.MaxItems); if (maxItems.Any()) { result.MaxItems = maxItems.Min(); } var minItems = schemas.Where(x => x.MinItems.HasValue).Select(x => x.MinItems); if (minItems.Any()) { result.MinItems = minItems.Max(); } var properties = schemas.Where(x => x.Properties != null && x.Properties.Any()).Select(x => x.Properties); if (properties.Any()) { result.Properties = properties.SelectMany(dict => dict) .ToLookup(pair => pair.Key, pair => pair.Value) .ToDictionary(group => group.Key, group => group.First()); } return(result); }
private string ToString(int indent, HashSet <JSONSchema> visited) { StringBuilder sb = new StringBuilder(); if (visited.Contains(this)) { sb.Append(spaces(indent)); sb.Append("$ref: "); sb.Append(this.GetHashCode()); return(sb.ToString()); } visited.Add(this); sb.Append('{'); PropertyInfo[] fields = typeof(JSONSchema).GetProperties(); foreach (PropertyInfo field in fields) { if (field.GetValue(this) == null) { continue; } sb.AppendLine(); sb.Append(spaces(indent + 1)); sb.Append("\"" + field.Name + "\" : "); if (field.PropertyType == typeof(string) || field.PropertyType == typeof(UInt32?) || field.PropertyType == typeof(bool?) || field.PropertyType == typeof(SimpleType)) { sb.Append("\""); sb.Append(field.GetValue(this)); sb.Append("\""); } if (field.PropertyType == typeof(Dictionary <string, JSONSchema>)) { sb.Append("{"); Dictionary <string, JSONSchema> dict = field.GetValue(this) as Dictionary <string, JSONSchema>; int n = dict.Count; int i = 1; foreach (string key in dict.Keys) { sb.AppendLine(); sb.Append(spaces(indent + 2)); sb.Append("\"" + key + "\": "); sb.Append(dict[key].ToString(indent + 2, visited)); if (i < n) { sb.Append(','); } } sb.AppendLine(); sb.Append(spaces(indent + 1) + "}"); } System.Type fieldType = field.PropertyType; Object fieldValue = field.GetValue(this); if (field.PropertyType.IsGenericType && field.PropertyType.GetGenericTypeDefinition() == typeof(AnyOf <,>)) { fieldType = (System.Type)field.PropertyType.GetMethod("GetUnderlyingType").Invoke(field.GetValue(this), null); //sb.Append(fieldType.Name); fieldValue = field.PropertyType.GetMethod("GetValue").Invoke(field.GetValue(this), null); } if (fieldType == typeof(SimpleType)) { sb.Append("\""); sb.Append((fieldValue as SimpleType).Value); sb.Append("\""); } if (fieldType == typeof(SchemaArray)) { sb.Append("["); SchemaArray arr = fieldValue as SchemaArray; int n = arr.Count; int i = 1; foreach (JSONSchema schema in arr) { sb.AppendLine(); sb.Append(spaces(indent + 1)); sb.Append(schema.ToString(indent + 1, visited)); if (i < n) { sb.Append(','); } } sb.AppendLine(); sb.Append(spaces(indent + 1) + "]"); } if (fieldType == typeof(JSONSchema)) { sb.Append((fieldValue as JSONSchema).ToString(indent + 1, visited)); } if (fieldType == typeof(UniqueNonEmptyList <JsonElement>)) { var list = fieldValue as UniqueNonEmptyList <JsonElement>; sb.Append("[ "); int n = list.Count; int i = 1; foreach (JsonElement jsonElement in list) { sb.Append(jsonElement.ToString()); if (i < n) { sb.Append(", "); } } sb.Append(" ]"); } if (fieldType == typeof(JsonElement?)) { JsonElement jsonElement = (JsonElement)fieldValue; sb.Append(jsonElement.ToString()); } } sb.AppendLine(); sb.Append(spaces(indent)); sb.Append('}'); return(sb.ToString()); }