JsonSchemaReferenceUtilities
Provides utilities to resolve and set JSON schema references.
using Newtonsoft.Json.Linq;
using NJsonSchema.Infrastructure;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace NJsonSchema
{
public static class JsonSchemaReferenceUtilities
{
public static async Task UpdateSchemaReferencesAsync(object rootObject, JsonReferenceResolver referenceResolver)
{
await AwaitExtensions.ConfigureAwait(UpdateSchemaReferencesAsync(rootObject, rootObject, new HashSet<object>(), referenceResolver), false);
}
public static string ConvertJsonReferences(string data)
{
return data.Replace("$ref", "schemaReferencePath");
}
public static string ConvertPropertyReferences(string data)
{
return data.Replace("schemaReferencePath", "$ref");
}
public static void UpdateSchemaReferencePaths(object rootObject)
{
Dictionary<JsonSchema4, JsonSchema4> dictionary = new Dictionary<JsonSchema4, JsonSchema4>();
UpdateSchemaReferencePaths(rootObject, new HashSet<object>(), dictionary);
IEnumerable<JsonSchema4> searchedObjects = (from p in dictionary
select p.Value).Distinct();
IDictionary<object, string> jsonPaths = JsonPathUtilities.GetJsonPaths(rootObject, searchedObjects);
foreach (KeyValuePair<JsonSchema4, JsonSchema4> item in dictionary) {
item.Key.SchemaReferencePath = jsonPaths[item.Value];
}
}
private static void UpdateSchemaReferencePaths(object obj, HashSet<object> checkedObjects, Dictionary<JsonSchema4, JsonSchema4> schemaReferences)
{
if (obj != null && !(obj is string)) {
JsonSchema4 jsonSchema = obj as JsonSchema4;
if (jsonSchema != null && jsonSchema.SchemaReference != null) {
if (jsonSchema.SchemaReference.DocumentPath == null)
schemaReferences[jsonSchema] = jsonSchema.SchemaReference.ActualSchema;
else {
JsonSchema4 schemaReference = jsonSchema.SchemaReference;
JsonSchema4 rootObject = schemaReference.FindRootParent();
jsonSchema.SchemaReferencePath = schemaReference.DocumentPath + JsonPathUtilities.GetJsonPath(rootObject, schemaReference);
}
}
if (obj is IDictionary) {
foreach (object item in ((IDictionary)obj).Values.OfType<object>().ToList()) {
UpdateSchemaReferencePaths(item, checkedObjects, schemaReferences);
}
} else if (obj is IEnumerable) {
object[] array = ((IEnumerable)obj).OfType<object>().ToArray();
for (int i = 0; i < array.Length; i++) {
UpdateSchemaReferencePaths(array[i], checkedObjects, schemaReferences);
}
}
if (!(obj is JToken)) {
foreach (ReflectionCache.PropertyOrField item2 in ReflectionCache.GetPropertiesAndFields(obj.GetType()).Where(delegate(ReflectionCache.PropertyOrField p) {
if (p.CanRead && !p.IsIndexer && p.MemberInfo is PropertyInfo)
return p.CustomAttributes.JsonIgnoreAttribute == null;
return false;
})) {
object value = item2.GetValue(obj);
if (value != null && !checkedObjects.Contains(value)) {
checkedObjects.Add(value);
UpdateSchemaReferencePaths(value, checkedObjects, schemaReferences);
}
}
}
}
}
private static async Task UpdateSchemaReferencesAsync(object rootObject, object obj, HashSet<object> checkedObjects, JsonReferenceResolver jsonReferenceResolver)
{
if (obj != null && !(obj is string)) {
JsonSchema4 jsonSchema = obj as JsonSchema4;
if (jsonSchema != null && jsonSchema.SchemaReferencePath != null) {
JsonSchema4 jsonSchema2 = jsonSchema;
jsonSchema2.SchemaReference = await AwaitExtensions.ConfigureAwait(jsonReferenceResolver.ResolveReferenceAsync(rootObject, jsonSchema.SchemaReferencePath), false);
}
if (obj is IDictionary) {
object[] array = ((IDictionary)obj).Values.OfType<object>().ToArray();
for (int i = 0; i < array.Length; i++) {
await AwaitExtensions.ConfigureAwait(UpdateSchemaReferencesAsync(rootObject, array[i], checkedObjects, jsonReferenceResolver), false);
}
} else if (obj is IEnumerable) {
object[] array = ((IEnumerable)obj).OfType<object>().ToArray();
for (int i = 0; i < array.Length; i++) {
await AwaitExtensions.ConfigureAwait(UpdateSchemaReferencesAsync(rootObject, array[i], checkedObjects, jsonReferenceResolver), false);
}
}
if (!(obj is JToken)) {
foreach (ReflectionCache.PropertyOrField item in ReflectionCache.GetPropertiesAndFields(obj.GetType()).Where(delegate(ReflectionCache.PropertyOrField p) {
if (p.CanRead && !p.IsIndexer && p.MemberInfo is PropertyInfo)
return p.CustomAttributes.JsonIgnoreAttribute == null;
return false;
})) {
object value = item.GetValue(obj);
if (value != null && !checkedObjects.Contains(value)) {
checkedObjects.Add(value);
await AwaitExtensions.ConfigureAwait(UpdateSchemaReferencesAsync(rootObject, value, checkedObjects, jsonReferenceResolver), false);
}
}
}
}
}
}
}