Copy from 72246 to trunk
[mono.git] / mcs / class / System.Configuration / System.Configuration / Configuration.cs
index 610e8fa061d32de2b67c52f31b8d5c27868c6cb4..19d71b61434779b30576617bbb2e38852950d701 100644 (file)
@@ -47,13 +47,16 @@ namespace System.Configuration {
                SectionGroupInfo rootGroup;
                IConfigSystem system;
                bool hasFile;
+               string rootNamespace;
                
                string configPath;
                string locationConfigPath;
                        
                internal Configuration (Configuration parent)
                {
-                       Init (parent.system, null, parent);
+                       this.parent = parent;
+                       this.system = parent.system;
+                       this.rootGroup = parent.rootGroup;
                }
                
                internal Configuration (InternalConfigurationSystem system, string locationSubPath)
@@ -108,7 +111,7 @@ namespace System.Configuration {
                                rootGroup.StreamName = streamName;
                        }
                        
-                       if (configPath != null)
+                       if (streamName != null)
                                Load ();
                }
                
@@ -176,14 +179,9 @@ namespace System.Configuration {
                        }
                }
 
-               [MonoTODO]
                public bool NamespaceDeclared {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-                       set {
-                               throw new NotImplementedException ();
-                       }
+                       get { return rootNamespace != null; }
+                       set { rootNamespace = value ? "http://schemas.microsoft.com/.NetConfiguration/v2.0" : null; }
                }
 
                public ConfigurationSectionGroup RootSectionGroup {
@@ -235,18 +233,24 @@ namespace System.Configuration {
                        ConfigurationSection sec = data as ConfigurationSection;
                        if (sec != null || !createDefaultInstance) return sec;
                        
-                       object secObj = config.CreateInstance () as ConfigurationSection;
-                       if (secObj == null)
-                               sec = new IgnoreSection ();
-                       else
-                               sec = (ConfigurationSection) secObj;
-                               
+                       object secObj = config.CreateInstance ();
+                       sec = secObj as ConfigurationSection;
+                       if (sec == null) {
+                               DefaultSection ds = new DefaultSection ();
+                               ds.SectionHandler = secObj as IConfigurationSectionHandler;
+                               sec = ds;
+                       }
+
                        ConfigurationSection parentSection = parent != null ? parent.GetSectionInstance (config, true) : null;
-                       sec.RawXml = data as string;
+
+                       string xml = data as string;
+                       if (xml == null && parentSection != null)
+                               xml = parentSection.RawXml;
+                       sec.RawXml = xml;
                        sec.Reset (parentSection);
-                       
-                       if (data != null) {
-                               XmlTextReader r = new XmlTextReader (new StringReader (data as string));
+
+                       if (xml != null && xml == data) {
+                               XmlTextReader r = new XmlTextReader (new StringReader (xml));
                                sec.DeserializeSection (r);
                                r.Close ();
                        }
@@ -293,9 +297,7 @@ namespace System.Configuration {
                        if (sec.SectionInformation.Type == null)
                                sec.SectionInformation.Type = system.Host.GetConfigTypeName (sec.GetType ());
                        
-                       sec.SectionInformation.SetName (name);
-
-                       SectionInfo section = new SectionInfo (name, sec.SectionInformation.Type, sec.SectionInformation.AllowLocation, sec.SectionInformation.AllowDefinition, sec.SectionInformation.AllowExeDefinition);
+                       SectionInfo section = new SectionInfo (name, sec.SectionInformation);
                        section.StreamName = streamName;
                        section.ConfigHost = system.Host;
                        group.AddChild (section);
@@ -358,7 +360,7 @@ namespace System.Configuration {
                [MonoTODO ("Detect if file has changed")]
                public void SaveAs (string filename, ConfigurationSaveMode mode, bool forceUpdateAll)
                {
-                       Save (new FileStream (filename, FileMode.Open, FileAccess.Write), mode, forceUpdateAll);
+                       Save (new FileStream (filename, FileMode.OpenOrCreate, FileAccess.Write), mode, forceUpdateAll);
                }
 
                void Save (Stream stream, ConfigurationSaveMode mode, bool forceUpdateAll)
@@ -366,7 +368,11 @@ namespace System.Configuration {
                        XmlTextWriter tw = new XmlTextWriter (new StreamWriter (stream));
                        tw.Formatting = Formatting.Indented;
                        try {
-                               tw.WriteStartElement ("configuration");
+                               tw.WriteStartDocument ();
+                               if (rootNamespace != null)
+                                       tw.WriteStartElement ("configuration", rootNamespace);
+                               else
+                                       tw.WriteStartElement ("configuration");
                                if (rootGroup.HasConfigContent (this)) {
                                        rootGroup.WriteConfig (this, tw, mode);
                                }
@@ -401,16 +407,21 @@ namespace System.Configuration {
                
                bool Load ()
                {
-                       if (streamName == null)
+                       if (streamName == null || streamName == "")
                                return true;
 
                        XmlTextReader reader = null;
+                       Stream stream = null;
+                       
                        try {
-                               Stream stream = system.Host.OpenStreamForRead (streamName);
-                               reader = new XmlTextReader (stream);
-                               ReadConfigFile (reader, streamName);
+                               stream = system.Host.OpenStreamForRead (streamName);
                        } catch (Exception e) {
                                return false;
+                       }
+
+                       try {
+                               reader = new XmlTextReader (stream);
+                               ReadConfigFile (reader, streamName);
                        } finally {
                                if (reader != null)
                                        reader.Close();
@@ -422,11 +433,21 @@ namespace System.Configuration {
                internal void ReadConfigFile (XmlTextReader reader, string fileName)
                {
                        reader.MoveToContent ();
+
                        if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration")
                                ThrowException ("Configuration file does not have a valid root element", reader);
 
-                       if (reader.HasAttributes)
-                               ThrowException ("Unrecognized attribute in root element", reader);
+                       if (reader.HasAttributes) {
+                               while (reader.MoveToNextAttribute ()) {
+                                       if (reader.LocalName == "xmlns") {
+                                               rootNamespace = reader.Value;
+                                               continue;
+                                       }
+                                       ThrowException (String.Format ("Unrecognized attribute '{0}' in root element", reader.LocalName), reader);
+                               }
+                       }
+
+                       reader.MoveToElement ();
 
                        if (reader.IsEmptyElement) {
                                reader.Skip ();
@@ -448,7 +469,7 @@ namespace System.Configuration {
                
                internal void ReadData (XmlTextReader reader, bool allowOverride)
                {
-                       rootGroup.ReadRootData (reader, this, allowOverride);
+                       rootGroup.ReadData (this, reader, allowOverride);
                }