Пример #1
0
        private static ObjectDeltaResult Delta(JObject source, JObject target)
        {
            var result = new ObjectDeltaResult();

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

            // compare internal fields
            var    removedNew = new JArray();
            var    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
                {
                    DeltaField(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, PREFIX_REMOVED_FIELDS);
            }
            if (removedNew.Count > 0)
            {
                AddNewValuesToken(result, removedNew, PREFIX_REMOVED_FIELDS);
            }

            return(result);
        }
Пример #2
0
 private static void AddOldValuesToken(ObjectDeltaResult item, JToken oldToken, string fieldName)
 {
     if (item.OldValues == null)
     {
         item.OldValues = new JObject();
     }
     item.OldValues[fieldName] = oldToken;
 }
Пример #3
0
        public static T PatchObject <T>(T source, ObjectDeltaResult deltaResult) where T : class
        {
            var patched = PatchObject(source, deltaResult.OldValues);

            return(PatchObject(patched, deltaResult.NewValues));
        }
Пример #4
0
 private static void AddToken(ObjectDeltaResult item, string fieldName, ObjectDeltaResult delta)
 {
     AddToken(item, fieldName, delta.OldValues, delta.NewValues);
 }
Пример #5
0
        private static void AddToken(ObjectDeltaResult item, string fieldName, JToken oldToken, JToken newToken)
        {
            AddOldValuesToken(item, oldToken, fieldName);

            AddNewValuesToken(item, newToken, fieldName);
        }
Пример #6
0
        private static void DeltaField(string fieldName, JToken source, JToken target, ObjectDeltaResult result = null)
        {
            if (result == null)
            {
                result = new ObjectDeltaResult();
            }
            if (source == null)
            {
                if (target != null)
                {
                    AddToken(result, fieldName, source, target);
                }
            }
            else if (target == null)
            {
                AddToken(result, fieldName, source, target);
            }
            else
            {
                switch (source.Type)
                {
                case JTokenType.Object:
                    var v = target as JObject;
                    var r = Delta(source as JObject, v);
                    if (!r.AreEqual)
                    {
                        AddToken(result, fieldName, r);
                    }
                    break;

                case JTokenType.Array:
                    var aS = source as JArray;
                    var aT = target as JArray;

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

                        if (arrayDelta.AreEqual)
                        {
                            return;
                        }
                        if (aS.Count != aT.Count)
                        {
                            AddToken(arrayDelta, PREFIX_ARRAY_SIZE, aS.Count, aT.Count);
                        }
                        AddToken(result, fieldName, arrayDelta);
                    }
                    break;

                default:
                    if (!JToken.DeepEquals(source, target))
                    {
                        AddToken(result, fieldName, source, target);
                    }
                    break;
                }
            }
        }