예제 #1
0
        private static ObjectDiffPatchResult Diff(JObject source, JObject target)
        {
            ObjectDiffPatchResult result = new ObjectDiffPatchResult();

            // check for null values
            if (source == null && target == null)
            {
                return(result);
            }
            else if (source == null || target == null)
            {
                result.OldValues = source;
                result.NewValues = target;
                return(result);
            }

            // compare internal fields
            JArray removedNew = new JArray();
            JArray removedOld = new JArray();
            JToken token;

            // start by iterating in source fields
            foreach (var i in source)
            {
                // check if field exists
                if (!target.TryGetValue(i.Key, out token))
                {
                    AddOldValuesToken(result, i.Value, i.Key);
                    removedNew.Add(i.Key);
                }
                // compare field values
                else
                {
                    DiffField(i.Key, i.Value, token, result);
                }
            }
            // then iterate in target fields that are not present in source
            foreach (var i in target)
            {
                // ignore alredy compared values
                if (source.TryGetValue(i.Key, out token))
                {
                    continue;
                }
                // add missing tokens
                removedOld.Add(i.Key);
                AddNewValuesToken(result, i.Value, i.Key);
            }

            if (removedOld.Count > 0)
            {
                AddOldValuesToken(result, removedOld, PrefixRemovedFields);
            }
            if (removedNew.Count > 0)
            {
                AddNewValuesToken(result, removedNew, PrefixRemovedFields);
            }

            return(result);
        }
예제 #2
0
 private static void AddOldValuesToken(ObjectDiffPatchResult item, JToken oldToken, string fieldName)
 {
     if (item.OldValues == null)
     {
         item.OldValues = new JObject();
     }
     item.OldValues[fieldName] = oldToken;
 }
예제 #3
0
 private static void AddToken(ObjectDiffPatchResult item, string fieldName, ObjectDiffPatchResult diff)
 {
     AddToken(item, fieldName, diff.OldValues, diff.NewValues);
 }
예제 #4
0
        private static void AddToken(ObjectDiffPatchResult item, string fieldName, JToken oldToken, JToken newToken)
        {
            AddOldValuesToken(item, oldToken, fieldName);

            AddNewValuesToken(item, newToken, fieldName);
        }
예제 #5
0
        private static void DiffField(string fieldName, JToken source, JToken target, ObjectDiffPatchResult result = null)
        {
            if (result == null)
            {
                result = new ObjectDiffPatchResult();
            }
            if (source == null)
            {
                if (target != null)
                {
                    AddToken(result, fieldName, null, target);
                }
            }
            else if (target == null)
            {
                AddToken(result, fieldName, source, null);
            }
            else if (source.Type == JTokenType.Object)
            {
                var v = target as JObject;
                var r = Diff(source as JObject, v);
                if (!r.AreEqual)
                {
                    AddToken(result, fieldName, r);
                }
            }
            else if (source.Type == JTokenType.Array)
            {
                var aS = (source as JArray);
                var aT = (target as JArray);

                if (aS == null || aT == null)
                {
                    AddToken(result, fieldName, source, target);
                }
                else if ((aS.Count == 0 || aT.Count == 0) && (aS.Count != aT.Count))
                {
                    AddToken(result, fieldName, source, target);
                }
                else
                {
                    ObjectDiffPatchResult arrayDiff = new ObjectDiffPatchResult();
                    int minCount = Math.Min(aS.Count, aT.Count);
                    for (int i = 0; i < Math.Max(aS.Count, aT.Count); i++)
                    {
                        if (i < minCount)
                        {
                            DiffField(i.ToString(), aS[i], aT[i], arrayDiff);
                        }
                        else if (i >= aS.Count)
                        {
                            AddNewValuesToken(arrayDiff, aT[i], i.ToString());
                        }
                        else
                        {
                            AddOldValuesToken(arrayDiff, aS[i], i.ToString());
                        }
                    }

                    if (!arrayDiff.AreEqual)
                    {
                        if (aS.Count != aT.Count)
                        {
                            AddToken(arrayDiff, PrefixArraySize, aS.Count, aT.Count);
                        }
                        AddToken(result, fieldName, arrayDiff);
                    }
                }
            }
            else
            {
                if (!JToken.DeepEquals(source, target))
                {
                    AddToken(result, fieldName, source, target);
                }
            }
        }