X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web.Configuration_2.0%2FWebConfigurationManager.cs;h=b75adb02b03c0109447ffd3e91d5afd0b4e7d528;hb=dfde3a4596fe1e9d34510e6314f7056529441678;hp=a57d1bf983ed7892f3c3ba7623088d1e8a298fae;hpb=7d0cc820e7caacd15e61e0ebc50ae72b491257a8;p=mono.git diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs index a57d1bf983e..b75adb02b03 100644 --- a/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs +++ b/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs @@ -34,6 +34,7 @@ using System.IO; using System.Collections; using System.Collections.Specialized; using System.Reflection; +using System.Web.Util; using System.Xml; using System.Configuration; using System.Configuration.Internal; @@ -43,8 +44,94 @@ namespace System.Web.Configuration { public static class WebConfigurationManager { +#if !TARGET_J2EE static IInternalConfigConfigurationFactory configFactory; - static Hashtable configurations = new Hashtable (); + static Hashtable configurations = Hashtable.Synchronized (new Hashtable ()); + static Hashtable sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase); +#else + const string AppSettingsKey = "WebConfigurationManager.AppSettings"; + static internal IInternalConfigConfigurationFactory configFactory + { + get{ + IInternalConfigConfigurationFactory factory = (IInternalConfigConfigurationFactory)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory"); + if (factory == null){ + lock (AppDomain.CurrentDomain){ + object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory.initialized"); + if (initialized == null){ + PropertyInfo prop = typeof(ConfigurationManager).GetProperty("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic); + if (prop != null){ + factory = prop.GetValue(null, null) as IInternalConfigConfigurationFactory; + configFactory = factory; + } + } + } + } + return factory != null ? factory : configFactory; + } + set{ + AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory", value); + AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory.initialized", true); + } + } + + static internal Hashtable configurations + { + get{ + Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations"); + if (table == null){ + lock (AppDomain.CurrentDomain){ + object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized"); + if (initialized == null){ + table = Hashtable.Synchronized (new Hashtable (StringComparer.OrdinalIgnoreCase)); + configurations = table; + } + } + } + return table != null ? table : configurations; + + } + set{ + AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value); + AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true); + } + } + + static Hashtable sectionCache + { + get + { + Hashtable sectionCache = (Hashtable) AppDomain.CurrentDomain.GetData ("sectionCache"); + if (sectionCache == null) { + sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase); + AppDomain.CurrentDomain.SetData ("sectionCache", sectionCache); + } + return sectionCache; + } + set + { + AppDomain.CurrentDomain.SetData ("sectionCache", value); + } + } +#endif + + static ArrayList extra_assemblies = null; + static internal ArrayList ExtraAssemblies { + get { + if (extra_assemblies == null) + extra_assemblies = new ArrayList(); + return extra_assemblies; + } + } + + static bool hasConfigErrors = false; + static object hasConfigErrorsLock = new object (); + static internal bool HasConfigErrors { + get { + lock (hasConfigErrorsLock) { + return hasConfigErrors; + } + } + } static WebConfigurationManager () { @@ -58,13 +145,13 @@ namespace System.Web.Configuration { return ConfigurationManager.OpenMachineConfiguration (); } - [MonoTODO ("need to handle locationSubPath")] + [MonoLimitation ("locationSubPath is not handled")] public static _Configuration OpenMachineConfiguration (string locationSubPath) { return OpenMachineConfiguration (); } - [MonoTODO] + [MonoLimitation("Mono does not support remote configuration")] public static _Configuration OpenMachineConfiguration (string locationSubPath, string server) { @@ -74,7 +161,7 @@ namespace System.Web.Configuration { throw new NotSupportedException ("Mono doesn't support remote configuration"); } - [MonoTODO] + [MonoLimitation("Mono does not support remote configuration")] public static _Configuration OpenMachineConfiguration (string locationSubPath, string server, IntPtr userToken) @@ -84,7 +171,7 @@ namespace System.Web.Configuration { throw new NotSupportedException ("Mono doesn't support remote configuration"); } - [MonoTODO] + [MonoLimitation("Mono does not support remote configuration")] public static _Configuration OpenMachineConfiguration (string locationSubPath, string server, string userName, @@ -110,10 +197,9 @@ namespace System.Web.Configuration { return OpenWebConfiguration (path, site, locationSubPath, null, null, null); } - [MonoTODO] public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server) { - throw new NotImplementedException (); + return OpenWebConfiguration (path, site, locationSubPath, server, null, null); } public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken) @@ -121,40 +207,23 @@ namespace System.Web.Configuration { return OpenWebConfiguration (path, site, locationSubPath, server, null, null); } - [MonoTODO] public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password) { - if (path == null) - path = ""; + if (path == null || path.Length == 0) + path = "/"; - string basePath = GetBasePath (path); _Configuration conf; - - lock (configurations) { - conf = (_Configuration) configurations [basePath]; - if (conf == null) { - conf = ConfigurationFactory.Create (typeof(WebConfigurationHost), null, basePath, site, locationSubPath, server, userName, password); - configurations [basePath] = conf; - } - } - if (basePath.Length < path.Length) { - - // If the path has a file name, look for a location specific configuration - - int dif = path.Length - basePath.Length; - string file = path.Substring (path.Length - dif); - int i=0; - while (i < file.Length && file [i] == '/') - i++; - if (i != 0) - file = file.Substring (i); - - if (file.Length != 0) { - foreach (ConfigurationLocation loc in conf.Locations) { - if (loc.Path == file) - return loc.OpenConfiguration (); + conf = (_Configuration) configurations [path]; + if (conf == null) { + try { + conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password); + configurations [path] = conf; + } catch (Exception ex) { + lock (hasConfigErrorsLock) { + hasConfigErrors = true; } + throw ex; } } return conf; @@ -165,13 +234,11 @@ namespace System.Web.Configuration { return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path); } - [MonoTODO ("Do something with the extra parameters")] public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site) { return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site); } - [MonoTODO ("Do something with the extra parameters")] public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath) { return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath); @@ -182,62 +249,89 @@ namespace System.Web.Configuration { return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap); } - [MonoTODO ("need to handle locationSubPath")] public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap, string locationSubPath) { return OpenMappedMachineConfiguration (fileMap); } - [MonoTODO ("apparently this bad boy can return null, but GetWebApplicationSection doesn't")] - public static object GetSection (string sectionName) + internal static object SafeGetSection (string sectionName, Type configSectionType) { try { - _Configuration c = OpenWebConfiguration (HttpContext.Current.Request.Path); - return c.GetSection (sectionName); - } - catch { - return GetWebApplicationSection (sectionName); + return GetSection (sectionName); + } catch (Exception) { + if (configSectionType != null) + return Activator.CreateInstance (configSectionType); + return null; } } - - [MonoTODO] - public static object GetSection (string sectionName, string path) + + internal static object SafeGetSection (string sectionName, string path, Type configSectionType) { try { - _Configuration c = OpenWebConfiguration (path); - return c.GetSection (sectionName); - } - catch { + return GetSection (sectionName, path); + } catch (Exception) { + if (configSectionType != null) + return Activator.CreateInstance (configSectionType); return null; } } - static _Configuration GetWebApplicationConfiguration () + public static object GetSection (string sectionName) { - _Configuration config; + return GetSection (sectionName, GetCurrentPath (HttpContext.Current)); + } - if (HttpContext.Current == null - || HttpContext.Current.Request == null - || HttpContext.Current.Request.ApplicationPath == null - || HttpContext.Current.Request.ApplicationPath == "") { - config = OpenWebConfiguration (""); - } - else { - config = OpenWebConfiguration (HttpContext.Current.Request.ApplicationPath); + public static object GetSection (string sectionName, string path) + { + object cachedSection = sectionCache [GetSectionCacheKey (sectionName, path)]; + if (cachedSection != null) + return cachedSection; + + _Configuration c = OpenWebConfiguration (path); + ConfigurationSection section = c.GetSection (sectionName); + + if (section == null) + return null; + +#if TARGET_J2EE + object value = get_runtime_object.Invoke (section, new object [0]); + if (String.CompareOrdinal ("appSettings", sectionName) == 0) { + NameValueCollection collection; + collection = new KeyValueMergedCollection (HttpContext.Current, (NameValueCollection) value); + value = collection; } - return config; + AddSectionToCache (GetSectionCacheKey (sectionName, path), value); + return value; +#else + object value = SettingsMappingManager.MapSection (get_runtime_object.Invoke (section, new object [0])); + AddSectionToCache (GetSectionCacheKey (sectionName, path), value); + return value; +#endif } - [MonoTODO] - public static object GetWebApplicationSection (string sectionName) + static string GetCurrentPath (HttpContext ctx) + { + return (ctx != null && ctx.Request != null) ? ctx.Request.Path : HttpRuntime.AppDomainAppVirtualPath; + } + + internal static void RemoveConfigurationFromCache (HttpContext ctx) { - _Configuration config = GetWebApplicationConfiguration (); + configurations.Remove (GetCurrentPath (ctx)); + } - ConfigurationSection section = config.GetSection (sectionName); + readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance); - return section; + public static object GetWebApplicationSection (string sectionName) + { + string path = (HttpContext.Current == null + || HttpContext.Current.Request == null + || HttpContext.Current.Request.ApplicationPath == null + || HttpContext.Current.Request.ApplicationPath == "") ? + String.Empty : HttpContext.Current.Request.ApplicationPath; + + return GetSection (sectionName, path); } public static NameValueCollection AppSettings { @@ -251,25 +345,26 @@ namespace System.Web.Configuration { internal static IInternalConfigConfigurationFactory ConfigurationFactory { get { return configFactory; } } - - static string GetBasePath (string path) + + static void AddSectionToCache (string key, object section) { - if (path == "/" || path == "") - return path; - - string pd = HttpContext.Current.Request.MapPath (path); + if (sectionCache [key] != null) + return; + + Hashtable tmpTable = (Hashtable) sectionCache.Clone (); + if (tmpTable.Contains (key)) + return; - if (!Directory.Exists (pd)) { - int i = path.LastIndexOf ('/'); - path = path.Substring (0, i); - } - - while (path [path.Length - 1] == '/') - path = path.Substring (0, path.Length - 1); - return path; + tmpTable.Add (key, section); + sectionCache = tmpTable; } + static string GetSectionCacheKey (string sectionName, string path) + { + return string.Concat (path, "/", sectionName); + } + #region stuff copied from WebConfigurationSettings #if TARGET_J2EE static internal IConfigurationSystem oldConfig { @@ -283,16 +378,25 @@ namespace System.Web.Configuration { static private Web20DefaultConfig config { get { - return (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("WebConfigurationManager.config"); + return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config"); + } + set { + AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value); + } + } + + static private IInternalConfigSystem configSystem { + get { + return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem"); } set { - AppDomain.CurrentDomain.SetData("WebConfigurationManager.config", value); + AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value); } } #else static internal IConfigurationSystem oldConfig; static Web20DefaultConfig config; - static IInternalConfigSystem configSystem; + //static IInternalConfigSystem configSystem; #endif const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static; static readonly object lockobj = new object (); @@ -332,7 +436,7 @@ namespace System.Web.Configuration { object [] args = new object [] {system}; changeConfig.Invoke (null, args); - configSystem = system; + //configSystem = system; } } }