private IEnumerable<IPath> BuildPaths(JToken data, Stack<Tuple<JProperty, bool>> propertyStack, JToken root)
{
var paths = new List<IPath>();
if (propertyStack.Count == 0 && data.IsEnumerable())
{
//
// Handle raw array of values
//
paths.Add(new JsonPath(JsonPath.EnumerableSymbol + JsonPath.SeperatorSymbol,
JsonPath.EnumerableSymbol + JsonPath.SeperatorSymbol, data.ToString()));
}
if (propertyStack.Count == 0 && data.IsPrimitive())
{
//
// Handle if the poco mapper is used to map to a raw primitive
//
paths.Add(new JsonPath(JsonPath.SeperatorSymbol, JsonPath.SeperatorSymbol, data.ToString()));
}
else if (data.IsObject())
{
var dataAsJObject = data as JObject;
if (dataAsJObject == null)
{
throw new Exception(string.Format("Data of type '{0}' expected, data of type '{1}' received.",
typeof (JObject), data.GetType()));
}
IList<JProperty> dataProperties = dataAsJObject.Properties().ToList();
foreach (
JProperty property in dataProperties.Where(p => p.IsPrimitive() || p.IsEnumerableOfPrimitives()))
{
JToken propertyData;
try
{
propertyData = property.Value;
}
catch (Exception ex)
{
Dev2Logger.Log.Error(ex);
propertyData = null;
}
if (propertyData != null)
{
paths.Add(BuildPath(propertyStack, property, root));
}
}
foreach (
JProperty property in dataProperties.Where(p => !p.IsPrimitive() && !p.IsEnumerableOfPrimitives()))
{
JContainer propertyData;
try
{
propertyData = property.Value as JContainer;
}
catch (Exception ex)
{
Dev2Logger.Log.Error(ex);
propertyData = null;
//TODO When an exception is encountered stop discovery for this path and write to log
}
if (propertyData != null)
{
if (property.IsEnumerable())
{
// ReSharper disable RedundantCast
var enumerableData = propertyData as IEnumerable;
// ReSharper restore RedundantCast
// ReSharper disable ConditionIsAlwaysTrueOrFalse
if (enumerableData != null)
// ReSharper restore ConditionIsAlwaysTrueOrFalse
{
IEnumerator enumerator = enumerableData.GetEnumerator();
enumerator.Reset();
if (enumerator.MoveNext())
{
propertyData = enumerator.Current as JContainer;
if (propertyData != null)
{
propertyStack.Push(new Tuple<JProperty, bool>(property, true));
paths.AddRange(BuildPaths(propertyData, propertyStack, root));
propertyStack.Pop();
}
}
}
}
else
{
propertyStack.Push(new Tuple<JProperty, bool>(property, true));
paths.AddRange(BuildPaths(propertyData, propertyStack, root));
propertyStack.Pop();
}
}
}
}
return paths;
}