2008-12-06 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System.Configuration / System.Configuration / SectionGroupInfo.cs
index 011276070f4a396a6b05784e9106d7f0d0935126..5332ef9bc9bb7a51dcfbf215d2dfb755bf2a1e88 100644 (file)
@@ -136,7 +136,7 @@ namespace System.Configuration
                        return false;
                }
                
-               public override void ReadConfig (Configuration cfg, string streamName, XmlTextReader reader)
+               public override void ReadConfig (Configuration cfg, string streamName, XmlReader reader)
                {
                        StreamName = streamName;
                        ConfigHost = cfg.ConfigHost;
@@ -198,9 +198,9 @@ namespace System.Configuration
 
                                if (name == "section")
                                        cinfo = new SectionInfo ();
-                               else if (name == "sectionGroup")
+                               else if (name == "sectionGroup") {
                                        cinfo = new SectionGroupInfo ();
-                               else
+                               else
                                        ThrowException ("Unrecognized element: " + reader.Name, reader);
                                        
                                cinfo.ReadConfig (cfg, streamName, reader);
@@ -210,6 +210,9 @@ namespace System.Configuration
                                if (actInfo != null) {
                                        if (actInfo.GetType () != cinfo.GetType ())
                                                ThrowException ("A section or section group named '" + cinfo.Name + "' already exists", reader);
+                                       // Merge all the new data
+                                       actInfo.Merge (cinfo);
+                                       
                                        // Make sure that this section is saved in this configuration file:
                                        actInfo.StreamName = streamName;
                                }
@@ -242,13 +245,13 @@ namespace System.Configuration
                        writer.WriteEndElement ();
                }
 
-               private void ReadRemoveSection (XmlTextReader reader)
+               private void ReadRemoveSection (XmlReader reader)
                {
                        if (!reader.MoveToNextAttribute () || reader.Name != "name")
                                ThrowException ("Unrecognized attribute.", reader);
 
                        string removeValue = reader.Value;
-                       if (removeValue == null || removeValue.Length == 0)
+                       if (String.IsNullOrEmpty (removeValue))
                                ThrowException ("Empty name to remove", reader);
 
                        reader.MoveToElement ();
@@ -260,32 +263,37 @@ namespace System.Configuration
                        reader.Skip ();
                }
 
-               public void ReadRootData (XmlTextReader reader, Configuration config, bool overrideAllowed)
+               public void ReadRootData (XmlReader reader, Configuration config, bool overrideAllowed)
                {
                        reader.MoveToContent ();
                        ReadContent (reader, config, overrideAllowed, true);
                }
                
-               public override void ReadData (Configuration config, XmlTextReader reader, bool overrideAllowed)
+               public override void ReadData (Configuration config, XmlReader reader, bool overrideAllowed)
                {
                        reader.MoveToContent ();
-                       reader.ReadStartElement ();
-                       ReadContent (reader, config, overrideAllowed, false);
-                       reader.MoveToContent ();
-                       reader.ReadEndElement ();
+                       if (!reader.IsEmptyElement) {
+                               reader.ReadStartElement ();
+                               ReadContent (reader, config, overrideAllowed, false);
+                               reader.MoveToContent ();
+                               reader.ReadEndElement ();
+                       } else
+                               reader.Read ();
                }
                
-               void ReadContent (XmlTextReader reader, Configuration config, bool overrideAllowed, bool root)
+               void ReadContent (XmlReader reader, Configuration config, bool overrideAllowed, bool root)
                {
-                       StringBuilder spacing = new StringBuilder ();
-                       while (reader.NodeType != XmlNodeType.EndElement) {
+                       while (reader.NodeType != XmlNodeType.EndElement && reader.NodeType != XmlNodeType.None) {
                                if (reader.NodeType != XmlNodeType.Element) {
-                                       if (reader.NodeType == XmlNodeType.Whitespace)
-                                               spacing.Append (reader.Value);
                                        reader.Skip ();
                                        continue;
                                }
-                               
+
+                               if (reader.LocalName == "dllmap") {
+                                       reader.Skip ();
+                                       continue;
+                               }
+
                                if (reader.LocalName == "location") {
                                        if (!root)
                                                ThrowException ("<location> elements are only allowed in <configuration> elements.", reader);
@@ -296,8 +304,13 @@ namespace System.Configuration
                                        if (path != null && path.Length > 0) {
                                                string xml = reader.ReadOuterXml ();
                                                string[] pathList = path.Split (',');
+                                               string tpath;
                                                foreach (string p in pathList) {
-                                                       ConfigurationLocation loc = new ConfigurationLocation (p.Trim (), xml, config, allowOverride);
+                                                       tpath = p.Trim ();
+                                                       if (config.Locations.Find (tpath) != null)
+                                                               ThrowException ("Sections must only appear once per config file.", reader);
+                                                       
+                                                       ConfigurationLocation loc = new ConfigurationLocation (tpath, xml, config, allowOverride);
                                                        config.Locations.Add (loc);
                                                }
                                        } else {
@@ -305,17 +318,61 @@ namespace System.Configuration
                                        }
                                        continue;
                                }
-
-                               
-                               ConfigInfo data = (sections != null) ? (ConfigInfo) sections [reader.LocalName] : (ConfigInfo) null;
-                               if (data == null) data = (groups != null) ? (ConfigInfo) groups [reader.LocalName] : (ConfigInfo) null;
-                               
+                       
+                               ConfigInfo data = GetConfigInfo (reader, this);
                                if (data != null)
                                        data.ReadData (config, reader, overrideAllowed);
                                else
                                        ThrowException ("Unrecognized configuration section <" + reader.LocalName + ">", reader);
                        }
                }
+
+               ConfigInfo GetConfigInfo (XmlReader reader, SectionGroupInfo current)
+               {
+                       ConfigInfo data = null;
+                       if (current.sections != null)
+                               data = current.sections [reader.LocalName];
+                       if (data != null)
+                               return data;
+                       if (current.groups != null)
+                               data = current.groups [reader.LocalName];
+                       if (data != null)
+                               return data;
+                       if (current.groups == null)
+                               return null;
+                       // It might be a section in descendant sectionGroups
+                       foreach (string key in current.groups.AllKeys) {
+                               data = GetConfigInfo (reader, (SectionGroupInfo) current.groups [key]);
+                               if (data != null)
+                                       return data;
+                       }
+                       
+                       // It might be in the root section group
+                       return null;
+               }
+
+               internal override void Merge (ConfigInfo newData)
+               {
+                       SectionGroupInfo data = newData as SectionGroupInfo;
+                       if (data == null)
+                               return;
+                       ConfigInfo actInfo;
+                       if (data.sections != null && data.sections.Count > 0)
+                               foreach (string key in data.sections.AllKeys) {
+                                       actInfo = sections[key];
+                                       if (actInfo != null)
+                                               continue;
+                                       sections.Add (key, data.sections[key]);
+                               }
+                       
+                       if (data.groups != null && data.sections != null && data.sections.Count > 0)
+                               foreach (string key in data.groups.AllKeys) {
+                                       actInfo = groups[key];
+                                       if (actInfo != null)
+                                               continue;
+                                       groups.Add (key, data.groups[key]);
+                               }
+               }
                
                public void WriteRootData (XmlWriter writer, Configuration config, ConfigurationSaveMode mode)
                {
@@ -343,6 +400,11 @@ namespace System.Configuration
        
        internal class ConfigInfoCollection : NameObjectCollectionBase
        {
+               public ConfigInfoCollection ()
+                       : base (StringComparer.Ordinal)
+               {
+               }
+
                public ICollection AllKeys
                {
                        get { return Keys; }