| File: Settings\TemplateInfoReader.cs | Web Access |
| Project: src\sdk\src\TemplateEngine\Microsoft.TemplateEngine.Edge\Microsoft.TemplateEngine.Edge.csproj (Microsoft.TemplateEngine.Edge) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Nodes; using System.Text.Json.Serialization; using Microsoft.TemplateEngine.Abstractions; using Microsoft.TemplateEngine.Abstractions.Constraints; using Microsoft.TemplateEngine.Abstractions.Parameters; using Microsoft.TemplateEngine.Utils; namespace Microsoft.TemplateEngine.Edge.Settings { internal partial class TemplateInfo { internal class TemplateInfoReader { internal static TemplateInfo FromJObject(JsonObject entry) { string identity = entry.ToString(nameof(Identity)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(Identity)} property.", nameof(entry)); string name = entry.ToString(nameof(Name)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(Name)} property.", nameof(entry)); string mountPointUri = entry.ToString(nameof(MountPointUri)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(MountPointUri)} property.", nameof(entry)); string configPlace = entry.ToString(nameof(ConfigPlace)) ?? throw new ArgumentException($"{nameof(entry)} doesn't have {nameof(ConfigPlace)} property.", nameof(entry)); JsonNode? shortNameToken = entry.Get<JsonNode>(nameof(ShortNameList)); IEnumerable<string> shortNames = shortNameToken.JTokenStringOrArrayToCollection([]); TemplateInfo info = new TemplateInfo(identity, name, shortNames, mountPointUri, configPlace) { Author = entry.ToString(nameof(Author)) }; JsonArray? classificationsArray = entry.Get<JsonArray>(nameof(Classifications)); if (classificationsArray != null) { List<string> classifications = new List<string>(); foreach (JsonNode? item in classificationsArray) { if (item != null) { classifications.Add(item.GetValue<string>()); } } info.Classifications = classifications; } info.DefaultName = entry.ToString(nameof(DefaultName)); info.PreferDefaultName = entry.ToBool(nameof(PreferDefaultName)); info.Description = entry.ToString(nameof(Description)); info.GeneratorId = Guid.Parse(entry.ToString(nameof(GeneratorId))); info.GroupIdentity = entry.ToString(nameof(GroupIdentity)); info.Precedence = entry.ToInt32(nameof(Precedence)); info.LocaleConfigPlace = entry.ToString(nameof(LocaleConfigPlace)); info.HostConfigPlace = entry.ToString(nameof(HostConfigPlace)); info.ThirdPartyNotices = entry.ToString(nameof(ThirdPartyNotices)); JsonObject? baselineJObject = entry.Get<JsonObject>(nameof(ITemplateInfo.BaselineInfo)); Dictionary<string, IBaselineInfo> baselineInfo = new Dictionary<string, IBaselineInfo>(); if (baselineJObject != null) { foreach (var item in baselineJObject) { var defaultOverrides = item.Value?.ToStringDictionary(propertyName: nameof(IBaselineInfo.DefaultOverrides)); if (defaultOverrides is null) { continue; } IBaselineInfo baseline = new BaselineInfo(defaultOverrides, item.Value.ToString(nameof(IBaselineInfo.Description))); baselineInfo.Add(item.Key, baseline); } info.BaselineInfo = baselineInfo; } //read parameters #pragma warning disable CS0618 // Type or member is obsolete JsonArray? parametersArray = entry.Get<JsonArray>(nameof(Parameters)); #pragma warning restore CS0618 // Type or member is obsolete if (parametersArray != null) { List<ITemplateParameter> templateParameters = new List<ITemplateParameter>(); foreach (JsonNode? item in parametersArray) { if (item is JsonObject jObj) { templateParameters.Add(ParameterFromJObject(jObj)); } } info.ParameterDefinitions = new ParameterDefinitionSet(templateParameters); } //read tags // tags are just "name": "description" // e.g.: "language": "C#" JsonObject? tagsObject = entry.Get<JsonObject>(nameof(TagsCollection)); if (tagsObject != null) { Dictionary<string, string> tags = new Dictionary<string, string>(); foreach (var item in tagsObject) { tags.Add(item.Key, item.Value?.GetValue<string>() ?? string.Empty); } info.TagsCollection = tags; } info.HostData = entry.ToString(nameof(info.HostData)); JsonArray? postActionsArray = entry.Get<JsonArray>(nameof(info.PostActions)); if (postActionsArray != null) { List<Guid> postActions = new List<Guid>(); foreach (JsonNode? item in postActionsArray) { if (item != null && Guid.TryParse(item.GetValue<string>(), out Guid id)) { postActions.Add(id); } } info.PostActions = postActions; } //read parameters JsonArray? constraintsArray = entry.Get<JsonArray>(nameof(info.Constraints)); if (constraintsArray != null) { List<TemplateConstraintInfo> constraints = new List<TemplateConstraintInfo>(); foreach (JsonNode? item in constraintsArray) { string? type = item.ToString(nameof(TemplateConstraintInfo.Type)); if (string.IsNullOrWhiteSpace(type)) { throw new ArgumentException($"{nameof(entry)} has {nameof(info.Constraints)} property which item doesn't have {nameof(TemplateConstraintInfo.Type)}.", nameof(entry)); } constraints.Add(new TemplateConstraintInfo(type!, item.ToString(nameof(TemplateConstraintInfo.Args)))); } info.Constraints = constraints; } return info; } /// <summary> /// Parses <see cref="ITemplateParameter"/> from <see cref="JsonObject"/>. /// </summary> /// <param name="jObject"></param> private static ITemplateParameter ParameterFromJObject(JsonObject jObject) { string? name = jObject.ToString(nameof(ITemplateParameter.Name)); if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException($"{nameof(ITemplateParameter.Name)} property should not be null or whitespace", nameof(jObject)); } string type = jObject.ToString(nameof(ITemplateParameter.Type)) ?? "parameter"; string dataType = jObject.ToString(nameof(ITemplateParameter.DataType)) ?? "string"; string? description = jObject.ToString(nameof(ITemplateParameter.Description)); string? defaultValue = jObject.ToString(nameof(ITemplateParameter.DefaultValue)); string? defaultIfOptionWithoutValue = jObject.ToString(nameof(ITemplateParameter.DefaultIfOptionWithoutValue)); string? displayName = jObject.ToString(nameof(ITemplateParameter.DisplayName)); bool isName = jObject.ToBool(nameof(ITemplateParameter.IsName)); bool allowMultipleValues = jObject.ToBool(nameof(ITemplateParameter.AllowMultipleValues)); Dictionary<string, ParameterChoice>? choices = null; if (dataType.Equals("choice", StringComparison.OrdinalIgnoreCase)) { choices = new Dictionary<string, ParameterChoice>(StringComparer.OrdinalIgnoreCase); JsonObject? cdToken = jObject.Get<JsonObject>(nameof(ITemplateParameter.Choices)); if (cdToken != null) { foreach (var cdPair in cdToken) { choices.Add( cdPair.Key, new ParameterChoice( cdPair.Value.ToString(nameof(ParameterChoice.DisplayName)), cdPair.Value.ToString(nameof(ParameterChoice.Description)))); } } } TemplateParameterPrecedence precedence = jObject.ToTemplateParameterPrecedence(nameof(ITemplateParameter.Precedence)); return new CacheTemplateParameter( new TemplateParameter(name!, type, dataType) { DisplayName = displayName, Precedence = precedence, IsName = isName, DefaultValue = defaultValue, DefaultIfOptionWithoutValue = defaultIfOptionWithoutValue, Description = description, AllowMultipleValues = allowMultipleValues, Choices = choices }); } /// <summary> /// This class is overload on <see cref="ITemplateParameter"/> controlling JSON serialization for template parameters in cache. /// Not all the members are required to be serialized. /// </summary> private class CacheTemplateParameter : ITemplateParameter { private readonly ITemplateParameter _parameter; internal CacheTemplateParameter(ITemplateParameter parameter) { _parameter = parameter; } public string? Description => _parameter.Description; [JsonPropertyName("Name")] public string Name => _parameter.Name; [JsonPropertyName("Precedence")] public TemplateParameterPrecedence Precedence => _parameter.Precedence; [JsonPropertyName("Type")] public string Type => _parameter.Type; [JsonPropertyName("IsName")] public bool IsName => _parameter.IsName; [JsonPropertyName("DefaultValue")] public string? DefaultValue => _parameter.DefaultValue; [JsonPropertyName("DefaultIfOptionWithoutValue")] public string? DefaultIfOptionWithoutValue => _parameter.DefaultIfOptionWithoutValue; [JsonPropertyName("DataType")] public string DataType => _parameter.DataType; [JsonPropertyName("Choices")] public IReadOnlyDictionary<string, ParameterChoice>? Choices => _parameter.Choices; [JsonPropertyName("DisplayName")] public string? DisplayName => _parameter.DisplayName; [JsonPropertyName("AllowMultipleValues")] public bool AllowMultipleValues => _parameter.AllowMultipleValues; [Obsolete] [JsonIgnore] public TemplateParameterPriority Priority => _parameter.Priority; [Obsolete] [JsonIgnore] public string? Documentation => _parameter.Documentation; public bool Equals(ITemplateParameter other) => _parameter.Equals(other); } } } }