private IEnumerable <ID> DoGetChildIDs(ItemDefinition itemDefinition, CallContext context)
        {
            var headChildIDs = HeadProvider
                               .GetChildIDs(itemDefinition, context)?
                               .Cast <ID>().ToArray() ?? EmptyIds;

            var readOnlyChildIDs = ReadOnlyProviders
                                   .SelectMany(x => x
                                               .GetChildIDs(itemDefinition)?
                                               .Select(ID.Parse) ?? EmptyIds);

            var childIDs = headChildIDs.Concat(readOnlyChildIDs)         // .Join()
                           .GroupBy(x => x.Guid).Select(x => x.First()); // .Distinct()

            // deleted or moved out items must be get off the list
            var itemId = itemDefinition.ID;

            foreach (var childID in childIDs)
            {
                var parentId = HeadProvider.GetParentID(new ItemDefinition(childID, string.Empty, ID.Null, ID.Null), context);
                if (ReferenceEquals(parentId, null) || parentId == itemId)
                {
                    yield return(childID);
                }
            }
        }
Esempio n. 2
0
        public override bool DeleteItem(ItemDefinition itemDefinition, CallContext context)
        {
#if DEBUG
            var timer = Stopwatch.StartNew();
#endif

            // check if already deleted in head
            var headParentId = HeadProvider.GetParentID(itemDefinition, context);
            if (headParentId == ID.Undefined)
            {
#if DEBUG
                this.Trace(true, timer, itemDefinition.ID, context);
#endif
                return(true);
            }

            var itemId = itemDefinition.ID;
            if (ReadOnlyProviders.FirstNotNull(x => x.GetItemDefinition(itemId)) == null)
            {
                // item may only exist in head provider
                // so we can simply delete it

                var deleted = HeadProvider.DeleteItem(itemDefinition, context);

#if DEBUG
                this.Trace(deleted, timer, itemDefinition.ID, context);
#endif
                return(deleted);
            }

            if (HeadProvider.GetItemDefinition(itemId, context) != null)
            {
                // item exists both in read-only data provider and in HEAD
                // so we first delete it in HEAD

                HeadProvider.DeleteItem(itemDefinition, context);

                // and pretend it was only in read-only data provider
            }

            // item only exists in read-only data provider
            // so we create item definition beneath undefied parent

            var deleted2 = CreateItem(itemId, itemDefinition.Name, itemDefinition.TemplateID, new ItemDefinition(ID.Undefined, "undefined", ID.Null, ID.Null), context);

#if DEBUG
            this.Trace(deleted2, timer, itemDefinition.ID, context);
#endif

            return(deleted2);
        }
        public override ID GetParentID(ItemDefinition itemDefinition, CallContext context)
        {
#if DEBUG
            var timer = Stopwatch.StartNew();
#endif

            var parentId = HeadProvider.GetParentID(itemDefinition, context)
                           ?? ReadOnlyProviders.FirstNotNull(x => x.GetParentID(itemDefinition));

#if DEBUG
            this.Trace(parentId, timer, itemDefinition, context);
#endif

            return(parentId);
        }
        private ID ResolvePath(ID parentId, string[] pathSegments, int segmentIndex, CallContext context)
        {
            if (segmentIndex >= pathSegments.Length)
            {
                return(parentId);
            }

            var segmentName = pathSegments[segmentIndex];

            foreach (var provider in ReadOnlyProviders)
            {
                var children = provider.GetChildIdsByName(segmentName, parentId);
                if (children == null)
                {
                    continue;
                }

                foreach (var childId in children)
                {
                    // TODO: refactor that in kernel
                    var headParentId = HeadProvider.GetParentID(new ItemDefinition(childId, "--fake--", ID.Null, ID.Null), context);
                    if (headParentId != (ID)null && headParentId != parentId)
                    {
                        continue;
                    }

                    var pathId = ResolvePath(childId, pathSegments, segmentIndex + 1, context);
                    if (pathId == (ID)null)
                    {
                        continue;
                    }

                    return(pathId);
                }
            }

            return(ResolveHeadPath(parentId, pathSegments, segmentIndex, context));
        }