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=7660f0287462d77739659a3dad06ff279a0674f7;hpb=69c46832f89d2e03fe8def137a323c7807988e44;p=mono.git diff --git a/mcs/class/System.Configuration/System.Configuration/Configuration.cs b/mcs/class/System.Configuration/System.Configuration/Configuration.cs index 7660f028746..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) @@ -108,7 +113,7 @@ namespace System.Configuration { rootGroup.StreamName = streamName; } - if (configPath != null) + if (streamName != null) Load (); } @@ -137,6 +142,19 @@ 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; } } @@ -149,8 +167,15 @@ namespace System.Configuration { 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 { @@ -159,12 +184,15 @@ namespace System.Configuration { } } - [MonoTODO ("HostingContext")] ContextInformation evaluationContext; public ContextInformation EvaluationContext { get { - if (evaluationContext == null) - evaluationContext = new ContextInformation (this, null /* XXX */); + if (evaluationContext == null) { + object ctx = system.Host.CreateConfigurationContext (configPath, GetLocationSubPath() ); + evaluationContext = new ContextInformation (this, ctx); + } + + return evaluationContext; } } @@ -176,14 +204,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,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 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 (); } @@ -294,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); @@ -314,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) @@ -338,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 { @@ -355,11 +383,14 @@ 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) @@ -367,7 +398,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); } @@ -402,16 +437,23 @@ namespace System.Configuration { bool Load () { - if (streamName == null) + if (String.IsNullOrEmpty (streamName)) return true; 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 { - Stream stream = system.Host.OpenStreamForRead (streamName); reader = new XmlTextReader (stream); ReadConfigFile (reader, streamName); - } catch (Exception e) { - return false; } finally { if (reader != null) reader.Close(); @@ -423,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 (); @@ -449,7 +501,7 @@ namespace System.Configuration { internal void ReadData (XmlTextReader reader, bool allowOverride) { - rootGroup.ReadRootData (reader, this, allowOverride); + rootGroup.ReadData (this, reader, allowOverride); }