Ejemplo n.º 1
0
        public async Task <IEnumerable <SubArtifact> > GetSubArtifactTreeAsync(int artifactId, int userId, int revisionId = int.MaxValue, bool includeDrafts = true)
        {
            var subArtifactsDictionary = (await GetSubArtifacts(artifactId, userId, revisionId, includeDrafts)).ToDictionary(a => a.Id);
            var itemIds = subArtifactsDictionary.Select(a => a.Key).ToList();
            var itemDetailsDictionary = (await _itemInfoRepository.GetItemsDetails(userId, itemIds, true, int.MaxValue)).ToDictionary(a => a.HolderId);

            foreach (var subArtifactEntry in subArtifactsDictionary)
            {
                var         subArtifact         = subArtifactEntry.Value;
                var         parentSubArtifactId = subArtifact.ParentId;
                SubArtifact parentSubArtifact;
                if (parentSubArtifactId != artifactId && subArtifactsDictionary.TryGetValue(parentSubArtifactId, out parentSubArtifact))
                {
                    if (parentSubArtifact.Children == null)
                    {
                        parentSubArtifact.Children = new List <SubArtifact>();
                    }
                    ((List <SubArtifact>)parentSubArtifact.Children).Add(subArtifact);
                    parentSubArtifact.HasChildren = true;
                }
                ItemDetails itemDetails;
                if (itemDetailsDictionary != null && itemDetailsDictionary.TryGetValue(subArtifact.Id, out itemDetails))
                {
                    subArtifactEntry.Value.Prefix = itemDetails.Prefix;
                }
                subArtifact.ArtifactId = artifactId;
            }
            var isUseCase = subArtifactsDictionary.Any() && (subArtifactsDictionary.ElementAt(0).Value.PredefinedType == ItemTypePredefined.PreCondition ||
                                                             subArtifactsDictionary.ElementAt(0).Value.PredefinedType == ItemTypePredefined.PostCondition ||
                                                             subArtifactsDictionary.ElementAt(0).Value.PredefinedType == ItemTypePredefined.Flow ||
                                                             subArtifactsDictionary.ElementAt(0).Value.PredefinedType == ItemTypePredefined.Step);

            if (isUseCase)
            {
                var itemLabelsDictionary = (await _itemInfoRepository.GetItemsLabels(userId, itemIds)).ToDictionary(a => a.ItemId);
                foreach (var subArtifactEntry in subArtifactsDictionary)
                {
                    // filter out flow subartifacts and append children of flow to children of flow's parent.
                    if (subArtifactEntry.Value.PredefinedType == ItemTypePredefined.Flow)
                    {
                        SubArtifact parent;
                        var         children = subArtifactEntry.Value.Children;
                        if (subArtifactsDictionary.TryGetValue(subArtifactEntry.Value.ParentId, out parent))
                        {
                            ((List <SubArtifact>)parent.Children).Remove(subArtifactEntry.Value);
                            ((List <SubArtifact>)parent.Children).AddRange(children);
                        }
                    }
                    // populate label as display names.
                    ItemLabel itemLabel;
                    if (itemLabelsDictionary != null && itemLabelsDictionary.TryGetValue(subArtifactEntry.Value.Id, out itemLabel))
                    {
                        subArtifactEntry.Value.DisplayName = itemLabel.Label;
                    }
                }
            }
            var result = subArtifactsDictionary.Where(a => a.Value.ParentId == artifactId).Select(b => b.Value);

            return(result);
        }
        public async Task <RelationshipResultSet> GetRelationships(
            int artifactId,
            int userId,
            int?subArtifactId = null,
            bool addDrafts    = true,
            bool allLinks     = false,
            int?versionId     = null,
            int?baselineId    = null)
        {
            var revisionId = await _itemInfoRepository.GetRevisionId(artifactId, userId, versionId, baselineId);

            var itemId = subArtifactId ?? artifactId;
            var types  = new List <int> {
                (int)LinkType.Manual,
                (int)LinkType.Association,
                (int)LinkType.ActorInheritsFrom,
                (int)LinkType.DocumentReference
            };

            if (allLinks)
            {
                types.AddRange(new[] { (int)LinkType.ParentChild, (int)LinkType.Reuse });
            }

            if (baselineId != null)
            {
                addDrafts = false;
            }

            var results     = (await GetLinkInfo(itemId, userId, addDrafts, revisionId, types)).ToList();
            var manualLinks = results.Where(a => a.LinkType == LinkType.Manual).ToList();
            // filter out Parent/Child links between artifact and its subartifact if exist
            var excludeParentChildLinks = results.Where(link =>
                                                        link.LinkType == LinkType.ParentChild &&
                                                        ((link.SourceArtifactId != link.SourceItemId || link.DestinationArtifactId != link.DestinationItemId)) || ////internal links
                                                        (link.SourceItemId == link.SourceProjectId))                                                              ////to artifact's project
                                          .ToList();
            // get reuse links to to modify them separaratly.
            var reuseLinks = results.Where(a => a.LinkType == LinkType.Reuse).ToList();
            // get collection of other links exept exclude parent/child links and reuse links
            var otherLinks = results.Except(excludeParentChildLinks).Except(reuseLinks).Where(link => link.LinkType != LinkType.Manual).ToList();

            // modify reuse links by combining matching pais (source match destination on other) and add them back to coolection of otherlinks
            otherLinks.AddRange(UpdateReuseLinks(reuseLinks, itemId));

            var manualTraceRelationships = GetManualTraceRelationships(manualLinks, itemId);
            var otherTraceRelationships  = new List <Relationship>();

            foreach (var otherLink in otherLinks)
            {
                var          traceDirection = otherLink.SourceItemId == itemId ? TraceDirection.To : TraceDirection.From;
                Relationship relationship   = null;
                if (otherLink.LinkType == LinkType.ActorInheritsFrom)
                {
                    var itemInfo = await _artifactPermissionsRepository.GetItemInfo(otherLink.DestinationArtifactId, userId, addDrafts, revisionId);

                    if (itemInfo != null)
                    {
                        relationship = ComposeRelationship(otherLink, traceDirection);
                    }
                }
                else if (otherLink.LinkType == LinkType.Reuse)
                {
                    traceDirection = TraceDirection.TwoWay;
                    var itemInfo = await _artifactPermissionsRepository.GetItemInfo(otherLink.DestinationArtifactId, userId, addDrafts, revisionId);

                    if (itemInfo != null)
                    {
                        relationship = ComposeRelationship(otherLink, traceDirection);
                    }
                }
                else
                {
                    relationship = ComposeRelationship(otherLink, traceDirection);
                }
                if (relationship != null)
                {
                    otherTraceRelationships.Add(relationship);
                }
            }

            var distinctItemIds = new HashSet <int>();

            foreach (var result in results)
            {
                distinctItemIds.Add(result.SourceArtifactId);
                distinctItemIds.Add(result.DestinationArtifactId);
                distinctItemIds.Add(result.SourceItemId);
                distinctItemIds.Add(result.DestinationItemId);
                distinctItemIds.Add(result.SourceProjectId);
                distinctItemIds.Add(result.DestinationProjectId);
            }

            var itemDetailsDictionary = (await _itemInfoRepository.GetItemsDetails(userId, distinctItemIds, true, revisionId)).ToDictionary(a => a.HolderId);
            var itemLabelsDictionary  = (await _itemInfoRepository.GetItemsLabels(userId, distinctItemIds, true, revisionId)).ToDictionary(a => a.ItemId);

            PopulateRelationshipInfos(manualTraceRelationships, itemDetailsDictionary, itemLabelsDictionary);
            PopulateRelationshipInfos(otherTraceRelationships, itemDetailsDictionary, itemLabelsDictionary);
            return(new RelationshipResultSet
            {
                RevisionId = revisionId,
                ManualTraces = manualTraceRelationships,
                OtherTraces = otherTraceRelationships
            });
        }