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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="SectionRecord.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.Configuration.Internal;
  18.     using System.Collections;
  19.     using System.Collections.Specialized;
  20.     using System.Collections.Generic;
  21.     using System.Configuration;
  22.     using System.Text;
  23.     using System.Threading;
  24.     using System.Reflection;
  25.     using System.Xml;
  26.    
  27.     [System.Diagnostics.DebuggerDisplay("SectionRecord {ConfigKey}")]
  28.     internal class SectionRecord
  29.     {
  30.         //
  31.         // Flags constants
  32.         //
  33.        
  34.         //
  35.         // Runtime flags below 0x10000
  36.         //
  37.        
  38.         // locked by parent input, either because a parent section is locked,
  39.         // a parent section locks all children, or a location input for this
  40.         // configPath has allowOverride=false.
  41.         private const int Flag_Locked = 1;
  42.        
  43.         // lock children of this section
  44.         private const int Flag_LockChildren = 2;
  45.        
  46.         // propagation of FactoryRecord.IsFactoryTrustedWithoutAptca
  47.         private const int Flag_IsResultTrustedWithoutAptca = 4;
  48.        
  49.         // propagation of FactoryRecord.RequirePermission
  50.         private const int Flag_RequirePermission = 8;
  51.        
  52.         //
  53.         // Designtime flags at or above 0x00010000
  54.         //
  55.        
  56.         // the section has been added to the update list
  57.         private const int Flag_AddUpdate = 65536;
  58.        
  59.         // result can be null, so we use this object to indicate whether it has been evaluated
  60.         static object s_unevaluated = new object();
  61.        
  62.         private SafeBitVector32 _flags;
  63.        
  64.         // config key
  65.         private string _configKey;
  66.        
  67.         // The input from location sections
  68.         // This list is ordered to keep oldest ancestors at the front
  69.         private List<SectionInput> _locationInputs;
  70.        
  71.         // The input from this file
  72.         private SectionInput _fileInput;
  73.        
  74.         // the cached result of evaluating this section
  75.         private object _result;
  76.        
  77.         // the cached result of evaluating this section after GetRuntimeObject is called
  78.         private object _resultRuntimeObject;
  79.        
  80.         // errors not associated with a particular input
  81.         // this it NOT the sum of all errors
  82.         private List<ConfigurationException> _errors;
  83.        
  84.        
  85.         internal SectionRecord(string configKey)
  86.         {
  87.             _configKey = configKey;
  88.             _result = s_unevaluated;
  89.             _resultRuntimeObject = s_unevaluated;
  90.         }
  91.        
  92.         internal string ConfigKey {
  93.             get { return _configKey; }
  94.         }
  95.        
  96.         internal bool Locked {
  97.             get { return _flags[Flag_Locked]; }
  98.             set { _flags[Flag_Locked] = value; }
  99.         }
  100.        
  101.         internal bool LockChildren {
  102.             get { return _flags[Flag_LockChildren]; }
  103.             set { _flags[Flag_LockChildren] = value; }
  104.         }
  105.        
  106.         internal bool IsResultTrustedWithoutAptca {
  107.             get { return _flags[Flag_IsResultTrustedWithoutAptca]; }
  108.             set { _flags[Flag_IsResultTrustedWithoutAptca] = value; }
  109.         }
  110.        
  111.         internal bool RequirePermission {
  112.             get { return _flags[Flag_RequirePermission]; }
  113.             set { _flags[Flag_RequirePermission] = value; }
  114.         }
  115.        
  116.         internal bool AddUpdate {
  117.             get { return _flags[Flag_AddUpdate]; }
  118.             set { _flags[Flag_AddUpdate] = value; }
  119.         }
  120.        
  121.         internal bool HasLocationInputs {
  122.             get { return _locationInputs != null && _locationInputs.Count > 0; }
  123.         }
  124.        
  125.         internal List<SectionInput> LocationInputs {
  126.             get { return _locationInputs; }
  127.         }
  128.        
  129.         internal SectionInput LastLocationInput {
  130.             get {
  131.                 if (HasLocationInputs) {
  132.                     return _locationInputs[_locationInputs.Count - 1];
  133.                 }
  134.                 else {
  135.                     return null;
  136.                 }
  137.             }
  138.         }
  139.        
  140.         internal void AddLocationInput(SectionInput sectionInput)
  141.         {
  142.             if (_locationInputs == null) {
  143.                 _locationInputs = new List<SectionInput>(1);
  144.             }
  145.            
  146.             // The list of locationSections is traversed from child to parent,
  147.             // so insert at the beginning of the list.
  148.             _locationInputs.Insert(0, sectionInput);
  149.            
  150.             // If LockChildren is set, lock both ourselves and children
  151.             if (!sectionInput.HasErrors && sectionInput.SectionXmlInfo.LockChildren) {
  152.                 Locked = true;
  153.                 LockChildren = true;
  154.             }
  155.         }
  156.        
  157.         internal bool HasFileInput {
  158.             get { return _fileInput != null; }
  159.         }
  160.        
  161.         internal SectionInput FileInput {
  162.             get { return _fileInput; }
  163.         }
  164.        
  165.         // AddFileInput
  166.         internal void AddFileInput(SectionInput sectionInput)
  167.         {
  168.             _fileInput = sectionInput;
  169.            
  170.             // If LockChildren is set, lock our children
  171.             if (!sectionInput.HasErrors && sectionInput.SectionXmlInfo.LockChildren) {
  172.                 LockChildren = true;
  173.             }
  174.         }
  175.        
  176.         internal void RemoveFileInput()
  177.         {
  178.             if (_fileInput != null) {
  179.                 _fileInput = null;
  180.                
  181.                 // Reset LockChildren flag to the value provided by
  182.                 // location input or inherited sections.
  183.                 LockChildren = Locked;
  184.             }
  185.         }
  186.        
  187.         internal bool HasInput {
  188.             get { return HasLocationInputs || HasFileInput; }
  189.         }
  190.        
  191.         internal void ClearRawXml()
  192.         {
  193.             if (HasLocationInputs) {
  194.                 foreach (SectionInput locationInput in LocationInputs) {
  195.                     locationInput.SectionXmlInfo.RawXml = null;
  196.                 }
  197.             }
  198.            
  199.             if (HasFileInput) {
  200.                 FileInput.SectionXmlInfo.RawXml = null;
  201.             }
  202.         }
  203.        
  204.         internal bool HasResult {
  205.             get { return _result != s_unevaluated; }
  206.         }
  207.        
  208.         internal bool HasResultRuntimeObject {
  209.             get { return _resultRuntimeObject != s_unevaluated; }
  210.         }
  211.        
  212.         internal object Result {
  213. // Useful assert, but it fires in the debugger when using automatic property evaluation
  214. // Debug.Assert(_result != s_unevaluated, "_result != s_unevaluated");
  215.             get { return _result; }
  216.            
  217.             set { _result = value; }
  218.         }
  219.        
  220.         internal object ResultRuntimeObject {
  221. // Useful assert, but it fires in the debugger when using automatic property evaluation
  222. // Debug.Assert(_resultRuntimeObject != s_unevaluated, "_resultRuntimeObject != s_unevaluated");
  223.             get { return _resultRuntimeObject; }
  224.            
  225.             set { _resultRuntimeObject = value; }
  226.         }
  227.        
  228.         internal void ClearResult()
  229.         {
  230.             if (_fileInput != null) {
  231.                 _fileInput.ClearResult();
  232.             }
  233.            
  234.             if (_locationInputs != null) {
  235.                 foreach (SectionInput input in _locationInputs) {
  236.                     input.ClearResult();
  237.                 }
  238.             }
  239.            
  240.             _result = s_unevaluated;
  241.             _resultRuntimeObject = s_unevaluated;
  242.         }
  243.        
  244.         //
  245.         // Error handling.
  246.         //
  247.        
  248.         private List<ConfigurationException> GetAllErrors()
  249.         {
  250.             List<ConfigurationException> allErrors = null;
  251.            
  252.             ErrorsHelper.AddErrors(ref allErrors, _errors);
  253.            
  254.             if (HasLocationInputs) {
  255.                 foreach (SectionInput input in LocationInputs) {
  256.                     ErrorsHelper.AddErrors(ref allErrors, input.Errors);
  257.                 }
  258.             }
  259.            
  260.             if (HasFileInput) {
  261.                 ErrorsHelper.AddErrors(ref allErrors, FileInput.Errors);
  262.             }
  263.            
  264.             return allErrors;
  265.         }
  266.        
  267.         internal bool HasErrors {
  268.             get {
  269.                 if (ErrorsHelper.GetHasErrors(_errors)) {
  270.                     return true;
  271.                 }
  272.                
  273.                 if (HasLocationInputs) {
  274.                     foreach (SectionInput input in LocationInputs) {
  275.                         if (input.HasErrors) {
  276.                             return true;
  277.                         }
  278.                     }
  279.                 }
  280.                
  281.                 if (HasFileInput) {
  282.                     if (FileInput.HasErrors) {
  283.                         return true;
  284.                     }
  285.                 }
  286.                
  287.                 return false;
  288.             }
  289.         }
  290.        
  291.         internal void ThrowOnErrors()
  292.         {
  293.             if (HasErrors) {
  294.                 throw new ConfigurationErrorsException(GetAllErrors());
  295.             }
  296.         }
  297.     }
  298. }

Developer Fusion