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 }); }