private void CopyConfigSource(XmlUtilWriter utilWriter, string updatedXml, string configSourceStreamName, byte[] buffer) { // only copy the byte order mark if it exists in the current web.config byte[] preamble; using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, true)) { preamble = ConfigStreamInfo.StreamEncoding.GetPreamble(); } } CheckPreamble(preamble, utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, false)) { XmlTextReader reader = xmlUtil.Reader; // copy up to the first element reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); // determine the indent to use for the element int indent = DEFAULT_INDENT; int linePosition = 1; bool hasElement = xmlUtil.CopyReaderToNextElement(utilWriter, false); if (hasElement) { // find the indent of the first attribute, if any int lineNumber = reader.LineNumber; linePosition = reader.LinePosition - 1; int attributeIndent = 0; while (reader.MoveToNextAttribute()) { if (reader.LineNumber > lineNumber) { attributeIndent = reader.LinePosition - linePosition; break; } } // find the indent of the first sub element, if any int elementIndent = 0; reader.Read(); while (reader.Depth >= 1) { if (reader.NodeType == XmlNodeType.Element) { elementIndent = (reader.LinePosition - 1) - linePosition; break; } reader.Read(); } if (elementIndent > 0) { indent = elementIndent; } else if (attributeIndent > 0) { indent = attributeIndent; } } // Write the config source string formattedXml = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, true); utilWriter.Write(formattedXml); // Copy remaining contents if (hasElement) { // Skip over the existing element while (reader.Depth > 0) { reader.Read(); } if (reader.IsEmptyElement || reader.NodeType == XmlNodeType.EndElement) { reader.Read(); } // Copy remainder of file while (xmlUtil.CopyXmlNode(utilWriter)) { } } } } }
private bool CopyConfigDeclarationsRecursive( SectionUpdates declarationUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, string group, int parentLinePosition, int parentIndent) { bool wroteASection = false; XmlTextReader reader = xmlUtil.Reader; int linePosition; int indent; int startingLinePosition; indent = UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { linePosition = xmlUtil.TrueLinePosition; startingLinePosition = linePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { linePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { linePosition = parentLinePosition + indent; startingLinePosition = 0; } // // Write any new section declarations that apply to this group // if (declarationUpdates != null) { string[] movedSectionNames = declarationUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } foreach (string configKey in movedSectionNames) { DeclarationUpdate sectionUpdate = declarationUpdates.GetDeclarationUpdate(configKey); Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); // Write the one line section declaration. utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(sectionUpdate.UpdatedXml); utilWriter.AppendNewLine(); wroteASection = true; } // Restore the whitespace we used for the first element, which is either a start or an end element. utilWriter.AppendSpacesToLinePosition(startingLinePosition); } } if (reader.NodeType == XmlNodeType.Element) { // // For each element at this depth, either: // - Write the element verbatim and recurse due to a group hierarchy element. // - Write the element verbatim because it is unchanged // - Write the updated XML for the section. // - Skip it because the section has been removed. // int depth = reader.Depth; while (reader.Depth == depth) { bool recurse = false; DeclarationUpdate sectionUpdate = null; DeclarationUpdate groupUpdate = null; SectionUpdates declarationUpdatesChild = null; SectionUpdates recurseDeclarationUpdates = declarationUpdates; string recurseGroup = group; // update the lineposition and indent for each element indent = UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); linePosition = xmlUtil.TrueLinePosition; string directive = reader.Name; string name = reader.GetAttribute(KEYWORD_SECTIONGROUP_NAME); string configKey = CombineConfigKey(group, name); if (directive == KEYWORD_SECTIONGROUP) { // it's a group - get the updates for children declarationUpdatesChild = declarationUpdates.GetSectionUpdatesForGroup(name); if (declarationUpdatesChild != null) { // get the group update groupUpdate = declarationUpdatesChild.GetSectionGroupUpdate(); // recurse if there are more sections to copy if (declarationUpdatesChild.HasUnretrievedSections()) { recurse = true; recurseGroup = configKey; recurseDeclarationUpdates = declarationUpdatesChild; } } } else { // it is a section - get the update Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); sectionUpdate = declarationUpdates.GetDeclarationUpdate(configKey); } bool writeGroupUpdate = (groupUpdate != null && groupUpdate.UpdatedXml != null); if (recurse) { #if DBG string startElementName = reader.Name; #endif // create a checkpoint that we can revert to if no children are written object checkpoint = utilWriter.CreateStreamCheckpoint(); string closingElement = null; // Copy this element node and up to the first subelement if (writeGroupUpdate) { // replace the element with the updated xml utilWriter.Write(groupUpdate.UpdatedXml); // skip over the start element reader.Read(); } else { closingElement= xmlUtil.UpdateStartElement(utilWriter, null, true, linePosition, indent); } if (closingElement == null) { // Only if there is a closing element should // we move to it xmlUtil.CopyReaderToNextElement(utilWriter, true); } // Recurse bool recurseWroteASection = CopyConfigDeclarationsRecursive( recurseDeclarationUpdates, xmlUtil, utilWriter, recurseGroup, linePosition, indent); if (closingElement != null) { utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(closingElement); // Since we already got to </configSections> in reader, lets // indent so we can copy the element in the right place utilWriter.AppendSpacesToLinePosition(parentLinePosition); } else { // Copy the end element xmlUtil.CopyXmlNode(utilWriter); } if (recurseWroteASection || writeGroupUpdate) { wroteASection = true; } else { // back out the change utilWriter.RestoreStreamCheckpoint(checkpoint); } // Copy up to the next element, or exit this level. xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool skip; bool skipChildElements = false; if (sectionUpdate == null) { skip = true; if (writeGroupUpdate) { // Insert an empty <sectionGroup type="typename" > node, to introduce the type wroteASection = true; utilWriter.Write(groupUpdate.UpdatedXml); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(FORMAT_SECTIONGROUP_ENDELEMENT); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(linePosition); } else if (groupUpdate != null) { // VSWhidbey 522450 // If groupUpdate exists, that means we've decided in GetConfigDeclarationUpdates // that the section group should stay in the file. Debug.Assert(groupUpdate.UpdatedXml == null, "groupUpdate.UpdatedXml == null"); Debug.Assert(!declarationUpdatesChild.HasUnretrievedSections(), "If the group has any unretrieved section, we should have chosen the recursive code path above."); wroteASection = true; skip = false; // We should skip all the child sections. If we indeed need to keep any child // section, we should have chosen the recursive code path above. skipChildElements = true; } } else { wroteASection = true; if (sectionUpdate.UpdatedXml == null) { skip = false; } else { skip = true; // Write the updated XML on a single line utilWriter.Write(sectionUpdate.UpdatedXml); } } if (skip) { // // Skip over the existing element, then // copy up to the next element, or exit this level. // xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { if (skipChildElements) { xmlUtil.SkipChildElementsAndCopyOuterXmlToNextElement(utilWriter); } else { // Copy this entire contents of this element and then to the next element, or exit this level. xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } } } } } return wroteASection; }
// Copy configuration sections from the original configuration file. private bool CopyConfigDefinitionsRecursive( ConfigDefinitionUpdates configDefinitionUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, bool locationPathApplies, LocationUpdates locationUpdates, SectionUpdates sectionUpdates, bool addNewSections, string group, int parentLinePosition, int parentIndent) { bool wroteASection = false; XmlTextReader reader = xmlUtil.Reader; int linePosition; int indent; int startingLinePosition; indent = UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { linePosition = xmlUtil.TrueLinePosition; startingLinePosition = linePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { linePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { linePosition = parentLinePosition + indent; startingLinePosition = 0; } // // Write any new sections that apply to this group // if (sectionUpdates != null && addNewSections) { // Remove newness, so we won't write again sectionUpdates.IsNew = false; Debug.Assert(locationPathApplies, "locationPathApplies"); string[] movedSectionNames = sectionUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.AppendSpacesToLinePosition(linePosition); bool skipFirstIndent = true; foreach (string configKey in movedSectionNames) { DefinitionUpdate update = sectionUpdates.GetDefinitionUpdate(configKey); WriteSectionUpdate(utilWriter, update, linePosition, indent, skipFirstIndent); skipFirstIndent = false; utilWriter.AppendNewLine(); wroteASection = true; } // Restore the whitespace we used for the first element, which is either a start or an end element. utilWriter.AppendSpacesToLinePosition(startingLinePosition); } } if (reader.NodeType == XmlNodeType.Element) { // // For each element at this depth, either: // - Write the element verbatim and recurse due to a location section or group hierarchy element. // - Write the element verbatim because it is unchanged, or because the current location does // not apply. // - Write the updated XML for the section. // - Skip it because the section has been removed. // int depth = reader.Depth; while (reader.Depth == depth) { bool recurse = false; DefinitionUpdate update = null; bool elementLocationPathApplies = locationPathApplies; LocationUpdates recurseLocationUpdates = locationUpdates; SectionUpdates recurseSectionUpdates = sectionUpdates; bool recurseAddNewSections = addNewSections; string recurseGroup = group; bool removedSectionOrGroup = false; // update the lineposition and indent for each element indent = UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); linePosition = xmlUtil.TrueLinePosition; string elementName = reader.Name; if (elementName == KEYWORD_LOCATION) { string locationSubPathAttribute = reader.GetAttribute(KEYWORD_LOCATION_PATH); locationSubPathAttribute = NormalizeLocationSubPath(locationSubPathAttribute, xmlUtil); elementLocationPathApplies = false; OverrideModeSetting overrideMode = OverrideModeSetting.LocationDefault; bool inheritInChildApps = true; if (IsLocationConfig) { // For location config we will compare config paths instead of location strings // so that we dont end up comparing "1" with "Default Web Site" and ending up with the wrong result if (locationSubPathAttribute == null) { elementLocationPathApplies = false; } else { elementLocationPathApplies = StringUtil.EqualsIgnoreCase(ConfigPath, Host.GetConfigPathFromLocationSubPath(Parent.ConfigPath, locationSubPathAttribute)); } } else { Debug.Assert(LocationSubPath == null); // This is the same as doing StringUtil.EqualsIgnoreCase(_locationSubPath, locationSubPathAttribute) // but remember the first one is null. Also remember locationSubPathAttribute is already normalized elementLocationPathApplies = (locationSubPathAttribute == null); } if (elementLocationPathApplies) { // Retrieve overrideMode and InheritInChildApps string allowOverrideAttribute = reader.GetAttribute(KEYWORD_LOCATION_ALLOWOVERRIDE); if (allowOverrideAttribute != null) { overrideMode = OverrideModeSetting.CreateFromXmlReadValue(Boolean.Parse(allowOverrideAttribute)); } string overrideModeAttribute = reader.GetAttribute(KEYWORD_LOCATION_OVERRIDEMODE); if (overrideModeAttribute != null) { overrideMode = OverrideModeSetting.CreateFromXmlReadValue(OverrideModeSetting.ParseOverrideModeXmlValue(overrideModeAttribute, null)); Debug.Assert(allowOverrideAttribute == null, "allowOverride and overrideMode both detected in a <location> tag"); } string inheritInChildAppsAttribute = reader.GetAttribute(KEYWORD_LOCATION_INHERITINCHILDAPPLICATIONS); if (inheritInChildAppsAttribute != null) { inheritInChildApps = Boolean.Parse(inheritInChildAppsAttribute); } // Flag that we already have one of these locations configDefinitionUpdates.FlagLocationWritten(); } if (reader.IsEmptyElement) { if (elementLocationPathApplies && (configDefinitionUpdates.FindLocationUpdates(overrideMode, inheritInChildApps) != null)) { // If we are going to make updates here, then // delete the one that is here (so we can update later) elementLocationPathApplies = true; } else { // If not lets leave it elementLocationPathApplies = false; } } else { // recurse if this location applies to us if (elementLocationPathApplies) { if (configDefinitionUpdates != null) { recurseLocationUpdates = configDefinitionUpdates.FindLocationUpdates(overrideMode, inheritInChildApps); if (recurseLocationUpdates != null) { recurse = true; recurseSectionUpdates = recurseLocationUpdates.SectionUpdates; // If this is <location path=".">, we don't want to add moved sections // to it. if (_locationSubPath == null && recurseLocationUpdates.IsDefault) { recurseAddNewSections = false; } } } } else { // recurse if necessary to remove items in _removedSections and _removedGroups if (HasRemovedSectionsOrGroups && !IsLocationConfig && Host.SupportsLocation) { recurse = true; recurseLocationUpdates = null; recurseSectionUpdates = null; recurseAddNewSections = false; } } } } else { string configKey = CombineConfigKey(group, elementName); FactoryRecord factoryRecord = FindFactoryRecord(configKey, false); if (factoryRecord == null) { // The factory was deleted, so regardless of whether this is a // section or sectionGroup, it can be skipped. if (!elementLocationPathApplies && !IsLocationConfig) { removedSectionOrGroup = true; } } else if (factoryRecord.IsGroup) { if (reader.IsEmptyElement) { if (!elementLocationPathApplies && !IsLocationConfig) { removedSectionOrGroup = true; } } else { // if the location path applies, recurse if there are updates if (sectionUpdates != null) { SectionUpdates sectionUpdatesChild = sectionUpdates.GetSectionUpdatesForGroup(elementName); if (sectionUpdatesChild != null) { recurse = true; recurseGroup = configKey; recurseSectionUpdates = sectionUpdatesChild; } } else if (!elementLocationPathApplies && !IsLocationConfig) { if (_removedSectionGroups != null && _removedSectionGroups.Contains(configKey)) { removedSectionOrGroup = true; } else { recurse = true; recurseGroup = configKey; recurseLocationUpdates = null; recurseSectionUpdates = null; recurseAddNewSections = false; } } } } else { // it is a section - get the update if (sectionUpdates != null) { update = sectionUpdates.GetDefinitionUpdate(configKey); } else if (!elementLocationPathApplies && !IsLocationConfig) { if (_removedSections != null && _removedSections.Contains(configKey)) { removedSectionOrGroup = true; } } } } if (recurse) { #if DBG string startElementName = reader.Name; #endif // flush, and get length of underlying stream object checkpoint = utilWriter.CreateStreamCheckpoint(); // Copy this element node and up to the first subelement xmlUtil.CopyXmlNode(utilWriter); xmlUtil.CopyReaderToNextElement(utilWriter, true); // Recurse bool recurseWroteASection = CopyConfigDefinitionsRecursive( configDefinitionUpdates, xmlUtil, utilWriter, elementLocationPathApplies, recurseLocationUpdates, recurseSectionUpdates, recurseAddNewSections, recurseGroup, linePosition, indent); // Copy the end element xmlUtil.CopyXmlNode(utilWriter); if (recurseWroteASection) { wroteASection = true; } else { // back out the change utilWriter.RestoreStreamCheckpoint(checkpoint); } // Copy up to the next element, or exit this level. xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool skip; if (update == null) { // remove the section from the file if we're in the correct location, // or if the section or group should be removed from all locations skip = elementLocationPathApplies || removedSectionOrGroup; } else { // replace the section if the xml for it has been updated // if it is a configSource, don't write it unless the configSource parameters have changed skip = false; if (update.UpdatedXml != null) { ConfigurationSection configSection = (ConfigurationSection) update.SectionRecord.Result; if ( String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource) || configSection.SectionInformation.ConfigSourceModified) { skip = true; WriteSectionUpdate(utilWriter, update, linePosition, indent, true); wroteASection = true; } } } if (skip) { // // Skip over the existing element, then // copy up to the next element, or exit this level. // xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { // Copy this entire contents of this element and then to the next element, or exit this level. xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); wroteASection = true; } } } } // // Write new section groups // if (sectionUpdates != null && addNewSections && sectionUpdates.HasNewSectionGroups()) { // Add whitespace to align us with the other elements in this group linePosition = parentLinePosition + indent; if (reader.NodeType == XmlNodeType.EndElement) { if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { startingLinePosition = 0; } utilWriter.AppendSpacesToLinePosition(linePosition); bool wroteNewSection = WriteNewConfigDefinitionsRecursive(utilWriter, sectionUpdates, linePosition, indent, true); if (wroteNewSection) { wroteASection = true; } // Restore the whitespace of the end element utilWriter.AppendSpacesToLinePosition(startingLinePosition); } return wroteASection; }
// Copy a config file, replacing sections with updates. private void CopyConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, byte[] buffer, string filename, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { CheckPreamble(ConfigStreamInfo.StreamEncoding.GetPreamble(), utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, filename, false)) { // copy up to the <configuration> node XmlTextReader reader = xmlUtil.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); xmlUtil.CopyReaderToNextElement(utilWriter, false); Debug.Assert(reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGURATION, "reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGURATION"); int indent = DEFAULT_INDENT; int configurationElementLinePosition = xmlUtil.TrueLinePosition; bool isEmptyConfigurationElement = reader.IsEmptyElement; // copy <configuration> node // if the node is an empty element, we may need to open it. string configurationStartElement; if (namespaceChange == NamespaceChange.Add) { configurationStartElement = string.Format( CultureInfo.InvariantCulture, FORMAT_CONFIGURATION_NAMESPACE, KEYWORD_CONFIGURATION_NAMESPACE); } else if (namespaceChange == NamespaceChange.Remove) { configurationStartElement = FORMAT_CONFIGURATION; } else { configurationStartElement = null; } bool needsChildren = (declarationUpdates != null || definitionUpdates != null); string configurationEndElement = xmlUtil.UpdateStartElement(utilWriter, configurationStartElement, needsChildren, configurationElementLinePosition, indent); bool foundConfigSectionsElement = false; if (!isEmptyConfigurationElement) { // copy up to the first element under <configuration> xmlUtil.CopyReaderToNextElement(utilWriter, true); // updateIndent indent = UpdateIndent(indent, xmlUtil, utilWriter, configurationElementLinePosition); if (reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGSECTIONS) { foundConfigSectionsElement = true; int configSectionsElementLinePosition = xmlUtil.TrueLinePosition; bool isEmptyConfigSectionsElement = reader.IsEmptyElement; // if no updates, copy the entire <configSections> element if (declarationUpdates == null) { xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } else { // copy <configSections>, and open it if it is an empty element string configSectionsEndElement = xmlUtil.UpdateStartElement( utilWriter, null, true, configSectionsElementLinePosition, indent); if (!isEmptyConfigSectionsElement) { // copy to next element under <configSections>, or up to closing </configSections> xmlUtil.CopyReaderToNextElement(utilWriter, true); // copy config declarations CopyConfigDeclarationsRecursive(declarationUpdates, xmlUtil, utilWriter, string.Empty, configSectionsElementLinePosition, indent); Debug.Assert(reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGSECTIONS, "reader.NodeType == XmlNodeType.EndElement && reader.Name == \"KEYWORD_CONFIGSECTIONS\""); } // write declarations not written by above copy if (declarationUpdates.HasUnretrievedSections()) { // determine the line position of the end element int endElementLinePosition = 0; if (configSectionsEndElement == null) { endElementLinePosition = xmlUtil.TrueLinePosition; } // indent a new line if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, configSectionsElementLinePosition + indent, indent, false); // restore spaces to end element if (configSectionsEndElement == null) { utilWriter.AppendSpacesToLinePosition(endElementLinePosition); } } // Copy the </configSections> element if (configSectionsEndElement == null) { xmlUtil.CopyXmlNode(utilWriter); } else { // note that configSectionsEndElement already contains the proper indenting utilWriter.Write(configSectionsEndElement); } // copy up to the next element under <configuration>, or up to closing </configSections> xmlUtil.CopyReaderToNextElement(utilWriter, true); } } } // Write new declarations if (!foundConfigSectionsElement && declarationUpdates != null) { bool skipFirstIndent = reader.Depth > 0 && reader.NodeType == XmlNodeType.Element; int newConfigSectionsLinePosition; if (skipFirstIndent) { newConfigSectionsLinePosition = xmlUtil.TrueLinePosition; } else { newConfigSectionsLinePosition = configurationElementLinePosition + indent; } WriteNewConfigDeclarations(declarationUpdates, utilWriter, newConfigSectionsLinePosition, indent, skipFirstIndent); } if (definitionUpdates != null) { // // Copy sections recursively. In the file we copy we start out at // location path="." allowOverride="true" inheritInChildApps="true" // bool locationPathApplies = false; LocationUpdates locationUpdates = null; SectionUpdates sectionUpdates = null; if (!IsLocationConfig) { locationPathApplies = true; locationUpdates = definitionUpdates.FindLocationUpdates(OverrideModeSetting.LocationDefault, true); if (locationUpdates != null) { sectionUpdates = locationUpdates.SectionUpdates; } } CopyConfigDefinitionsRecursive(definitionUpdates, xmlUtil, utilWriter, locationPathApplies, locationUpdates, sectionUpdates, true, string.Empty, configurationElementLinePosition, indent); // Write new config sections from new groups. WriteNewConfigDefinitions(definitionUpdates, utilWriter, configurationElementLinePosition + indent, indent); #if DBG Debug.Assert(configurationEndElement != null || (reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGURATION), "configurationEndElement != null || (reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGURATION)"); #endif #if DBG { foreach (LocationUpdates l in definitionUpdates.LocationUpdatesList) { Debug.Assert(!l.SectionUpdates.HasUnretrievedSections(), "!l.SectionUpdates.HasUnretrievedSections()"); } } #endif } if (configurationEndElement != null) { // If we have to add closing config tag, then do it now // before copying extra whitespace/comments if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.Write(configurationEndElement); } // // Copy the remainder of the file, the closing </configuration> node plus any whitespace // and comments // while (xmlUtil.CopyXmlNode(utilWriter)) { } } } }
private void CopyConfigSource(XmlUtilWriter utilWriter, string updatedXml, string configSourceStreamName, byte[] buffer) { byte[] preamble; using (Stream stream = new MemoryStream(buffer)) { using (new XmlUtil(stream, configSourceStreamName, true)) { preamble = base.ConfigStreamInfo.StreamEncoding.GetPreamble(); } } this.CheckPreamble(preamble, utilWriter, buffer); using (Stream stream2 = new MemoryStream(buffer)) { using (XmlUtil util2 = new XmlUtil(stream2, configSourceStreamName, false)) { XmlTextReader reader = util2.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); int indent = 4; int linePosition = 1; bool flag = util2.CopyReaderToNextElement(utilWriter, false); if (flag) { int lineNumber = reader.LineNumber; linePosition = reader.LinePosition - 1; int num4 = 0; while (reader.MoveToNextAttribute()) { if (reader.LineNumber > lineNumber) { num4 = reader.LinePosition - linePosition; break; } } int num5 = 0; reader.Read(); while (reader.Depth >= 1) { if (reader.NodeType == XmlNodeType.Element) { num5 = (reader.LinePosition - 1) - linePosition; break; } reader.Read(); } if (num5 > 0) { indent = num5; } else if (num4 > 0) { indent = num4; } } string s = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, true); utilWriter.Write(s); if (flag) { while (reader.Depth > 0) { reader.Read(); } if (reader.IsEmptyElement || (reader.NodeType == XmlNodeType.EndElement)) { reader.Read(); } while (util2.CopyXmlNode(utilWriter)) { } } } } }
private bool CopyConfigDefinitionsRecursive(ConfigDefinitionUpdates configDefinitionUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, bool locationPathApplies, LocationUpdates locationUpdates, SectionUpdates sectionUpdates, bool addNewSections, string group, int parentLinePosition, int parentIndent) { int trueLinePosition; int num3; bool flag = false; XmlTextReader reader = xmlUtil.Reader; int indent = this.UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { trueLinePosition = xmlUtil.TrueLinePosition; num3 = trueLinePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { trueLinePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { trueLinePosition = parentLinePosition + indent; num3 = 0; } if ((sectionUpdates != null) && addNewSections) { sectionUpdates.IsNew = false; string[] movedSectionNames = sectionUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.AppendSpacesToLinePosition(trueLinePosition); bool skipFirstIndent = true; foreach (string str in movedSectionNames) { DefinitionUpdate definitionUpdate = sectionUpdates.GetDefinitionUpdate(str); this.WriteSectionUpdate(utilWriter, definitionUpdate, trueLinePosition, indent, skipFirstIndent); skipFirstIndent = false; utilWriter.AppendNewLine(); flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } } if (reader.NodeType == XmlNodeType.Element) { int depth = reader.Depth; while (reader.Depth == depth) { bool flag3 = false; DefinitionUpdate update = null; bool flag4 = locationPathApplies; LocationUpdates updates = locationUpdates; SectionUpdates updates2 = sectionUpdates; bool flag5 = addNewSections; string str2 = group; bool flag6 = false; indent = this.UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); trueLinePosition = xmlUtil.TrueLinePosition; string name = reader.Name; if (name == "location") { string locationSubPath = BaseConfigurationRecord.NormalizeLocationSubPath(reader.GetAttribute("path"), xmlUtil); flag4 = false; OverrideModeSetting locationDefault = OverrideModeSetting.LocationDefault; bool inheritInChildApps = true; if (base.IsLocationConfig) { if (locationSubPath == null) { flag4 = false; } else { flag4 = StringUtil.EqualsIgnoreCase(base.ConfigPath, base.Host.GetConfigPathFromLocationSubPath(base.Parent.ConfigPath, locationSubPath)); } } else { flag4 = locationSubPath == null; } if (flag4) { string attribute = reader.GetAttribute("allowOverride"); if (attribute != null) { locationDefault = OverrideModeSetting.CreateFromXmlReadValue(bool.Parse(attribute)); } string str6 = reader.GetAttribute("overrideMode"); if (str6 != null) { locationDefault = OverrideModeSetting.CreateFromXmlReadValue(OverrideModeSetting.ParseOverrideModeXmlValue(str6, null)); } string str7 = reader.GetAttribute("inheritInChildApplications"); if (str7 != null) { inheritInChildApps = bool.Parse(str7); } configDefinitionUpdates.FlagLocationWritten(); } if (reader.IsEmptyElement) { if (flag4 && (configDefinitionUpdates.FindLocationUpdates(locationDefault, inheritInChildApps) != null)) { flag4 = true; } else { flag4 = false; } } else if (flag4) { if (configDefinitionUpdates != null) { updates = configDefinitionUpdates.FindLocationUpdates(locationDefault, inheritInChildApps); if (updates != null) { flag3 = true; updates2 = updates.SectionUpdates; if ((base._locationSubPath == null) && updates.IsDefault) { flag5 = false; } } } } else if ((this.HasRemovedSectionsOrGroups && !base.IsLocationConfig) && base.Host.SupportsLocation) { flag3 = true; updates = null; updates2 = null; flag5 = false; } } else { string configKey = BaseConfigurationRecord.CombineConfigKey(group, name); FactoryRecord record = base.FindFactoryRecord(configKey, false); if (record == null) { if (!flag4 && !base.IsLocationConfig) { flag6 = true; } } else if (record.IsGroup) { if (reader.IsEmptyElement) { if (!flag4 && !base.IsLocationConfig) { flag6 = true; } } else if (sectionUpdates != null) { SectionUpdates sectionUpdatesForGroup = sectionUpdates.GetSectionUpdatesForGroup(name); if (sectionUpdatesForGroup != null) { flag3 = true; str2 = configKey; updates2 = sectionUpdatesForGroup; } } else if (!flag4 && !base.IsLocationConfig) { if ((this._removedSectionGroups != null) && this._removedSectionGroups.Contains(configKey)) { flag6 = true; } else { flag3 = true; str2 = configKey; updates = null; updates2 = null; flag5 = false; } } } else if (sectionUpdates != null) { update = sectionUpdates.GetDefinitionUpdate(configKey); } else if ((!flag4 && !base.IsLocationConfig) && ((this._removedSections != null) && this._removedSections.Contains(configKey))) { flag6 = true; } } if (flag3) { object o = utilWriter.CreateStreamCheckpoint(); xmlUtil.CopyXmlNode(utilWriter); xmlUtil.CopyReaderToNextElement(utilWriter, true); bool flag8 = this.CopyConfigDefinitionsRecursive(configDefinitionUpdates, xmlUtil, utilWriter, flag4, updates, updates2, flag5, str2, trueLinePosition, indent); xmlUtil.CopyXmlNode(utilWriter); if (flag8) { flag = true; } else { utilWriter.RestoreStreamCheckpoint(o); } xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool flag9; if (update == null) { flag9 = flag4 || flag6; } else { flag9 = false; if (update.UpdatedXml != null) { ConfigurationSection result = (ConfigurationSection) update.SectionRecord.Result; if (string.IsNullOrEmpty(result.SectionInformation.ConfigSource) || result.SectionInformation.ConfigSourceModified) { flag9 = true; this.WriteSectionUpdate(utilWriter, update, trueLinePosition, indent, true); flag = true; } } } if (flag9) { xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); flag = true; } } } } if (((sectionUpdates != null) && addNewSections) && sectionUpdates.HasNewSectionGroups()) { trueLinePosition = parentLinePosition + indent; if (reader.NodeType == XmlNodeType.EndElement) { if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { num3 = 0; } utilWriter.AppendSpacesToLinePosition(trueLinePosition); if (this.WriteNewConfigDefinitionsRecursive(utilWriter, sectionUpdates, trueLinePosition, indent, true)) { flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } return flag; }
private bool CopyConfigDeclarationsRecursive(SectionUpdates declarationUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, string group, int parentLinePosition, int parentIndent) { int trueLinePosition; int num3; bool flag = false; XmlTextReader reader = xmlUtil.Reader; int oldIndent = this.UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { trueLinePosition = xmlUtil.TrueLinePosition; num3 = trueLinePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { trueLinePosition = parentLinePosition + oldIndent; if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { trueLinePosition = parentLinePosition + oldIndent; num3 = 0; } if (declarationUpdates != null) { string[] movedSectionNames = declarationUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } foreach (string str in movedSectionNames) { DeclarationUpdate declarationUpdate = declarationUpdates.GetDeclarationUpdate(str); utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write(declarationUpdate.UpdatedXml); utilWriter.AppendNewLine(); flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } } if (reader.NodeType == XmlNodeType.Element) { int depth = reader.Depth; while (reader.Depth == depth) { bool flag2 = false; DeclarationUpdate update2 = null; DeclarationUpdate sectionGroupUpdate = null; SectionUpdates sectionUpdatesForGroup = null; SectionUpdates updates2 = declarationUpdates; string str2 = group; oldIndent = this.UpdateIndent(oldIndent, xmlUtil, utilWriter, parentLinePosition); trueLinePosition = xmlUtil.TrueLinePosition; string name = reader.Name; string attribute = reader.GetAttribute("name"); string configKey = BaseConfigurationRecord.CombineConfigKey(group, attribute); if (name == "sectionGroup") { sectionUpdatesForGroup = declarationUpdates.GetSectionUpdatesForGroup(attribute); if (sectionUpdatesForGroup != null) { sectionGroupUpdate = sectionUpdatesForGroup.GetSectionGroupUpdate(); if (sectionUpdatesForGroup.HasUnretrievedSections()) { flag2 = true; str2 = configKey; updates2 = sectionUpdatesForGroup; } } } else { update2 = declarationUpdates.GetDeclarationUpdate(configKey); } bool flag3 = (sectionGroupUpdate != null) && (sectionGroupUpdate.UpdatedXml != null); if (flag2) { object o = utilWriter.CreateStreamCheckpoint(); string s = null; if (flag3) { utilWriter.Write(sectionGroupUpdate.UpdatedXml); reader.Read(); } else { s = xmlUtil.UpdateStartElement(utilWriter, null, true, trueLinePosition, oldIndent); } if (s == null) { xmlUtil.CopyReaderToNextElement(utilWriter, true); } bool flag4 = this.CopyConfigDeclarationsRecursive(updates2, xmlUtil, utilWriter, str2, trueLinePosition, oldIndent); if (s != null) { utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write(s); utilWriter.AppendSpacesToLinePosition(parentLinePosition); } else { xmlUtil.CopyXmlNode(utilWriter); } if (flag4 || flag3) { flag = true; } else { utilWriter.RestoreStreamCheckpoint(o); } xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool flag5; bool flag6 = false; if (update2 == null) { flag5 = true; if (flag3) { flag = true; utilWriter.Write(sectionGroupUpdate.UpdatedXml); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write("</sectionGroup>"); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(trueLinePosition); } else if (sectionGroupUpdate != null) { flag = true; flag5 = false; flag6 = true; } } else { flag = true; if (update2.UpdatedXml == null) { flag5 = false; } else { flag5 = true; utilWriter.Write(update2.UpdatedXml); } } if (flag5) { xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { if (flag6) { xmlUtil.SkipChildElementsAndCopyOuterXmlToNextElement(utilWriter); continue; } xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } } } } return flag; }
private void CopyConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, byte[] buffer, string filename, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { this.CheckPreamble(base.ConfigStreamInfo.StreamEncoding.GetPreamble(), utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil util = new XmlUtil(stream, filename, false)) { string str; XmlTextReader reader = util.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); util.CopyReaderToNextElement(utilWriter, false); int indent = 4; int trueLinePosition = util.TrueLinePosition; bool isEmptyElement = reader.IsEmptyElement; if (namespaceChange == NamespaceChange.Add) { str = string.Format(CultureInfo.InvariantCulture, "<configuration xmlns=\"{0}\">\r\n", new object[] { "http://schemas.microsoft.com/.NetConfiguration/v2.0" }); } else if (namespaceChange == NamespaceChange.Remove) { str = "<configuration>\r\n"; } else { str = null; } bool needsChildren = (declarationUpdates != null) || (definitionUpdates != null); string s = util.UpdateStartElement(utilWriter, str, needsChildren, trueLinePosition, indent); bool flag3 = false; if (!isEmptyElement) { util.CopyReaderToNextElement(utilWriter, true); indent = this.UpdateIndent(indent, util, utilWriter, trueLinePosition); if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "configSections")) { flag3 = true; int linePosition = util.TrueLinePosition; bool flag4 = reader.IsEmptyElement; if (declarationUpdates == null) { util.CopyOuterXmlToNextElement(utilWriter, true); } else { string str3 = util.UpdateStartElement(utilWriter, null, true, linePosition, indent); if (!flag4) { util.CopyReaderToNextElement(utilWriter, true); this.CopyConfigDeclarationsRecursive(declarationUpdates, util, utilWriter, string.Empty, linePosition, indent); } if (declarationUpdates.HasUnretrievedSections()) { int num4 = 0; if (str3 == null) { num4 = util.TrueLinePosition; } if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } this.WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, linePosition + indent, indent, false); if (str3 == null) { utilWriter.AppendSpacesToLinePosition(num4); } } if (str3 == null) { util.CopyXmlNode(utilWriter); } else { utilWriter.Write(str3); } util.CopyReaderToNextElement(utilWriter, true); } } } if (!flag3 && (declarationUpdates != null)) { int num5; bool skipFirstIndent = (reader.Depth > 0) && (reader.NodeType == XmlNodeType.Element); if (skipFirstIndent) { num5 = util.TrueLinePosition; } else { num5 = trueLinePosition + indent; } this.WriteNewConfigDeclarations(declarationUpdates, utilWriter, num5, indent, skipFirstIndent); } if (definitionUpdates != null) { bool locationPathApplies = false; LocationUpdates locationUpdates = null; SectionUpdates sectionUpdates = null; if (!base.IsLocationConfig) { locationPathApplies = true; locationUpdates = definitionUpdates.FindLocationUpdates(OverrideModeSetting.LocationDefault, true); if (locationUpdates != null) { sectionUpdates = locationUpdates.SectionUpdates; } } this.CopyConfigDefinitionsRecursive(definitionUpdates, util, utilWriter, locationPathApplies, locationUpdates, sectionUpdates, true, string.Empty, trueLinePosition, indent); this.WriteNewConfigDefinitions(definitionUpdates, utilWriter, trueLinePosition + indent, indent); } if (s != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.Write(s); } while (util.CopyXmlNode(utilWriter)) { } } } }