| File: Model\PackageSearchMetadataBuilder.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Protocol\NuGet.Protocol.csproj (NuGet.Protocol) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #nullable disable using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using NuGet.Common; using NuGet.Packaging; using NuGet.Packaging.Core; namespace NuGet.Protocol.Core.Types { /// <summary> /// Helper class allowing creation/alteration of immutable package metadata objects. /// </summary> public class PackageSearchMetadataBuilder { private readonly IPackageSearchMetadata _metadata; private AsyncLazy<IEnumerable<VersionInfo>> _lazyVersionsFactory; private AsyncLazy<PackageDeprecationMetadata> _lazyDeprecationFactory; public class ClonedPackageSearchMetadata : IPackageSearchMetadata { private static readonly AsyncLazy<IEnumerable<VersionInfo>> LazyEmptyVersionInfo = AsyncLazy.New(Enumerable.Empty<VersionInfo>()); private static readonly AsyncLazy<PackageDeprecationMetadata> LazyNullDeprecationMetadata = AsyncLazy.New((PackageDeprecationMetadata)null); public string Authors { get; set; } public IEnumerable<PackageDependencyGroup> DependencySets { get; set; } public string Description { get; set; } public long? DownloadCount { get; set; } public Uri IconUrl { get; set; } public PackageIdentity Identity { get; set; } public Uri LicenseUrl { get; set; } public IReadOnlyList<string> OwnersList { get; set; } public string Owners { get; set; } public Uri ProjectUrl { get; set; } public DateTimeOffset? Published { get; set; } public Uri ReadmeUrl { get; set; } public string ReadmeFileUrl { get; set; } public Uri ReportAbuseUrl { get; set; } public Uri PackageDetailsUrl { get; set; } public bool RequireLicenseAcceptance { get; set; } public string Summary { get; set; } public string Tags { get; set; } public string Title { get; set; } public bool PrefixReserved { get; set; } public LicenseMetadata LicenseMetadata { get; set; } internal AsyncLazy<IEnumerable<VersionInfo>> LazyVersionsFactory { get; set; } public async Task<IEnumerable<VersionInfo>> GetVersionsAsync() => await (LazyVersionsFactory ?? LazyEmptyVersionInfo); internal AsyncLazy<PackageDeprecationMetadata> LazyDeprecationFactory { get; set; } public async Task<PackageDeprecationMetadata> GetDeprecationMetadataAsync() => await (LazyDeprecationFactory ?? LazyNullDeprecationMetadata); public IEnumerable<PackageVulnerabilityMetadata> Vulnerabilities { get; set; } public bool IsListed { get; set; } [Obsolete("PackagePath is recommended in place of PackageReader")] public Func<PackageReaderBase> PackageReader { get; set; } public string PackagePath { get; set; } internal void CacheStrings(MetadataReferenceCache cache) { Authors = cache.GetString(Authors); Description = cache.GetString(Description); Owners = cache.GetString(Owners); ReadmeFileUrl = cache.GetString(ReadmeFileUrl); Summary = cache.GetString(Summary); Tags = cache.GetString(Tags); Title = cache.GetString(Title); PackagePath = cache.GetString(PackagePath); } } private PackageSearchMetadataBuilder(IPackageSearchMetadata metadata) { if (metadata == null) { throw new ArgumentNullException(nameof(metadata)); } _metadata = metadata; } public PackageSearchMetadataBuilder WithVersions(AsyncLazy<IEnumerable<VersionInfo>> lazyVersionsFactory) { _lazyVersionsFactory = lazyVersionsFactory; return this; } public PackageSearchMetadataBuilder WithDeprecation(AsyncLazy<PackageDeprecationMetadata> lazyDeprecationFactory) { _lazyDeprecationFactory = lazyDeprecationFactory; return this; } public IPackageSearchMetadata Build() { var clonedMetadata = new ClonedPackageSearchMetadata { Authors = _metadata.Authors, DependencySets = _metadata.DependencySets ?? Enumerable.Empty<PackageDependencyGroup>(), Description = _metadata.Description, DownloadCount = _metadata.DownloadCount, IconUrl = _metadata.IconUrl, Identity = _metadata.Identity, LicenseUrl = _metadata.LicenseUrl, OwnersList = _metadata.OwnersList, Owners = _metadata.Owners, ProjectUrl = _metadata.ProjectUrl, Published = _metadata.Published, ReadmeUrl = _metadata.ReadmeUrl, ReadmeFileUrl = _metadata.ReadmeFileUrl, ReportAbuseUrl = _metadata.ReportAbuseUrl, PackageDetailsUrl = _metadata.PackageDetailsUrl, RequireLicenseAcceptance = _metadata.RequireLicenseAcceptance, Summary = _metadata.Summary, Tags = _metadata.Tags, Title = _metadata.Title, LazyVersionsFactory = _lazyVersionsFactory, IsListed = _metadata.IsListed, PrefixReserved = _metadata.PrefixReserved, LicenseMetadata = _metadata.LicenseMetadata, LazyDeprecationFactory = _lazyDeprecationFactory ?? AsyncLazy.New(_metadata.GetDeprecationMetadataAsync), Vulnerabilities = _metadata.Vulnerabilities, #pragma warning disable CS0618 // Type or member is obsolete PackageReader = (_metadata as LocalPackageSearchMetadata)?.PackageReader ?? (_metadata as ClonedPackageSearchMetadata)?.PackageReader, #pragma warning restore CS0618 // Type or member is obsolete PackagePath = (_metadata as LocalPackageSearchMetadata)?.PackagePath ?? (_metadata as ClonedPackageSearchMetadata)?.PackagePath, }; return clonedMetadata; } public static PackageSearchMetadataBuilder FromMetadata(IPackageSearchMetadata metadata) => new PackageSearchMetadataBuilder(metadata); public static PackageSearchMetadataBuilder FromIdentity(PackageIdentity identity) { var metadata = new ClonedPackageSearchMetadata { Identity = identity, Title = identity.Id, Summary = string.Empty, Authors = string.Empty }; return FromMetadata(metadata); } } /// <summary> /// Shortcut methods to create altered metadata objects with new versions. /// </summary> public static class PackageSearchMetadataExtensions { public static IPackageSearchMetadata WithVersions(this IPackageSearchMetadata metadata, IEnumerable<VersionInfo> versions) { return PackageSearchMetadataBuilder .FromMetadata(metadata) .WithVersions(AsyncLazy.New(versions)) .Build(); } public static IPackageSearchMetadata WithVersions(this IPackageSearchMetadata metadata, Func<Task<IEnumerable<VersionInfo>>> asyncValueFactory) { return PackageSearchMetadataBuilder .FromMetadata(metadata) .WithVersions(AsyncLazy.New(asyncValueFactory)) .Build(); } public static IPackageSearchMetadata WithVersions(this IPackageSearchMetadata metadata, Func<IEnumerable<VersionInfo>> valueFactory) { return PackageSearchMetadataBuilder .FromMetadata(metadata) .WithVersions(AsyncLazy.New(valueFactory)) .Build(); } } }