| File: System\Configuration\SectionUpdates.cs | Web Access |
| Project: src\runtime\src\libraries\System.Configuration.ConfigurationManager\src\System.Configuration.ConfigurationManager.csproj (System.Configuration.ConfigurationManager) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; using System.Diagnostics; namespace System.Configuration { internal sealed class SectionUpdates { private readonly Hashtable _groups; private readonly string _name; private readonly Hashtable _sections; private int _cMoved; private int _cUnretrieved; private Update _sectionGroupUpdate; internal SectionUpdates(string name) { _name = name; _groups = new Hashtable(); _sections = new Hashtable(); } internal bool IsNew { get; set; } internal bool IsEmpty => (_groups.Count == 0) && (_sections.Count == 0); // Find the SectionUpdates for a configKey, and create it if it does not exist. private SectionUpdates FindSectionUpdates(string configKey, bool isGroup) { string group; if (isGroup) group = configKey; else BaseConfigurationRecord.SplitConfigKey(configKey, out group, out _); Debug.Assert(string.IsNullOrEmpty(_name), "FindSectionUpdates assumes search is from root record"); SectionUpdates sectionUpdates = this; if (group.Length != 0) { // find the SectionUpdates for the group string[] groups = group.Split(BaseConfigurationRecord.s_configPathSeparatorParams); foreach (string groupPart in groups) { SectionUpdates sectionUpdatesChild = (SectionUpdates)sectionUpdates._groups[groupPart]; if (sectionUpdatesChild == null) { sectionUpdatesChild = new SectionUpdates(groupPart); sectionUpdates._groups[groupPart] = sectionUpdatesChild; } sectionUpdates = sectionUpdatesChild; } } return sectionUpdates; } // Recursively check whether this group has all new updates. // An update is new if all sections are new and all subgroups are new. internal void CompleteUpdates() { bool allSubgroupsAreNew = true; // call CompleteUpdates() for all children foreach (SectionUpdates sectionUpdates in _groups.Values) { sectionUpdates.CompleteUpdates(); if (!sectionUpdates.IsNew) allSubgroupsAreNew = false; } IsNew = allSubgroupsAreNew && (_cMoved == _sections.Count); } internal void AddSection(Update update) { SectionUpdates sectionUpdates = FindSectionUpdates(update.ConfigKey, false); sectionUpdates._sections.Add(update.ConfigKey, update); // Maintain counts. sectionUpdates._cUnretrieved++; if (update.Moved) sectionUpdates._cMoved++; } internal void AddSectionGroup(Update update) { SectionUpdates sectionUpdates = FindSectionUpdates(update.ConfigKey, true); sectionUpdates._sectionGroupUpdate = update; } private Update GetUpdate(string configKey) { Update update = (Update)_sections[configKey]; if (update != null) { if (update.Retrieved) update = null; else { update.Retrieved = true; _cUnretrieved--; if (update.Moved) _cMoved--; } } return update; } internal DeclarationUpdate GetSectionGroupUpdate() { if ((_sectionGroupUpdate != null) && !_sectionGroupUpdate.Retrieved) { _sectionGroupUpdate.Retrieved = true; return (DeclarationUpdate)_sectionGroupUpdate; } return null; } internal DefinitionUpdate GetDefinitionUpdate(string configKey) { return (DefinitionUpdate)GetUpdate(configKey); } internal DeclarationUpdate GetDeclarationUpdate(string configKey) { return (DeclarationUpdate)GetUpdate(configKey); } internal SectionUpdates GetSectionUpdatesForGroup(string group) { return (SectionUpdates)_groups[group]; } // Return true if this section group or any of its children have unretrieved sections. internal bool HasUnretrievedSections() { if ((_cUnretrieved > 0) || ((_sectionGroupUpdate != null) && !_sectionGroupUpdate.Retrieved)) return true; foreach (SectionUpdates sectionUpdates in _groups.Values) if (sectionUpdates.HasUnretrievedSections()) return true; return false; } internal void MarkAsRetrieved() { _cUnretrieved = 0; foreach (SectionUpdates sectionUpdates in _groups.Values) sectionUpdates.MarkAsRetrieved(); _sectionGroupUpdate?.Retrieved = true; } internal void MarkGroupAsRetrieved(string groupName) { SectionUpdates sectionUpdates = _groups[groupName] as SectionUpdates; sectionUpdates?.MarkAsRetrieved(); } internal bool HasNewSectionGroups() { foreach (SectionUpdates sectionUpdates in _groups.Values) if (sectionUpdates.IsNew) return true; return false; } // Return a sorted list of the names of unretrieved sections in this group. internal string[] GetUnretrievedSectionNames() { if (_cUnretrieved == 0) return null; string[] sectionNames = new string[_cUnretrieved]; int i = 0; foreach (Update update in _sections.Values) if (!update.Retrieved) { sectionNames[i] = update.ConfigKey; i++; } Array.Sort(sectionNames); return sectionNames; } // Return a sorted list of the names of moved and unretrieved sections in this group. internal string[] GetMovedSectionNames() { if (_cMoved == 0) return null; string[] sectionNames = new string[_cMoved]; int i = 0; foreach (Update update in _sections.Values) if (update.Moved && !update.Retrieved) { sectionNames[i] = update.ConfigKey; i++; } Array.Sort(sectionNames); return sectionNames; } // Return a sorted list of the names of groups with unretrieved sections. internal string[] GetUnretrievedGroupNames() { ArrayList unretrievedGroups = new ArrayList(); foreach (DictionaryEntry de in _groups) { string group = (string)de.Key; SectionUpdates sectionUpdates = (SectionUpdates)de.Value; if (sectionUpdates.HasUnretrievedSections()) unretrievedGroups.Add(group); } if (unretrievedGroups.Count == 0) return null; string[] groupNames = new string[unretrievedGroups.Count]; unretrievedGroups.CopyTo(groupNames); Array.Sort(groupNames); return groupNames; } // Return a sorted list of the names of new section groups with unretrieved sections. internal string[] GetNewGroupNames() { ArrayList newsGroups = new ArrayList(); foreach (DictionaryEntry de in _groups) { string group = (string)de.Key; SectionUpdates sectionUpdates = (SectionUpdates)de.Value; if (sectionUpdates.IsNew && sectionUpdates.HasUnretrievedSections()) newsGroups.Add(group); } if (newsGroups.Count == 0) return null; string[] groupNames = new string[newsGroups.Count]; newsGroups.CopyTo(groupNames); Array.Sort(groupNames); return groupNames; } } }