protected internal virtual void SynchronizeCollectionsLeftToRight(ICollection <TRight> rights, ICollection <TLeft> lefts, ISynchronizationContext context, bool ignoreCandidates) { if (context.Direction == SynchronizationDirection.CheckOnly) { MatchCollections(lefts, rights, context); return; } if (rights.IsReadOnly) { throw new InvalidOperationException("Collection is read-only!"); } IEnumerable <TRight> rightsSaved; HashSet <TRight> doubles; if (context.Direction == SynchronizationDirection.LeftToRight) { rightsSaved = null; doubles = null; } else { rightsSaved = rights.ToArray(); doubles = new HashSet <TRight>(); } IEnumerable rightContext = ignoreCandidates ? null : rights; foreach (var item in lefts) { var comp = context.CallTransformation(LeftToRight, new object[] { item }, rightContext) as SynchronizationComputation <TLeft, TRight>; comp.DoWhenOutputIsAvailable((inp, outp) => { if (!rights.Contains(outp)) { rights.Add(outp); } else if (context.Direction != SynchronizationDirection.LeftToRight) { doubles.Add(outp); } }); } if (context.Direction == SynchronizationDirection.LeftWins) { foreach (var item in rightsSaved.Except(doubles)) { var comp = context.CallTransformation(RightToLeft, new object[] { item }, null) as SynchronizationComputation <TRight, TLeft>; comp.DoWhenOutputIsAvailable((inp, outp) => { lefts.Add(outp); }); } } else if (context.Direction == SynchronizationDirection.LeftToRightForced) { foreach (var item in rightsSaved.Except(doubles)) { rights.Remove(item); } } }
private void MatchCollections(ICollection <TLeft> lefts, ICollection <TRight> rights, ISynchronizationContext context) { var leftsRemaining = lefts.ToList(); var rightsRemaining = new HashSet <TRight>(rights); foreach (var left in lefts) { var right = null as TRight; var found = false; foreach (var item in rightsRemaining) { if (ShouldCorrespond(left, item, context)) { right = item; found = true; break; } } if (found) { // call rule in order to establish trace entry and determine inner differences context.CallTransformation(LeftToRight, new object[] { left }, new Axiom(right)); rightsRemaining.Remove(right); } else { context.Inconsistencies.Add(new MissingItemInconsistency <TLeft, TRight>(context, LeftToRight, lefts, rights, left, false)); } } foreach (var item in rightsRemaining) { context.Inconsistencies.Add(new MissingItemInconsistency <TRight, TLeft>(context, RightToLeft, rights, lefts, item, true)); } }
private void AddCorrespondingToRights(ICollection <TDepRight> rights, ISynchronizationContext context, TDepLeft item) { var comp = context.CallTransformation(childRule.LeftToRight, new object[] { item }, null) as SynchronizationComputation <TDepLeft, TDepRight>; comp.DoWhenOutputIsAvailable((inp, outp) => { rights.Add(outp); }); }
private void AddCorrespondingToTargets(ICollection <TTargetDep> targets, ISynchronizationContext context, TSourceDep item) { var comp = context.CallTransformation(childRule, new object[] { item }, null) as SynchronizationComputation <TSourceDep, TTargetDep>; comp.DoWhenOutputIsAvailable((inp, outp) => { targets.Add(outp); }); }
protected virtual IDisposable SynchronizeRTLCollections(SynchronizationComputation <TRight, TLeft> computation, ICollection <TDepLeft> lefts, ICollection <TDepRight> rights, ISynchronizationContext context, bool ignoreCandidates) { if (lefts != null) { if (lefts.IsReadOnly) { throw new InvalidOperationException("Collection is read-only!"); } IEnumerable <TDepLeft> leftsSaved = lefts; if (rights == null || context.Direction == SynchronizationDirection.RightToLeftForced) { leftsSaved = lefts.ToArray(); lefts.Clear(); } var doubles = new HashSet <TDepLeft>(); IEnumerable leftContext = ignoreCandidates ? null : lefts; foreach (var item in rights) { var comp = context.CallTransformation(childRule.RightToLeft, new object[] { item }, leftContext) as SynchronizationComputation <TDepRight, TDepLeft>; comp.DoWhenOutputIsAvailable((inp, outp) => { if (!lefts.Contains(outp)) { lefts.Add(outp); } else { doubles.Add(outp); } }); } if (context.Direction == SynchronizationDirection.RightWins) { foreach (var item in leftsSaved.Except(doubles)) { AddCorrespondingToRights(rights, context, item); } } return(RegisterRightChangePropagationHooks(lefts, rights, context)); } else { throw new NotSupportedException("Target collection must not be null!"); } }
protected virtual IDisposable SynchronizeCollections(IEnumerable <TSourceDep> source, ICollection <TTargetDep> targets, ISynchronizationContext context, bool ignoreCandidates) { if (targets != null) { if (targets.IsReadOnly) { throw new InvalidOperationException("Collection is read-only!"); } IEnumerable <TTargetDep> rightsSaved = targets; if (source == null || (context.Direction == SynchronizationDirection.LeftToRightForced || context.Direction == SynchronizationDirection.RightToLeftForced)) { rightsSaved = targets.ToArray(); targets.Clear(); } var doubles = new HashSet <TTargetDep>(); IEnumerable rightContext = ignoreCandidates ? null : targets; foreach (var item in source) { var comp = (SynchronizationComputation <TSourceDep, TTargetDep>)context.CallTransformation(childRule, new object[] { item }, rightContext); comp.DoWhenOutputIsAvailable((inp, outp) => { if (!targets.Contains(outp)) { targets.Add(outp); } else { doubles.Add(outp); } }); } return(RegisterChangePropagationHooks(source, targets, context)); } else { throw new NotSupportedException("Target collection must not be null!"); } }