JsonPathUtilities
Utilities to work with JSON paths.
using Newtonsoft.Json.Serialization;
using NJsonSchema.Infrastructure;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace NJsonSchema
{
public static class JsonPathUtilities
{
public const string ReferenceReplaceString = "__referencePath";
public static string GetJsonPath(object rootObject, object searchedObject)
{
return GetJsonPath(rootObject, searchedObject, new DefaultContractResolver());
}
public static string GetJsonPath(object rootObject, object searchedObject, IContractResolver contractResolver)
{
return GetJsonPaths(rootObject, new List<object> {
searchedObject
}, contractResolver)[searchedObject];
}
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))
throw new InvalidOperationException("Could not find the JSON path of a referenced schema: Manually referenced schemas must be added to the 'Definitions' of a parent schema.");
return dictionary;
}
private static bool FindJsonPaths(object obj, Dictionary<object, string> searchedObjects, string basePath, HashSet<object> checkedObjects, IContractResolver contractResolver)
{
if (obj == null || obj is string || 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);
if (obj is IDictionary) {
foreach (object key in ((IDictionary)obj).Keys) {
if (FindJsonPaths(((IDictionary)obj)[key], searchedObjects, basePath + "/" + key, checkedObjects, contractResolver))
return true;
}
} else if (obj is IEnumerable) {
int num = 0;
foreach (object item in (IEnumerable)obj) {
if (FindJsonPaths(item, searchedObjects, basePath + "/" + num, checkedObjects, contractResolver))
return true;
num++;
}
} else {
JsonObjectContract obj2 = contractResolver.ResolveContract(obj.GetType()) as JsonObjectContract;
Newtonsoft.Json.Serialization.JsonProperty[] source = ((obj2 != null) ? obj2.Properties.Where(delegate(Newtonsoft.Json.Serialization.JsonProperty p) {
if (!p.Ignored) {
Predicate<object> shouldSerialize = p.ShouldSerialize;
if (shouldSerialize == null)
return false;
return !shouldSerialize(obj);
}
return true;
}).ToArray() : null) ?? new Newtonsoft.Json.Serialization.JsonProperty[0];
foreach (ReflectionCache.PropertyOrField item2 in from p in ReflectionCache.GetPropertiesAndFields(obj.GetType())
where p.CustomAttributes.JsonIgnoreAttribute == null
select p) {
string name = item2.GetName();
bool flag = obj is IJsonExtensionObject && name == "ExtensionData";
if (flag || source.All((Newtonsoft.Json.Serialization.JsonProperty p2) => p2.UnderlyingName != item2.MemberInfo.Name)) {
object value = item2.GetValue(obj);
if (value != null) {
if (flag) {
if (FindJsonPaths(value, searchedObjects, basePath, checkedObjects, contractResolver))
return true;
} else if (FindJsonPaths(value, searchedObjects, basePath + "/" + name, checkedObjects, contractResolver)) {
return true;
}
}
}
}
}
return false;
}
}
}