/// <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));
 }
예제 #2
0
        /// <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);
        }