private void SetupParentAttribute(XElement basis, XElement e) { if (e.Parent != basis) { var parentKey = new XDiffKey(_options, e.Parent); string parentRef = ""; if (!_options.IsNameIndepended) { parentRef += parentKey.Name + "-"; } if (!string.IsNullOrWhiteSpace(parentKey.Id) && 0 != parentKey.Id.ToInt()) { parentRef += "id-" + parentKey.Id; } else { parentRef += "code-" + parentKey.Code; } e.SetAttributeValue("__parent", parentRef); } }
private bool Equals(XDiffKey other) { if (!_options.IsNameIndepended && Name != other.Name) { return(false); } bool?equalId = null; if (!string.IsNullOrWhiteSpace(Id) && !string.IsNullOrWhiteSpace(other.Id)) { equalId = Id == other.Id; if (!_options.ChangeIds) { return(equalId.Value); } } if (!string.IsNullOrWhiteSpace(Code) && !string.IsNullOrWhiteSpace(other.Code)) { return(Code == other.Code); } return(equalId.HasValue && equalId.Value); }
private void RegisterBase(XElement basis, ref int trgid, XElement e, ConcurrentDictionary <int, EndpointPack> trg, ConcurrentDictionary <string, InterPack> idinter, ConcurrentDictionary <string, InterPack> codeinter) { int id = Interlocked.Increment(ref trgid); var key = new XDiffKey(_options, e); string _id = _options.IsNameIndepended ? key.Id : (key.Name + "_" + key.Id); string _code = _options.IsNameIndepended ? key.Code : (key.Name + "_" + key.Code); if (_options.IsHierarchy) { SetupParentAttribute(basis, e); } var ep = new EndpointPack { Key = key, Element = e, Bag = new ConcurrentBag <XElement>() }; trg[id] = ep; if (!string.IsNullOrWhiteSpace(key.Id)) { idinter.AddOrUpdate(_id, _ => new InterPack { Target = ep }, (k, _) => { if (null != _.Target) { throw new Exception("double id match in trg " + _.Target.Key); } _.Target = ep; ConcurrentBag <XElement> _bag = _.Source.Bag; _.Source.Bag = ep.Bag; foreach (XElement c in _bag) { ep.Bag.Add(c); } ep.IsBound = true; _.Source.IsBound = true; return(_); }); } if (!string.IsNullOrWhiteSpace(key.Code)) { codeinter.AddOrUpdate(_code, _ => new InterPack { Target = ep }, (k, _) => { if (null != _.Target) { throw new Exception("double code match in trg " + _.Target.Key); } _.Target = ep; if (_.Source.Bag != ep.Bag) { ConcurrentBag <XElement> _bag = _.Source.Bag; _.Source.Bag = ep.Bag; foreach (XElement c in _bag) { ep.Bag.Add(c); } } ep.IsBound = true; _.Source.IsBound = true; return(_); }); } return; }
private void RegisterDelta(XElement newest, ref int srcid, XElement e, ConcurrentDictionary <int, EndpointPack> src, ConcurrentDictionary <string, InterPack> idinter, ConcurrentDictionary <string, InterPack> codeinter) { int id = Interlocked.Increment(ref srcid); var key = new XDiffKey(_options, e); string _id = _options.IsNameIndepended ? key.Id : (key.Name + "_" + key.Id); string _code = _options.IsNameIndepended ? key.Code : (key.Name + "_" + key.Code); if (_options.IsHierarchy) { SetupParentAttribute(newest, e); } var ep = new EndpointPack { Key = key, Element = e, Bag = new ConcurrentBag <XElement>() }; ep.Bag.Add(e); src[id] = ep; EndpointPack _idpack = null; EndpointPack _idtrg = null; if (!string.IsNullOrWhiteSpace(key.Id) && 0 != key.Id.ToInt()) { idinter.AddOrUpdate(_id, _ => new InterPack { Source = _idpack = ep }, (k, _) => { if (null != _.Source) { _idpack = _.Source; //it's not problem if same as code binding _.Source.Bag.Add(e); ep.IsBound = true; } else { _.Source = ep; _idpack = _.Source; _.Source.Bag = _.Target.Bag; _.Target.IsBound = true; _idtrg = _.Target; ep.IsBound = true; _.Target.Bag.Add(ep.Element); } return(_); }); } if (!string.IsNullOrWhiteSpace(key.Code)) { codeinter.AddOrUpdate(_code, _ => { if (null != _idpack && _idpack != ep) { throw new Exception("ambigous source (1)" + ep.Key); } if (null != _idtrg) { throw new Exception("ambigous source (2)" + ep.Key); } return(new InterPack { Source = ep }); }, (k, _) => { if (_.Source != null && _idpack != null && _.Source != _idpack) { throw new Exception("ambigous source (3)" + ep.Key); } if (null != _idtrg && _idtrg != _.Target) { throw new Exception("ambigous source (4)" + ep.Key); } if (null != _.Source) { _.Source.Bag.Add(e); ep.IsBound = true; } else { _.Source = ep; _.Source.Bag = _.Target.Bag; _.Target.IsBound = true; ep.IsBound = true; _.Target.Bag.Add(ep.Element); } return(_); }); } }