JsonPathUtilities
Utilities to work with JSON paths.
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NJsonSchema
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class JsonPathUtilities
{
[return: System.Runtime.CompilerServices.Nullable(2)]
public static string GetJsonPath(object rootObject, object searchedObject)
{
return GetJsonPath(rootObject, searchedObject, new DefaultContractResolver());
}
[return: System.Runtime.CompilerServices.Nullable(2)]
public static string GetJsonPath(object rootObject, object searchedObject, IContractResolver contractResolver)
{
return GetJsonPaths(rootObject, new <>z__ReadOnlySingleElementList<object>(searchedObject), contractResolver)[searchedObject];
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2
})]
public static IReadOnlyDictionary<object, string> GetJsonPaths(object rootObject, IEnumerable<object> searchedObjects, IContractResolver contractResolver)
{
if (rootObject == null)
throw new ArgumentNullException("rootObject");
Dictionary<object, string> dictionary = searchedObjects.ToDictionary((Func<object, object>)((object o) => o), (Func<object, string>)((object o) => null));
FindJsonPaths(rootObject, dictionary, "#", new HashSet<object>(), contractResolver);
if (dictionary.Any((KeyValuePair<object, string> p) => p.Value == null)) {
IEnumerable<string> values = from p in dictionary
where p.Value == null
select p into x
select x.Key.GetType().FullName;
throw new InvalidOperationException("Could not find the JSON path of a referenced schema: " + string.Join(",", values) + ". Manually referenced schemas must be added to the 'Definitions' of a parent schema.");
}
return dictionary;
}
private static bool FindJsonPaths(object obj, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2
})] Dictionary<object, string> searchedObjects, string basePath, HashSet<object> checkedObjects, IContractResolver contractResolver)
{
if (obj == null)
return false;
Type type = obj.GetType();
if (type == typeof(string) || type.IsPrimitive || type.IsEnum || type == typeof(JValue) || checkedObjects.Contains(obj))
return false;
if (searchedObjects.ContainsKey(obj)) {
searchedObjects[obj] = basePath;
if (searchedObjects.All((KeyValuePair<object, string> p) => p.Value != null))
return true;
}
checkedObjects.Add(obj);
string str = basePath + "/";
IDictionary dictionary = obj as IDictionary;
if (dictionary != null) {
IDictionaryEnumerator enumerator = dictionary.GetEnumerator();
try {
while (enumerator.MoveNext()) {
DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current;
if (dictionaryEntry.Value != null && FindJsonPaths(dictionaryEntry.Value, searchedObjects, str + dictionaryEntry.Key?.ToString(), checkedObjects, contractResolver))
return true;
}
} finally {
(enumerator as IDisposable)?.Dispose();
}
} else {
IList list = obj as IList;
if (list != null) {
for (int i = 0; i < list.Count; i++) {
object obj2 = list[i];
if (obj2 != null && FindJsonPaths(obj2, searchedObjects, str + i.ToString(), checkedObjects, contractResolver))
return true;
}
} else {
IEnumerable enumerable = obj as IEnumerable;
if (enumerable != null) {
int num = 0;
foreach (object item in enumerable) {
if (item != null && FindJsonPaths(item, searchedObjects, str + num.ToString(), checkedObjects, contractResolver))
return true;
num++;
}
} else {
JsonObjectContract jsonObjectContract = contractResolver.ResolveContract(type) as JsonObjectContract;
if (jsonObjectContract != null) {
foreach (JsonProperty property in jsonObjectContract.Properties) {
if (!property.Ignored) {
object obj3 = property.ValueProvider?.GetValue(obj);
if (obj3 != null && FindJsonPaths(obj3, searchedObjects, str + property.PropertyName, checkedObjects, contractResolver))
return true;
}
}
if (obj is IJsonExtensionObject) {
PropertyInfo runtimeProperty = type.GetRuntimeProperty("ExtensionData");
if (runtimeProperty != (PropertyInfo)null) {
object value = runtimeProperty.GetValue(obj);
if (value != null && FindJsonPaths(value, searchedObjects, basePath, checkedObjects, contractResolver))
return true;
}
}
}
}
}
}
return false;
}
}
}