System.Configuration.BaseConfigurationRecord.ResolveLocationSections C# (CSharp) Method

ResolveLocationSections() private method

private ResolveLocationSections ( ) : void
return void
        private void ResolveLocationSections() {
            if (!_flags[IsLocationListResolved]) {
                // Resolve outside of any lock
                if (!_parent.IsRootConfig) {
                    _parent.ResolveLocationSections();
                }
                
                lock (this) {
                    if (!_flags[IsLocationListResolved]) {
                        if (_locationSections != null) {
                            //
                            // Create dictionary that maps configPaths to (dictionary that maps sectionNames to locationSectionRecords)
                            //
                            HybridDictionary locationConfigPaths = new HybridDictionary(true);
                            foreach (LocationSectionRecord locationSectionRecord in _locationSections) {
                                //
                                // Resolve the target config path
                                //
                                string targetConfigPath = Host.GetConfigPathFromLocationSubPath(_configPath, locationSectionRecord.SectionXmlInfo.SubPath);
                                locationSectionRecord.SectionXmlInfo.TargetConfigPath = targetConfigPath;
                                    
                                //
                                // Check uniqueness
                                //
                                HybridDictionary locationSectionRecordDictionary = (HybridDictionary) locationConfigPaths[targetConfigPath];
                                if (locationSectionRecordDictionary == null) {
                                    locationSectionRecordDictionary = new HybridDictionary(false);
                                    locationConfigPaths.Add(targetConfigPath, locationSectionRecordDictionary);
                                }

                                LocationSectionRecord duplicateRecord = (LocationSectionRecord) locationSectionRecordDictionary[locationSectionRecord.ConfigKey];
                                if (duplicateRecord == null) {
                                    locationSectionRecordDictionary.Add(locationSectionRecord.ConfigKey, locationSectionRecord);
                                }
                                else {
                                    if (!duplicateRecord.HasErrors) {
                                        duplicateRecord.AddError(
                                            new ConfigurationErrorsException(
                                                    SR.GetString(SR.Config_sections_must_be_unique), 
                                                    duplicateRecord.SectionXmlInfo));
                                    }

                                    locationSectionRecord.AddError(
                                            new ConfigurationErrorsException(
                                                    SR.GetString(SR.Config_sections_must_be_unique), 
                                                    locationSectionRecord.SectionXmlInfo));
                                }

                                //
                                // Check if the definition is allowed
                                //
                                FactoryRecord factoryRecord = FindFactoryRecord(locationSectionRecord.ConfigKey, true);
                                if (!factoryRecord.HasErrors) {
                                    try {
                                        VerifyDefinitionAllowed(factoryRecord, targetConfigPath, locationSectionRecord.SectionXmlInfo);
                                    }
                                    catch (ConfigurationException e) {
                                        locationSectionRecord.AddError(e);
                                    }
                                }
                            }

                            //
                            // Check location section for being locked.
                            //
                            BaseConfigurationRecord parent = _parent;
                            while (!parent.IsRootConfig) {
                                foreach (LocationSectionRecord locationSectionRecord in this._locationSections) {
                                    bool locked = false;

                                    //
                                    // It is an error if a parent section with the same configKey is locked.
                                    //
                                    SectionRecord sectionRecord = parent.GetSectionRecord(locationSectionRecord.ConfigKey, true);
                                    if (   sectionRecord != null && 
                                            (sectionRecord.LockChildren || sectionRecord.Locked)) {

                                        locked = true;
                                    }
                                    else {
                                        //
                                        // It is an error if a parent configuration file locks a section for the
                                        // locationConfigPath or any sub-path of the locationConfigPath.
                                        //
                                        if (parent._locationSections != null) {
                                            string targetConfigPath = locationSectionRecord.SectionXmlInfo.TargetConfigPath;

                                            foreach (LocationSectionRecord parentLocationSectionRecord in parent._locationSections) {
                                                string parentTargetConfigPath = parentLocationSectionRecord.SectionXmlInfo.TargetConfigPath;

                                                if (   parentLocationSectionRecord.SectionXmlInfo.LockChildren &&
                                                       locationSectionRecord.ConfigKey == parentLocationSectionRecord.ConfigKey &&
                                                       UrlPath.IsEqualOrSubpath(targetConfigPath, parentTargetConfigPath)) {

                                                    locked = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    if (locked) {
                                        locationSectionRecord.AddError(new ConfigurationErrorsException(
                                            SR.GetString(SR.Config_section_locked),
                                            locationSectionRecord.SectionXmlInfo));
                                    }
                                }

                                parent = parent._parent;
                            }
                        }
                    }

                    _flags[IsLocationListResolved] = true;
                }
            }
        }

Usage Example

        internal void Init(
                IInternalConfigRoot         configRoot,
                BaseConfigurationRecord     parent,
                string                      configPath,
                string                      locationSubPath) {

            _initErrors = new ConfigurationSchemaErrors();

            //
            // try/catch here is only for unexpected exceptions due to errors in
            // our own code, as we always want the configuration record to be 
            // usable
            //
            try {
                _configRoot = (InternalConfigRoot) configRoot;
                _parent = parent;
                _configPath = configPath;
                _locationSubPath = locationSubPath;
                _configName = ConfigPathUtility.GetName(configPath);

                if (IsLocationConfig) {
                    _configStreamInfo = _parent.ConfigStreamInfo;
                }
                else {
                    _configStreamInfo = new ConfigRecordStreamInfo();
                }

                // no more initialization in case of root config
                if (IsRootConfig)
                    return;

                // determine what features we support
                _flags[SupportsChangeNotifications] = ClassFlags[ClassSupportsChangeNotifications] && Host.SupportsChangeNotifications;
                _flags[SupportsRefresh] = ClassFlags[ClassSupportsRefresh] && Host.SupportsRefresh;
                _flags[SupportsKeepInputs] = ClassFlags[ClassSupportsKeepInputs] || _flags[SupportsRefresh];
                _flags[SupportsPath] = Host.SupportsPath;
                _flags[SupportsLocation] = Host.SupportsLocation;

                // get static state based on the configPath
                if (_flags[SupportsLocation]) {
                    _flags[IsAboveApplication] = Host.IsAboveApplication(_configPath);
                }

                _flags[IsTrusted] = Host.IsTrustedConfigPath(_configPath);

                ArrayList locationSubPathInputs = null;

                if (_flags[SupportsLocation]) {
                    //
                    // Treat location inputs from parent record
                    // as though they were bonafide sections in this record.
                    //
                    if (IsLocationConfig && _parent._locationSections != null) {
                        // Resolve paths and check for errors in location sections.
                        _parent.ResolveLocationSections();

                        int i = 0;
                        while (i < _parent._locationSections.Count) {
                            LocationSectionRecord locationSectionRecord = (LocationSectionRecord) _parent._locationSections[i];

                            if (!StringUtil.EqualsIgnoreCase(locationSectionRecord.SectionXmlInfo.SubPath, _locationSubPath)) {
                                i++;
                            }
                            else {
                                // remove the locationSectionRecord from the list
                                _parent._locationSections.RemoveAt(i);

                                if (locationSubPathInputs == null) {
                                    locationSubPathInputs = new ArrayList();
                                }

                                locationSubPathInputs.Add(locationSectionRecord);
                            }
                        }
                    }

                    //
                    // Add location inputs that apply to this path, all the way up the parent hierarchy.
                    //
                    if (Host.IsLocationApplicable(_configPath)) {
                        BaseConfigurationRecord current = _parent;
                        while (!current.IsRootConfig) {
                            if (current._locationSections != null) {
                                current.ResolveLocationSections();
                                foreach (LocationSectionRecord locationSectionRecord in current._locationSections) {
                                    // We use the location tag input if:
                                    // - The path matches, and
                                    // - It's not skipped due to inheritInChildApplications setting.
                                    if (StringUtil.EqualsIgnoreCase(locationSectionRecord.SectionXmlInfo.TargetConfigPath, this._configPath) &&
                                        !ShouldSkipDueToInheritInChildApplications(locationSectionRecord.SectionXmlInfo.SkipInChildApps)) {
                                        // add the location input for this section
                                        SectionRecord sectionRecord = EnsureSectionRecord(locationSectionRecord.ConfigKey, true);
                                        SectionInput sectionInput = new SectionInput(
                                                locationSectionRecord.SectionXmlInfo, locationSectionRecord.ErrorsList);

                                        sectionRecord.AddLocationInput(sectionInput);

                                        // copy the initialization errors to the record
                                        if (locationSectionRecord.HasErrors) {
                                            this._initErrors.AddSavedLocalErrors(locationSectionRecord.Errors);
                                        }
                                    }
                                }
                            }
    
                            current = current._parent;
                        }
                    }
                }

                if (!IsLocationConfig) {
                    //
                    // If config file exists, open it and parse it once so we can
                    // find what to evaluate later.
                    //
                    InitConfigFromFile();
                }
                else {
                    // Add location sections for this record as bonafide sections.
                    if (locationSubPathInputs != null) {
                        foreach (LocationSectionRecord locationSectionRecord in locationSubPathInputs) {
                            // add the file input
                            SectionRecord sectionRecord = EnsureSectionRecord(locationSectionRecord.ConfigKey, true);
                            SectionInput sectionInput = new SectionInput(locationSectionRecord.SectionXmlInfo, locationSectionRecord.ErrorsList);
                            sectionRecord.AddFileInput(sectionInput);

                            // copy the initialization errors to the record
                            if (locationSectionRecord.HasErrors) {
                                this._initErrors.AddSavedLocalErrors(locationSectionRecord.Errors);
                            }
                        }
                    }
                }
            }
            //
            // Capture all exceptions and include them in initialization errors.
            //
            catch (Exception e) {
                string streamname = (ConfigStreamInfo != null) ? ConfigStreamInfo.StreamName : null;

                _initErrors.AddError(
                        ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, streamname, 0),
                        ExceptionAction.Global);
            }
            catch {
                string streamname = (ConfigStreamInfo != null) ? ConfigStreamInfo.StreamName : null;

                _initErrors.AddError(
                        ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, streamname, 0),
                        ExceptionAction.Global);
            }
        }
BaseConfigurationRecord