public override Element Apply(Difference difference)
        {
            if (difference == null)
                throw new ArgumentNullException("difference");
            if (!difference.Identifier.Equals(this.Identifier))
                throw new MergeException("Cannot apply a difference that does not share the same identifier with the element.");

            if (difference is NodeDifference)
            {
                var mergedChilds = new ElementHashList(r_childs);
                foreach (var subdifference in ((NodeDifference)difference).Subdifferences)
                {
                    switch (subdifference.OperationOnParent)
                    {
                        case OperationOnParent.Added:
                            mergedChilds.Add(subdifference.Identifier.CreateEmptyElement().Apply(subdifference));
                            break;
                        case OperationOnParent.Modified:
                            mergedChilds.AddOrUpdate(mergedChilds[subdifference.Identifier].Apply(subdifference));
                            break;
                        case OperationOnParent.Removed:
                            mergedChilds.Remove(subdifference.Identifier);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException("subdifference.OperationOnParent", subdifference.OperationOnParent, "Invalid value");
                    }
                }
                return new NodeElement(this.Identifier, mergedChilds);
            }
            else
            {
                throw new MergeException(string.Format("Cannot apply a {0} on a {1}.", difference.GetType().Name, this.GetType().Name));
            }
        }
        public override Conflict CompareTo(Difference destinationDifference)
        {
            if (destinationDifference == null)
                throw new ArgumentNullException("destinationDifference");
            if (!destinationDifference.Identifier.Equals(this.Identifier))
                throw new MergeException("Cannot compare differences that does not share the same identifier.");

            var source = this;
            var destination = destinationDifference as ValueDifference;
            if (destination == null)
                throw new MergeException(string.Format("Cannot compare a {0} to a {1}.", destinationDifference.GetType().Name, this.GetType().Name));
            if (source.OldValue != destination.OldValue)
                throw new MergeException("Cannot compare value differences that does not share the same 'OldValue'.");

            if (source.OperationOnParent != destination.OperationOnParent)
            {
                return new OperationTypeConflict(
                            source,
                            destination);
            }
            else if (source.NewValue != destination.NewValue)
            {
                return new ValueConflict(
                            source.Identifier,
                            source.OperationOnParent,
                            source.OldValue,
                            source.NewValue,
                            destination.NewValue);
            }
            else
            {
                return null;
            }
        }
        public override Element Apply(Difference difference)
        {
            if (difference == null)
                throw new ArgumentNullException("difference");
            if (!difference.Identifier.Equals(this.Identifier))
                throw new MergeException("Cannot apply a difference that does not share the same identifier with the element.");

            if (difference is ValueDifference)
            {
                if (difference.OperationOnParent == OperationOnParent.Removed)
                    throw new MergeException("Cannot apply a 'remove' difference on a ValueElement.");
                return new ValueElement(
                            this.Identifier,
                            ((ValueDifference)difference).NewValue);
            }
            else if (difference is NodeDifference)
            {
                var emptyNodeElement = new NodeElement(this.Identifier, null);
                return emptyNodeElement.Apply(difference);
            }
            else
            {
                throw new MergeException(string.Format("Cannot apply a {0} on a {1}.", difference.GetType().Name, this.GetType().Name));
            }
        }
        public override Element Apply(Difference difference)
        {
            if (difference == null)
                throw new ArgumentNullException("difference");
            if (!difference.Identifier.Equals(this.Identifier))
                throw new MergeException("Cannot apply a difference that does not share the same identifier with the element.");

            if (difference is ValueDifference)
            {
                return new ValueElement(
                            this.Identifier,
                            ((ValueDifference)difference).NewValue);
            }
            else
            {
                throw new MergeException(string.Format("Cannot apply a {0} on a {1}.", difference.GetType().Name, this.GetType().Name));
            }
        }
Beispiel #5
0
 public abstract Conflict CompareTo(Difference destinationDifference);
Beispiel #6
0
        public override Conflict CompareTo(Difference destinationDifference)
        {
            if (destinationDifference == null)
                throw new ArgumentNullException("destinationDifference");
            if (!destinationDifference.Identifier.Equals(this.Identifier))
                throw new MergeException("Cannot compare differences that does not share the same identifier.");

            var source = this;
            var destination = destinationDifference as NodeDifference;
            if (destination == null)
                throw new MergeException(string.Format("Cannot compare a {0} to a {1}.", destinationDifference.GetType().Name, this.GetType().Name));

            if (source.OperationOnParent != destination.OperationOnParent)
            {
                return new OperationTypeConflict(
                            source,
                            destination);
            }
            else
            {
                var subconflicts = new List<Conflict>();
                var acceptedSubdifferences = new DifferenceHashList();
                foreach (var destinationSubdifference in destination.Subdifferences)
                {
                    // Add all the destinationBranchDifferences to the acceptedSubdifferences (they might be removed from the list later).
                    acceptedSubdifferences.Add(destinationSubdifference);
                }
                foreach (var sourceSubdifference in source.Subdifferences)
                {
                    if (!acceptedSubdifferences.Contains(sourceSubdifference.Identifier))
                    {
                        // This is a new difference that is not present in the destination branch, add the difference to the acceptedSubdifferences.
                        acceptedSubdifferences.Add(sourceSubdifference);
                    }
                    else
                    {
                        // There is a difference in both branch for the same identifier, see if there is a conflict or not
                        var destinationSubdifference = acceptedSubdifferences[sourceSubdifference.Identifier];
                        var conflict = sourceSubdifference.CompareTo(destinationSubdifference);
                        if (conflict != null)
                        {
                            var nodeConflict = conflict as NodeConflict;
                            if ((nodeConflict != null) && (nodeConflict.Subconflicts.Count == 0))
                            {
                                acceptedSubdifferences.Remove(sourceSubdifference.Identifier);
                                acceptedSubdifferences.Add(
                                            new NodeDifference(
                                                nodeConflict.Identifier,
                                                nodeConflict.OperationOnParent,
                                                nodeConflict.AcceptedSubdifferences));
                            }
                            else
                            {
                                acceptedSubdifferences.Remove(sourceSubdifference.Identifier);
                                subconflicts.Add(conflict);
                            }
                        }
                    }
                }

                return new NodeConflict(
                            source.Identifier,
                            source.OperationOnParent,
                            acceptedSubdifferences,
                            subconflicts);
            }
        }
 public abstract Element Apply(Difference difference);