using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
+using System.Web.Util;
using System.Xml;
using System.Configuration;
using System.Configuration.Internal;
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 ()
{
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)
{
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)
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,
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)
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;
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);
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 {
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 {
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 ();
object [] args = new object [] {system};
changeConfig.Invoke (null, args);
- configSystem = system;
+ //configSystem = system;
}
}
}