private void SetTreeScopeIdErrors()
        {
            if (!TreeIdMap.Contains(Id))
            {
                TreeIdMap.Add(Id);
                return;
            }

            var duplicates = Root.Where(n => n.HasEquivalentId(Id));

            duplicates.ForEach(dup => dup.Error |= IdentityError.TreeScopeIdDuplicate);
        }
Example #2
0
        protected sealed override void SetChildErrorsOnAttachment()
        {
            if (CheckOptions.HasFlag(ErrorCheckOptions.CyclicIdDuplicates))
            {
                SetChildCyclicIdErrorsOnAttachment();
            }

            if (CheckOptions.HasFlag(ErrorCheckOptions.SiblingAliasDuplicates))
            {
                SetChildSiblingAliasErrorsOnAttachment();
            }

            ILookup <TId, TNode> nodesGroupedById = null;

            if (CheckOptions.HasFlag(ErrorCheckOptions.SiblingIdDuplicates))
            {
                nodesGroupedById = Children.ToLookup(c => c.Id, Definition.IdEqualityComparer);

                var siblingDuplicateIdNodes =
                    nodesGroupedById
                    .Where(grp => grp.Count() > 1)
                    .SelectMany(n => n);

                siblingDuplicateIdNodes.ForEach(n => n.Error |= IdentityError.SiblingIdDuplicate);
            }

            if (!IdentityTrackingIsTreeScope)
            {
                return;
            }

            nodesGroupedById = nodesGroupedById ?? Children.ToLookup(c => c.Id, Definition.IdEqualityComparer);

            var duplicateNodeIds =
                from grp in nodesGroupedById
                let hasBeenRegistered = TreeIdMap.Contains(grp.Key)
                                        where hasBeenRegistered
                                        select grp.Key;

            var treeScopeIdDuplicateNodes =
                from node in Root
                where duplicateNodeIds.Contains(node.Id)
                select node;

            treeScopeIdDuplicateNodes.ForEach(n => n.Error |= IdentityError.TreeScopeIdDuplicate);

            nodesGroupedById.ForEach(grp => TreeIdMap.Add(grp.Key));
        }
        private void UpdateTreeScopeIdErrorsBeforeDetachingThis()
        {
            var treeIdGroups = Root.ToLookup(n => n.Id);

            foreach (var grp in treeIdGroups)
            {
                var id = grp.Key;

                var enumerated = grp.ToArray();
                var insiders   = enumerated.Where(n => n.Equals(This) || n.IsDescendantOf(This)).ToArray();

                if (insiders.Length == 0)
                {
                    continue;
                }

                if (enumerated.Length == insiders.Length)
                {
                    TreeIdMap.Remove(id);
                    continue;
                }

                var outsiders = enumerated.Except(insiders).ToArray();

                if (outsiders.Length == 1)
                {
                    outsiders[0].Error &= ~IdentityError.TreeScopeIdDuplicate;
                }

                if (insiders.Length == 1)
                {
                    insiders[0].Error &= ~IdentityError.TreeScopeIdDuplicate;
                }
            }

            TreeIdMap = new HashSet <TId>(Definition.IdEqualityComparer);
            this.Select(n => n.Id).ForEach(id => TreeIdMap.Add(id));
        }