e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
290 lines
9.8 KiB
C#
290 lines
9.8 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="SectionUpdates.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.Configuration {
|
|
using System.Collections;
|
|
|
|
//
|
|
// A collection of updates to the sections that have the same location attributes.
|
|
//
|
|
internal class SectionUpdates {
|
|
private string _name; // name of this section, for debugging
|
|
private Hashtable _groups; // group name -> SectionUpdates
|
|
private Hashtable _sections; // section name -> Update
|
|
private int _cUnretrieved; // number of items not retrieved in update algorithm.
|
|
private int _cMoved; // number of items moved (new or location attributes changed).
|
|
private Update _sectionGroupUpdate; // update for this group
|
|
private bool _isNew; // is the entire section new (all sections and subgroups)?
|
|
|
|
internal SectionUpdates(string name) {
|
|
_name = name;
|
|
_groups = new Hashtable();
|
|
_sections = new Hashtable();
|
|
}
|
|
|
|
internal bool IsNew {
|
|
get {return _isNew;}
|
|
set {_isNew = value;}
|
|
}
|
|
|
|
internal bool IsEmpty {
|
|
get {
|
|
return _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, dummy;
|
|
|
|
if (isGroup) {
|
|
group = configKey;
|
|
}
|
|
else {
|
|
BaseConfigurationRecord.SplitConfigKey(configKey, out group, out dummy);
|
|
}
|
|
|
|
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.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;
|
|
}
|
|
|
|
//
|
|
// Add one update.
|
|
//
|
|
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++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add a section group update.
|
|
//
|
|
internal void AddSectionGroup(Update update) {
|
|
SectionUpdates sectionUpdates = FindSectionUpdates(update.ConfigKey, true);
|
|
sectionUpdates._sectionGroupUpdate = update;
|
|
}
|
|
|
|
//
|
|
// Retrieve an update if it has not yet been retrieved.
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Get the update for a section group.
|
|
//
|
|
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();
|
|
}
|
|
if (_sectionGroupUpdate != null){
|
|
_sectionGroupUpdate.Retrieved = true;
|
|
}
|
|
}
|
|
|
|
internal void MarkGroupAsRetrieved(string groupName)
|
|
{
|
|
SectionUpdates sectionUpdates = _groups[groupName] as SectionUpdates;
|
|
if (sectionUpdates != null) {
|
|
sectionUpdates.MarkAsRetrieved();
|
|
}
|
|
}
|
|
//
|
|
// Return true if this section group contains any new section groups, false otherwise.
|
|
//
|
|
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;
|
|
}
|
|
}
|
|
}
|