The Labs \ Source Viewer \ SSCLI \ System.Configuration \ SectionUpdates

  1. //------------------------------------------------------------------------------
  2. // <copyright file="SectionUpdates.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Configuration
  16. {
  17.     using System.Collections;
  18.    
  19.     //
  20.     // A collection of updates to the sections that have the same location attributes.
  21.     //
  22.     internal class SectionUpdates
  23.     {
  24.         private string _name;
  25.         // name of this section, for debugging
  26.         private Hashtable _groups;
  27.         // group name -> SectionUpdates
  28.         private Hashtable _sections;
  29.         // section name -> Update
  30.         private int _cUnretrieved;
  31.         // number of items not retrieved in update algorithm.
  32.         private int _cMoved;
  33.         // number of items moved (new or location attributes changed).
  34.         private Update _sectionGroupUpdate;
  35.         // update for this group
  36.         private bool _isNew;
  37.         // is the entire section new (all sections and subgroups)?
  38.         internal SectionUpdates(string name)
  39.         {
  40.             _name = name;
  41.             _groups = new Hashtable();
  42.             _sections = new Hashtable();
  43.         }
  44.        
  45.         internal bool IsNew {
  46.             get { return _isNew; }
  47.             set { _isNew = value; }
  48.         }
  49.        
  50.         internal bool IsEmpty {
  51.             get { return _groups.Count == 0 && _sections.Count == 0; }
  52.         }
  53.        
  54.         //
  55.         // Find the SectionUpdates for a configKey, and create it if it does not exist.
  56.         //
  57.         private SectionUpdates FindSectionUpdates(string configKey, bool isGroup)
  58.         {
  59.             string group;
  60.             string dummy;
  61.            
  62.             if (isGroup) {
  63.                 group = configKey;
  64.             }
  65.             else {
  66.                 BaseConfigurationRecord.SplitConfigKey(configKey, out group, out dummy);
  67.             }
  68.            
  69.             Debug.Assert(String.IsNullOrEmpty(_name), "FindSectionUpdates assumes search is from root record");
  70.             SectionUpdates sectionUpdates = this;
  71.             if (group.Length != 0) {
  72.                 // find the SectionUpdates for the group
  73.                 string[] groups = group.Split(BaseConfigurationRecord.ConfigPathSeparatorParams);
  74.                 foreach (string groupPart in groups) {
  75.                     SectionUpdates sectionUpdatesChild = (SectionUpdates)sectionUpdates._groups[groupPart];
  76.                     if (sectionUpdatesChild == null) {
  77.                         sectionUpdatesChild = new SectionUpdates(groupPart);
  78.                         sectionUpdates._groups[groupPart] = sectionUpdatesChild;
  79.                     }
  80.                    
  81.                     sectionUpdates = sectionUpdatesChild;
  82.                 }
  83.             }
  84.            
  85.             return sectionUpdates;
  86.         }
  87.        
  88.         //
  89.         // Recursively check whether this group has all new updates.
  90.         // An update is new if all sections are new and all subgroups are new.
  91.         //
  92.         internal void CompleteUpdates()
  93.         {
  94.             bool allSubgroupsAreNew = true;
  95.            
  96.             // call CompleteUpdates() for all children
  97.             foreach (SectionUpdates sectionUpdates in _groups.Values) {
  98.                 sectionUpdates.CompleteUpdates();
  99.                 if (!sectionUpdates.IsNew) {
  100.                     allSubgroupsAreNew = false;
  101.                 }
  102.             }
  103.            
  104.             _isNew = allSubgroupsAreNew && _cMoved == _sections.Count;
  105.         }
  106.        
  107.         //
  108.         // Add one update.
  109.         //
  110.         internal void AddSection(Update update)
  111.         {
  112.             SectionUpdates sectionUpdates = FindSectionUpdates(update.ConfigKey, false);
  113.             sectionUpdates._sections.Add(update.ConfigKey, update);
  114.            
  115.             // Maintain counts.
  116.             sectionUpdates._cUnretrieved++;
  117.             if (update.Moved) {
  118.                 sectionUpdates._cMoved++;
  119.             }
  120.         }
  121.        
  122.         //
  123.         // Add a section group update.
  124.         //
  125.         internal void AddSectionGroup(Update update)
  126.         {
  127.             SectionUpdates sectionUpdates = FindSectionUpdates(update.ConfigKey, true);
  128.             sectionUpdates._sectionGroupUpdate = update;
  129.         }
  130.        
  131.         //
  132.         // Retrieve an update if it has not yet been retrieved.
  133.         //
  134.         private Update GetUpdate(string configKey)
  135.         {
  136.             Update update = (Update)_sections[configKey];
  137.             if (update != null) {
  138.                 if (update.Retrieved) {
  139.                     update = null;
  140.                 }
  141.                 else {
  142.                     update.Retrieved = true;
  143.                     _cUnretrieved--;
  144.                     if (update.Moved) {
  145.                         _cMoved--;
  146.                     }
  147.                 }
  148.             }
  149.            
  150.             return update;
  151.         }
  152.        
  153.         //
  154.         // Get the update for a section group.
  155.         //
  156.         internal DeclarationUpdate GetSectionGroupUpdate()
  157.         {
  158.             if (_sectionGroupUpdate != null && !_sectionGroupUpdate.Retrieved) {
  159.                 _sectionGroupUpdate.Retrieved = true;
  160.                 return (DeclarationUpdate)_sectionGroupUpdate;
  161.             }
  162.            
  163.             return null;
  164.         }
  165.        
  166.         internal DefinitionUpdate GetDefinitionUpdate(string configKey)
  167.         {
  168.             return (DefinitionUpdate)GetUpdate(configKey);
  169.         }
  170.        
  171.         internal DeclarationUpdate GetDeclarationUpdate(string configKey)
  172.         {
  173.             return (DeclarationUpdate)GetUpdate(configKey);
  174.         }
  175.        
  176.         internal SectionUpdates GetSectionUpdatesForGroup(string group)
  177.         {
  178.             return (SectionUpdates)_groups[group];
  179.         }
  180.        
  181.         //
  182.         // Return true if this section group or any of its children have unretrieved sections.
  183.         //
  184.         internal bool HasUnretrievedSections()
  185.         {
  186.             if (_cUnretrieved > 0 || (_sectionGroupUpdate != null && !_sectionGroupUpdate.Retrieved)) {
  187.                 return true;
  188.             }
  189.            
  190.             foreach (SectionUpdates sectionUpdates in _groups.Values) {
  191.                 if (sectionUpdates.HasUnretrievedSections()) {
  192.                     return true;
  193.                 }
  194.             }
  195.            
  196.             return false;
  197.         }
  198.        
  199.         //
  200.         // Return true if this section group contains any new section groups, false otherwise.
  201.         //
  202.         internal bool HasNewSectionGroups()
  203.         {
  204.             foreach (SectionUpdates sectionUpdates in _groups.Values) {
  205.                 if (sectionUpdates.IsNew)
  206.                     return true;
  207.             }
  208.            
  209.             return false;
  210.         }
  211.        
  212.         //
  213.         // Return a sorted list of the names of unretrieved sections in this group.
  214.         //
  215.         internal string[] GetUnretrievedSectionNames()
  216.         {
  217.             if (_cUnretrieved == 0)
  218.                 return null;
  219.            
  220.             string[] sectionNames = new string[_cUnretrieved];
  221.             int i = 0;
  222.             foreach (Update update in _sections.Values) {
  223.                 if (!update.Retrieved) {
  224.                     sectionNames[i] = update.ConfigKey;
  225.                     i++;
  226.                 }
  227.             }
  228.            
  229.             Array.Sort(sectionNames);
  230.             return sectionNames;
  231.         }
  232.        
  233.         //
  234.         // Return a sorted list of the names of moved and unretrieved sections in this group.
  235.         //
  236.         internal string[] GetMovedSectionNames()
  237.         {
  238.             if (_cMoved == 0)
  239.                 return null;
  240.            
  241.             string[] sectionNames = new string[_cMoved];
  242.             int i = 0;
  243.             foreach (Update update in _sections.Values) {
  244.                 if (update.Moved && !update.Retrieved) {
  245.                     sectionNames[i] = update.ConfigKey;
  246.                     i++;
  247.                 }
  248.             }
  249.            
  250.             Array.Sort(sectionNames);
  251.             return sectionNames;
  252.         }
  253.        
  254.         //
  255.         // Return a sorted list of the names of groups with unretrieved sections.
  256.         //
  257.         internal string[] GetUnretrievedGroupNames()
  258.         {
  259.             ArrayList unretrievedGroups = new ArrayList();
  260.            
  261.             foreach (DictionaryEntry de in _groups) {
  262.                 string group = (string)de.Key;
  263.                 SectionUpdates sectionUpdates = (SectionUpdates)de.Value;
  264.                 if (sectionUpdates.HasUnretrievedSections()) {
  265.                     unretrievedGroups.Add(group);
  266.                 }
  267.             }
  268.            
  269.             if (unretrievedGroups.Count == 0)
  270.                 return null;
  271.            
  272.             string[] groupNames = new string[unretrievedGroups.Count];
  273.             unretrievedGroups.CopyTo(groupNames);
  274.             Array.Sort(groupNames);
  275.             return groupNames;
  276.         }
  277.        
  278.         //
  279.         // Return a sorted list of the names of new section groups with unretrieved sections.
  280.         //
  281.         internal string[] GetNewGroupNames()
  282.         {
  283.             ArrayList newsGroups = new ArrayList();
  284.            
  285.             foreach (DictionaryEntry de in _groups) {
  286.                 string group = (string)de.Key;
  287.                 SectionUpdates sectionUpdates = (SectionUpdates)de.Value;
  288.                 if (sectionUpdates.IsNew && sectionUpdates.HasUnretrievedSections()) {
  289.                     newsGroups.Add(group);
  290.                 }
  291.             }
  292.            
  293.             if (newsGroups.Count == 0)
  294.                 return null;
  295.            
  296.             string[] groupNames = new string[newsGroups.Count];
  297.             newsGroups.CopyTo(groupNames);
  298.             Array.Sort(groupNames);
  299.             return groupNames;
  300.         }
  301.     }
  302. }

Developer Fusion