X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem%2FSystem.Configuration%2FConfigurationSettings.cs;h=199d83fe7bb383121660fd6e0dc5199d262e4321;hb=75883dc733e1e318c83ff2eab3c408d2926301f3;hp=a6ec20cc07da06fa01f5c9fc72e06d4c052803e3;hpb=f55d328a2f3ce76097d8bccb53861b7ff356fb78;p=mono.git diff --git a/mcs/class/System/System.Configuration/ConfigurationSettings.cs b/mcs/class/System/System.Configuration/ConfigurationSettings.cs index a6ec20cc07d..199d83fe7bb 100644 --- a/mcs/class/System/System.Configuration/ConfigurationSettings.cs +++ b/mcs/class/System/System.Configuration/ConfigurationSettings.cs @@ -32,7 +32,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if CONFIGURATION_DEP +#if CONFIGURATION_DEP && !TARGET_JVM extern alias PrebuiltSystem; using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection; #endif @@ -47,12 +47,32 @@ using System.Security.Permissions; using System.Xml; using System.Xml.XPath; #endif +#if TARGET_JVM +using vmw.common; +using vmw.@internal.io; +#endif namespace System.Configuration { public sealed class ConfigurationSettings { - static IConfigurationSystem config = DefaultConfig.GetInstance (); +#if !TARGET_JVM + static IConfigurationSystem config = DefaultConfig.GetInstance (); +#else + static IConfigurationSystem config { + get { + IConfigurationSystem conf = (IConfigurationSystem) AppDomain.CurrentDomain.GetData ("ConfigurationSettings.Config"); + if (conf == null) { + conf = DefaultConfig.GetInstance (); + AppDomain.CurrentDomain.SetData ("ConfigurationSettings.Config", conf); + } + return conf; + } + set { + AppDomain.CurrentDomain.SetData ("ConfigurationSettings.Config", value); + } + } +#endif static object lockobj = new object (); private ConfigurationSettings () { @@ -63,7 +83,11 @@ namespace System.Configuration #endif public static object GetConfig (string sectionName) { +#if NET_2_0 && CONFIGURATION_DEP + return ConfigurationManager.GetSection (sectionName); +#else return config.GetConfig (sectionName); +#endif } #if NET_2_0 @@ -103,7 +127,23 @@ namespace System.Configuration // class DefaultConfig : IConfigurationSystem { - static readonly DefaultConfig instance = new DefaultConfig (); +#if !TARGET_JVM + static readonly DefaultConfig instance = new DefaultConfig (); +#else + static DefaultConfig instance { + get { + DefaultConfig conf = (DefaultConfig) AppDomain.CurrentDomain.GetData ("DefaultConfig.instance"); + if (conf == null) { + conf = new DefaultConfig (); + AppDomain.CurrentDomain.SetData ("DefaultConfig.instance", conf); + } + return conf; + } + set { + AppDomain.CurrentDomain.SetData ("DefaultConfig.instance", value); + } + } +#endif ConfigurationData config; private DefaultConfig () @@ -131,9 +171,13 @@ namespace System.Configuration return; ConfigurationData data = new ConfigurationData (); - if (!data.Load (GetMachineConfigPath ())) - throw new ConfigurationException ("Cannot find " + GetMachineConfigPath ()); + if (data.LoadString (GetBundledMachineConfig ())) { + // do nothing + } else { + if (!data.Load (GetMachineConfigPath ())) + throw new ConfigurationException ("Cannot find " + GetMachineConfigPath ()); + } string appfile = GetAppConfigPath (); if (appfile == null) { config = data; @@ -147,15 +191,29 @@ namespace System.Configuration config = data; } } - +#if TARGET_JVM + internal static string GetBundledMachineConfig () + { + return null; + } + internal static string GetMachineConfigPath () + { + return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile; + } +#else + [MethodImplAttribute(MethodImplOptions.InternalCall)] + extern private static string get_bundled_machine_config (); + internal static string GetBundledMachineConfig () + { + return get_bundled_machine_config (); + } [MethodImplAttribute(MethodImplOptions.InternalCall)] extern private static string get_machine_config_path (); - internal static string GetMachineConfigPath () { return get_machine_config_path (); } - +#endif private static string GetAppConfigPath () { AppDomainSetup currentInfo = AppDomain.CurrentDomain.SetupInformation; @@ -175,7 +233,7 @@ namespace System.Configuration MachineOnly, MachineToApplication } - + class SectionData { public readonly string SectionName; @@ -183,40 +241,42 @@ namespace System.Configuration public readonly bool AllowLocation; public readonly AllowDefinition AllowDefinition; public string FileName; + public readonly bool RequirePermission; public SectionData (string sectionName, string typeName, - bool allowLocation, AllowDefinition allowDefinition) + bool allowLocation, AllowDefinition allowDefinition, bool requirePermission) { SectionName = sectionName; TypeName = typeName; AllowLocation = allowLocation; AllowDefinition = allowDefinition; + RequirePermission = requirePermission; } } - + class ConfigurationData { ConfigurationData parent; Hashtable factories; + static object removedMark = new object (); + static object emptyMark = new object (); +#if (XML_DEP) Hashtable pending; string fileName; - static object removedMark = new object (); - static object emptyMark = new object (); -#if (XML_DEP) - static object groupMark = new object (); + static object groupMark = new object (); #endif Hashtable cache; - Hashtable FileCache { - get { + Hashtable FileCache { + get { if (cache != null) return cache; cache = new Hashtable (); - return cache; - } - } + return cache; + } + } public ConfigurationData () : this (null) { @@ -232,17 +292,35 @@ namespace System.Configuration [FileIOPermission (SecurityAction.Assert, Unrestricted = true)] public bool Load (string fileName) { +#if (XML_DEP) this.fileName = fileName; - if (fileName == null || !File.Exists (fileName)) + if (fileName == null +#if !TARGET_JVM + || !File.Exists (fileName) +#endif +) return false; -#if (XML_DEP) + XmlTextReader reader = null; try { +#if !TARGET_JVM FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read); +#else + Stream fs = (Stream) vmw.common.IOUtils.getStream (fileName); + + //patch for machine.config + if (fs == null && fileName.EndsWith ("machine.config")) { + fs = (Stream) IOUtils.getStreamForGHConfigs (fileName); + } + + if (fs == null) { + return false; + } +#endif reader = new XmlTextReader (fs); - InitRead (reader); - ReadConfigFile (reader); + if (InitRead (reader)) + ReadConfigFile (reader); } catch (ConfigurationException) { throw; } catch (Exception e) { @@ -254,7 +332,31 @@ namespace System.Configuration #endif return true; } + + public bool LoadString (string data) + { + if (data == null) + return false; +#if (XML_DEP) + XmlTextReader reader = null; + try { + TextReader tr = new StringReader (data); + reader = new XmlTextReader (tr); + if (InitRead (reader)) + ReadConfigFile (reader); + } catch (ConfigurationException) { + throw; + } catch (Exception e) { + throw new ConfigurationException ("Error reading " + fileName, e); + } finally { + if (reader != null) + reader.Close(); + } +#endif + return true; + } + object GetHandler (string sectionName) { lock (factories) { @@ -333,7 +435,7 @@ namespace System.Configuration return GetInnerDoc (doc, 0, sectionPath); } - + object GetConfigInternal (string sectionName) { object handler = GetHandler (sectionName); @@ -364,11 +466,11 @@ namespace System.Configuration config = this.FileCache [sectionName]; } - if (config == emptyMark) - return null; + if (config == emptyMark) + return null; - if (config != null) - return config; + if (config != null) + return config; lock (this) { config = GetConfigInternal (sectionName); @@ -376,7 +478,7 @@ namespace System.Configuration } return config; - } + } private object LookForFactory (string key) { @@ -390,7 +492,7 @@ namespace System.Configuration return null; } #if (XML_DEP) - private void InitRead (XmlTextReader reader) + private bool InitRead (XmlTextReader reader) { reader.MoveToContent (); if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration") @@ -398,10 +500,16 @@ namespace System.Configuration if (reader.HasAttributes) ThrowException ("Unrecognized attribute in root element", reader); - - MoveToNextElement (reader); + if (reader.IsEmptyElement) { + reader.Skip (); + return false; + } + reader.Read (); + reader.MoveToContent (); + return reader.NodeType != XmlNodeType.EndElement; } + // FIXME: this approach is not always safe and likely to cause bugs. private void MoveToNextElement (XmlTextReader reader) { while (reader.Read ()) { @@ -423,6 +531,8 @@ namespace System.Configuration string nameValue = null; string typeValue = null; string allowLoc = null, allowDef = null; + bool requirePermission = false; + string requirePer = null; bool allowLocation = true; AllowDefinition allowDefinition = AllowDefinition.Everywhere; @@ -443,6 +553,16 @@ namespace System.Configuration continue; } + if (attName == "requirePermission") { + if (requirePer != null) + ThrowException ("Duplicated requirePermission attribute.", reader); + requirePer = reader.Value; + requirePermission = (requirePer == "true"); + if (!requirePermission && requirePer != "false") + ThrowException ("Invalid attribute value", reader); + continue; + } + if (attName == "allowDefinition") { if (allowDef != null) ThrowException ("Duplicated allowDefinition attribute.", reader); @@ -487,11 +607,22 @@ namespace System.Configuration object o = LookForFactory (nameValue); if (o != null && o != removedMark) ThrowException ("Already have a factory for " + nameValue, reader); - SectionData section = new SectionData (nameValue, typeValue, allowLocation, allowDefinition); + SectionData section = new SectionData (nameValue, typeValue, allowLocation, + allowDefinition, requirePermission); section.FileName = fileName; factories [nameValue] = section; - MoveToNextElement (reader); + if (reader.IsEmptyElement) + reader.Skip (); + else { + reader.Read (); + reader.MoveToContent (); + if (reader.NodeType != XmlNodeType.EndElement) + // sub-section inside a section + ReadSections (reader, nameValue); + reader.ReadEndElement (); + } + reader.MoveToContent (); } private void ReadRemoveSection (XmlTextReader reader, string sectionName) @@ -528,7 +659,7 @@ namespace System.Configuration ThrowException ("Duplicate 'name' attribute.", reader); value = reader.Value; } - else + else #if NET_2_0 if (reader.Name != "type") #endif @@ -537,10 +668,10 @@ namespace System.Configuration if (value == null) ThrowException ("No 'name' attribute.", reader); - + if (value == "location") ThrowException ("location is a reserved section name", reader); - + if (configSection != null) value = configSection + '/' + value; @@ -549,14 +680,28 @@ namespace System.Configuration ThrowException ("Already have a factory for " + value, reader); factories [value] = groupMark; - MoveToNextElement (reader); - ReadSections (reader, value); + + if (reader.IsEmptyElement) { + reader.Skip (); + reader.MoveToContent (); + } else { + reader.Read (); + reader.MoveToContent (); + if (reader.NodeType != XmlNodeType.EndElement) + ReadSections (reader, value); + reader.ReadEndElement (); + reader.MoveToContent (); + } } + // It stops XmlReader consumption at where it found + // surrounding EndElement i.e. EndElement is not consumed here private void ReadSections (XmlTextReader reader, string configSection) { int depth = reader.Depth; - while (reader.Depth == depth) { + for (reader.MoveToContent (); + reader.Depth == depth; + reader.MoveToContent ()) { string name = reader.Name; if (name == "section") { ReadSection (reader, configSection); @@ -597,16 +742,23 @@ namespace System.Configuration private void ReadConfigFile (XmlTextReader reader) { - int depth = reader.Depth; - while (!reader.EOF && reader.Depth == depth) { + //int depth = reader.Depth; + for (reader.MoveToContent (); + !reader.EOF && reader.NodeType != XmlNodeType.EndElement; + reader.MoveToContent ()) { string name = reader.Name; if (name == "configSections") { if (reader.HasAttributes) ThrowException ("Unrecognized attribute in .", reader); - - MoveToNextElement (reader); - if (reader.Depth > depth) - ReadSections (reader, null); + if (reader.IsEmptyElement) + reader.Skip (); + else { + reader.Read (); + reader.MoveToContent (); + if (reader.NodeType != XmlNodeType.EndElement) + ReadSections (reader, null); + reader.ReadEndElement (); + } } else if (name != null && name != "") { StorePending (name, reader); MoveToNextElement (reader); @@ -615,7 +767,7 @@ namespace System.Configuration } } } - + private void ThrowException (string text, XmlTextReader reader) { throw new ConfigurationException (text, fileName, reader.LineNumber);