/// <summary> /// Initializes a new instance of the <see cref="ParameterCollection" /> class. /// </summary> /// <param name="parameterFile">The parent parameter file.</param> /// <param name="parameters">The parameters.</param> /// <exception cref="T:System.ArgumentNullException">parameterFile.</exception> /// <inheritdoc /> public ParameterCollection(SharedParameterFile parameterFile, IEnumerable <ParameterDefinition> parameters) : base(parameters ?? new List <ParameterDefinition>()) { this.parameterFile = parameterFile ?? throw new ArgumentNullException(nameof(parameterFile)); }
/// <summary> /// Extracts <see cref="SharedParameterFile"/> object from a string. /// </summary> /// <param name="sharedParameterText">Text content of shared parameter file.</param> /// <returns>The shared parameter file</returns> /// <exception cref="System.ArgumentException">sharedParameterText</exception> public static SharedParameterFile FromText(string sharedParameterText) { if (string.IsNullOrWhiteSpace(sharedParameterText)) { throw new ArgumentException($"{nameof(sharedParameterText)} must be a non empty string"); } var sharedParamsFileLines = SectionRegex .Split(sharedParameterText) .Where(line => !line.StartsWith("#")) // Exclude comment lines .ToArray(); var sharedParamsFileSections = sharedParamsFileLines .Where((e, i) => i % 2 == 0) .Select((e, i) => new { Key = e, Value = sharedParamsFileLines[i * 2 + 1] }) .ToDictionary(kp => kp.Key, kp => kp.Value.Replace($"{kp.Key}\t", string.Empty)); var sharedParamsFile = new SharedParameterFile(); if (sharedParamsFileSections == null || sharedParamsFileSections.Count < 3 || !(sharedParamsFileSections.ContainsKey(Sections.META) && sharedParamsFileSections.ContainsKey(Sections.GROUPS) && sharedParamsFileSections.ContainsKey(Sections.PARAMS))) { throw new InvalidDataException("Failed to parse shared parameter file content," + "because it doesn't contain enough data for being qualified as a valid shared parameter file."); } foreach (var section in sharedParamsFileSections) { using (var stringReader = new StringReader(section.Value)) { using (var csvReader = new CsvReader(stringReader, CsvConfiguration)) { csvReader.Configuration.TrimOptions = TrimOptions.Trim; // TODO implement // csvReader.Configuration.AllowComments = true; // csvReader.Configuration.Comment = '#'; var originalHeaderValidated = csvReader.Configuration.HeaderValidated; csvReader.Configuration.HeaderValidated = (isValid, headerNames, headerIndex, context) => { // Everything is OK, just go out if (isValid) { return; } // Allow DESCRIPTION header to be missing (it's actually missing in older shared parameter files) if (nameof(Parameter.Description).Equals(headerNames?.FirstOrDefault(), StringComparison.OrdinalIgnoreCase)) { return; } // Allow USERMODIFIABLE header to be missing (it's actually missing in older shared parameter files) if (nameof(Parameter.UserModifiable).Equals(headerNames?.FirstOrDefault(), StringComparison.OrdinalIgnoreCase)) { return; } originalHeaderValidated(false, headerNames, headerIndex, context); }; var originalMissingFieldFound = csvReader.Configuration.MissingFieldFound; csvReader.Configuration.MissingFieldFound = (headerNames, index, context) => { // Allow DESCRIPTION header to be missing (it's actually missing in older shared parameter files) if (nameof(Parameter.Description).Equals(headerNames?.FirstOrDefault(), StringComparison.OrdinalIgnoreCase)) { return; } // Allow USERMODIFIABLE header to be missing (it's actually missing in older shared parameter files) if (nameof(Parameter.UserModifiable).Equals(headerNames?.FirstOrDefault(), StringComparison.OrdinalIgnoreCase)) { return; } originalMissingFieldFound(headerNames, index, context); }; switch (section.Key) { // Parse *META section case Sections.META: csvReader.Configuration.RegisterClassMap <MetaClassMap>(); sharedParamsFile.Metadata = csvReader.GetRecords <Meta>().FirstOrDefault(); break; // Parse *GROUP section case Sections.GROUPS: csvReader.Configuration.RegisterClassMap <GroupClassMap>(); sharedParamsFile.Groups = csvReader.GetRecords <Group>().ToList(); break; // Parse *PARAM section case Sections.PARAMS: csvReader.Configuration.RegisterClassMap <ParameterClassMap>(); sharedParamsFile.Parameters = csvReader.GetRecords <Parameter>().ToList(); break; default: Debug.WriteLine($"Unknown section type: {section.Key}"); continue; } } } } // Post-process parameters by assigning group names using group IDs // and recover UnitType from ParameterType sharedParamsFile.Parameters = sharedParamsFile .Parameters .Select(p => { p.GroupName = sharedParamsFile.Groups?.FirstOrDefault(g => g.Id == p.GroupId)?.Name; p.UnitType = p.ParameterType.GetUnitType(); return(p); }) .ToList(); return(sharedParamsFile); }