in JetBrains.SbomUtils/src/JetBrains.SbomUtils/SbomReader.cs [60:121]
public SbomModel LoadSbom(SpdxDocument spdxDocument)
{
var packagesDict = spdxDocument.Packages!.ToDictionary(p => p.SPDXID);
var filesDict = spdxDocument.Files!.ToDictionary(f => f.SPDXID);
var relationshipsBySourceElement = new Dictionary<string, List<Relationship>>();
var relationshipsByDestinationElement = new Dictionary<string, List<Relationship>>();
foreach (var relationship in spdxDocument.Relationships!)
{
if (relationshipsBySourceElement.TryGetValue(relationship.SpdxElementId, out var relationshipsBySourceList))
relationshipsBySourceList.Add(relationship);
else
relationshipsBySourceElement.Add(relationship.SpdxElementId, new List<Relationship>() { relationship });
if (relationshipsByDestinationElement.TryGetValue(relationship.RelatedSpdxElement,
out var relationshipsByDestinationList))
relationshipsByDestinationList.Add(relationship);
else
relationshipsByDestinationElement.Add(relationship.RelatedSpdxElement,
new List<Relationship>() { relationship });
}
var filesDictionaryByRelativePath = new Dictionary<string, List<FileInfo>>();
var filesDictionaryByFileName = new Dictionary<string, List<FileInfo>>();
var files = GetAllFilesWithPackages(filesDict, packagesDict, relationshipsBySourceElement,
relationshipsByDestinationElement);
foreach (var file in files)
{
string temp = Path.GetTempPath();
string fullPath = Path.GetRelativePath(temp, Path.GetFullPath(file.File.FileName, temp));
string filename = Path.GetFileName(file.File.FileName);
if (filesDictionaryByRelativePath.TryGetValue(fullPath, out var existingFile))
existingFile.Add(file);
else
filesDictionaryByRelativePath.Add(fullPath, new List<FileInfo>(2) { file });
if (filesDictionaryByFileName.TryGetValue(filename, out var existingFiles))
existingFiles.Add(file);
else
filesDictionaryByFileName.Add(filename, new List<FileInfo>() { file });
}
foreach (var file in filesDictionaryByRelativePath)
{
if (file.Value.Count > 1)
_logger.LogDebug("File {file} has duplicates in {count} following packages:\n {packages}", file.Key,
file.Value.Count, string.Join("\n ", file.Value.Select(v => v.Package.Name)));
}
var sbomModel = new SbomModel(
spdxDocument,
new ReadOnlyDictionary<string, Package>(packagesDict),
new ReadOnlyDictionary<string, File>(filesDict),
new ReadOnlyDictionary<string, List<Relationship>>(relationshipsBySourceElement),
new ReadOnlyDictionary<string, List<Relationship>>(relationshipsByDestinationElement),
new ReadOnlyDictionary<string, List<FileInfo>>(filesDictionaryByRelativePath),
new ReadOnlyDictionary<string, List<FileInfo>>(filesDictionaryByFileName));
return sbomModel;
}