X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Configuration%2FSystem.Configuration%2FConfiguration.cs;h=9f6a3ae117511a6d8f2c1030543d4a3fb9d25616;hb=ec3a87f0fdb71dfe4ee5727dc45a9ddbd817345f;hp=1b84a74efc0904df5239b1430112c3478051822e;hpb=65ea1509d38859e9ef15dca4f8092f21670f88a4;p=mono.git diff --git a/mcs/class/System.Configuration/System.Configuration/Configuration.cs b/mcs/class/System.Configuration/System.Configuration/Configuration.cs index 1b84a74efc0..9f6a3ae1175 100644 --- a/mcs/class/System.Configuration/System.Configuration/Configuration.cs +++ b/mcs/class/System.Configuration/System.Configuration/Configuration.cs @@ -47,13 +47,18 @@ namespace System.Configuration { SectionGroupInfo rootGroup; IConfigSystem system; bool hasFile; + string rootNamespace; string configPath; string locationConfigPath; - - internal Configuration (Configuration parent) + string locationSubPath; + + internal Configuration (Configuration parent, string locationSubPath) { - Init (parent.system, null, parent); + this.parent = parent; + this.system = parent.system; + this.rootGroup = parent.rootGroup; + this.locationSubPath = locationSubPath; } internal Configuration (InternalConfigurationSystem system, string locationSubPath) @@ -98,6 +103,7 @@ namespace System.Configuration { internal void Init (IConfigSystem system, string configPath, Configuration parent) { this.system = system; + this.configPath = configPath; streamName = system.Host.GetStreamName (configPath); this.parent = parent; if (parent != null) @@ -107,7 +113,7 @@ namespace System.Configuration { rootGroup.StreamName = streamName; } - if (configPath != null) + if (streamName != null) Load (); } @@ -136,20 +142,40 @@ namespace System.Configuration { get { return locationConfigPath; } } + internal string GetLocationSubPath () + { + Configuration confg = parent; + string path = null; + while (confg != null) { + path = confg.locationSubPath; + if (!String.IsNullOrEmpty (path)) + return path; + confg = confg.parent; + } + return path; + } + internal string ConfigPath { get { return configPath; } } public AppSettingsSection AppSettings { - get { return Sections ["appSettings"] as AppSettingsSection; } + get { return (AppSettingsSection) GetSection ("appSettings"); } } public ConnectionStringsSection ConnectionStrings { get { return (ConnectionStringsSection) GetSection ("connectionStrings"); } } + // MSDN: If the value for this FilePath property represents a merged view and + // no actual file exists for the application, the path to the parent configuration + // file is returned. public string FilePath { - get { return streamName; } + get { + if (streamName == null && parent != null) + return parent.FilePath; + return streamName; + } } public bool HasFile { @@ -157,6 +183,19 @@ namespace System.Configuration { return hasFile; } } + + ContextInformation evaluationContext; + public ContextInformation EvaluationContext { + get { + if (evaluationContext == null) { + object ctx = system.Host.CreateConfigurationContext (configPath, GetLocationSubPath() ); + evaluationContext = new ContextInformation (this, ctx); + } + + + return evaluationContext; + } + } public ConfigurationLocationCollection Locations { get { @@ -165,6 +204,11 @@ namespace System.Configuration { } } + public bool NamespaceDeclared { + get { return rootNamespace != null; } + set { rootNamespace = value ? "http://schemas.microsoft.com/.NetConfiguration/v2.0" : null; } + } + public ConfigurationSectionGroup RootSectionGroup { get { if (rootSectionGroup == null) { @@ -214,19 +258,24 @@ namespace System.Configuration { ConfigurationSection sec = data as ConfigurationSection; if (sec != null || !createDefaultInstance) return sec; - object secObj = config.CreateInstance () as ConfigurationSection; - if (!(secObj is ConfigurationSection)) - sec = new RuntimeOnlySection (); - 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 (); } @@ -273,9 +322,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); @@ -293,6 +340,8 @@ namespace System.Configuration { section.ConfigHost = system.Host; parentGroup.AddChild (section); elementData [section] = sec; + + sec.Initialize (this, section); } internal void RemoveConfigInfo (ConfigInfo config) @@ -317,7 +366,7 @@ namespace System.Configuration { try { Save (stream, mode, forceUpdateAll); system.Host.WriteCompleted (streamName, true, ctx); - } catch (Exception ex) { + } catch (Exception) { system.Host.WriteCompleted (streamName, false, ctx); throw; } finally { @@ -334,19 +383,26 @@ namespace System.Configuration { { SaveAs (filename, mode, false); } - - [MonoTODO ("Detect if file has changed")] + + [MonoInternalNote ("Detect if file has changed")] public void SaveAs (string filename, ConfigurationSaveMode mode, bool forceUpdateAll) { - Save (new FileStream (filename, FileMode.Open, FileAccess.Write), mode, forceUpdateAll); + string dir = Path.GetDirectoryName (Path.GetFullPath (filename)); + if (!Directory.Exists (dir)) + Directory.CreateDirectory (dir); + Save (new FileStream (filename, FileMode.OpenOrCreate, FileAccess.Write), mode, forceUpdateAll); } - + void Save (Stream stream, ConfigurationSaveMode mode, bool forceUpdateAll) { 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); } @@ -381,20 +437,24 @@ namespace System.Configuration { bool Load () { - if (streamName == null) + if (String.IsNullOrEmpty (streamName)) return true; - - Stream stream = system.Host.OpenStreamForRead (streamName); + XmlTextReader reader = null; + Stream stream = null; + + // FIXME: we should remove this kind of hack that + // hides the actual error + try { + stream = system.Host.OpenStreamForRead (streamName); + } catch (Exception) { + return false; + } try { reader = new XmlTextReader (stream); ReadConfigFile (reader, streamName); -/* } catch (ConfigurationException) { - throw; - } catch (Exception e) { - throw new ConfigurationException ("Error reading " + fileName, e); -*/ } finally { + } finally { if (reader != null) reader.Close(); } @@ -405,11 +465,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 (); @@ -431,7 +501,7 @@ namespace System.Configuration { internal void ReadData (XmlTextReader reader, bool allowOverride) { - rootGroup.ReadRootData (reader, this, allowOverride); + rootGroup.ReadData (this, reader, allowOverride); }