ln.objects/ng/diff/ListDiff.cs

103 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ln.objects.catalog;
namespace ln.types.odb.ng.diff
{
public class ListDiff : Diff
{
List<ODBValue> remove = new List<ODBValue>();
List<ODBEntity> add = new List<ODBEntity>();
Dictionary<ODBValue, Diff> update = new Dictionary<ODBValue, Diff>();
public ListDiff(ODBList src,ODBList dst)
{
HashSet<ODBEntity> srcItems = new HashSet<ODBEntity>(src);
HashSet<ODBEntity> common = new HashSet<ODBEntity>(srcItems);
HashSet<ODBEntity> dstItems = new HashSet<ODBEntity>(dst);
HashSet<ODBEntity> commonDst = new HashSet<ODBEntity>(dstItems);
common.IntersectWith(dstItems);
commonDst.IntersectWith(srcItems);
srcItems.ExceptWith(common);
dstItems.ExceptWith(common);
remove.AddRange(srcItems.Select((i) => i.Identity));
add.AddRange(dstItems);
Dictionary<ODBValue, ODBEntity> srcLookup = new Dictionary<ODBValue, ODBEntity>();
foreach (ODBEntity entity in common)
srcLookup.Add(entity.Identity, entity);
foreach (ODBEntity entity in commonDst)
{
ODBValue identity = entity.Identity;
ODBEntity srcEntity = srcLookup[identity];
if (entity.CompareTo(srcEntity) != 0)
update.Add(identity, Diff.Construct(srcEntity, entity));
}
}
public override ODBEntity Apply(ODBEntity src)
{
ODBList list = src as ODBList;
foreach (ODBEntity entity in list.ToArray())
{
ODBValue identity = entity.Identity;
if (remove.Contains(identity))
{
list.Remove(entity);
} else if (update.ContainsKey(identity))
{
update[identity].Apply(entity);
}
}
foreach (ODBEntity entity in add)
{
list.Add(entity.Clone());
}
return src;
}
public override string ToString()
{
return base.ToString();
}
public override string ToTreeString(int indent)
{
indent += 2;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendFormat("ListDiff Remove={0} Change={1} Add={2}",remove.Count,update.Count,add.Count);
foreach (ODBEntity key in remove)
{
stringBuilder.AppendLine();
stringBuilder.AppendFormat("{0}-{1}", new string(' ', indent), key);
}
foreach (ODBValue key in update.Keys)
{
stringBuilder.AppendLine();
stringBuilder.AppendFormat("{0} {1} {2}", new string(' ', indent), key, update[key].ToTreeString(indent));
}
foreach (ODBEntity key in add)
{
stringBuilder.AppendLine();
stringBuilder.AppendFormat("{0}+{1}", new string(' ', indent), key.ToTreeString(indent));
}
return stringBuilder.ToString();
}
}
}