New test.
[mono.git] / mcs / class / System.Web / System.Web.Configuration_2.0 / WebConfigurationManager.cs
index 8002d813c975cf7b37aeff7e92565c8b9ad90e25..fd87f12d0854ce5c5c70fb91d6e32237c9e1e52b 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Authors:
 //     Lluis Sanchez Gual (lluis@novell.com)
+//     Chris Toshok (toshok@ximian.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -27,6 +28,7 @@
 //
 
 #if NET_2_0
+
 using System;
 using System.IO;
 using System.Collections;
@@ -41,8 +43,56 @@ namespace System.Web.Configuration {
 
        public static class WebConfigurationManager
        {
+#if !TARGET_J2EE
                static IInternalConfigConfigurationFactory configFactory;
                static Hashtable configurations = new Hashtable ();
+#else
+        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 = new Hashtable();
+                            configurations = table;
+                        }
+                    }
+                }
+                return table != null ? table : configurations;
+
+            }
+            set{
+                AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value);
+                AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
+            }
+        }
+#endif
                
                static WebConfigurationManager ()
                {
@@ -51,23 +101,25 @@ namespace System.Web.Configuration {
                                configFactory = prop.GetValue (null, null) as IInternalConfigConfigurationFactory;
                }
 
-               [MonoTODO]
                public static _Configuration OpenMachineConfiguration ()
                {
-                       throw new NotImplementedException ();
+                       return ConfigurationManager.OpenMachineConfiguration ();
                }
                
-               [MonoTODO]
+               [MonoTODO ("need to handle locationSubPath")]
                public static _Configuration OpenMachineConfiguration (string locationSubPath)
                {
-                       throw new NotImplementedException ();
+                       return OpenMachineConfiguration ();
                }
 
                [MonoTODO]
                public static _Configuration OpenMachineConfiguration (string locationSubPath,
                                                                       string server)
                {
-                       throw new NotImplementedException ();
+                       if (server == null)
+                               return OpenMachineConfiguration (locationSubPath);
+
+                       throw new NotSupportedException ("Mono doesn't support remote configuration");
                }
 
                [MonoTODO]
@@ -75,7 +127,9 @@ namespace System.Web.Configuration {
                                                                       string server,
                                                                       IntPtr userToken)
                {
-                       throw new NotImplementedException ();
+                       if (server == null)
+                               return OpenMachineConfiguration (locationSubPath);
+                       throw new NotSupportedException ("Mono doesn't support remote configuration");
                }
 
                [MonoTODO]
@@ -84,22 +138,24 @@ namespace System.Web.Configuration {
                                                                       string userName,
                                                                       string password)
                {
-                       throw new NotImplementedException ();
+                       if (server == null)
+                               return OpenMachineConfiguration (locationSubPath);
+                       throw new NotSupportedException ("Mono doesn't support remote configuration");
                }
 
                public static _Configuration OpenWebConfiguration (string path)
                {
-                       return OpenWebConfiguration (path, null, null, null, IntPtr.Zero, null);
+                       return OpenWebConfiguration (path, null, null, null, null, null);
                }
                
                public static _Configuration OpenWebConfiguration (string path, string site)
                {
-                       return OpenWebConfiguration (path, site, null, null, IntPtr.Zero, null);
+                       return OpenWebConfiguration (path, site, null, null, null, null);
                }
                
                public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
                {
-                       return OpenWebConfiguration (path, site, locationSubPath, null, IntPtr.Zero, null);
+                       return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
                }
 
                [MonoTODO]
@@ -110,19 +166,23 @@ namespace System.Web.Configuration {
 
                public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
                {
-                       return OpenWebConfiguration (path, site, locationSubPath, server, userToken, null);
+                       return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
                }
                
-               [MonoTODO ("Do something with the extra parameters")]
-               public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken, string password)
+               [MonoTODO]
+               public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
                {
+                       if (path == null)
+                               path = "";
+
                        string basePath = GetBasePath (path);
                        _Configuration conf;
+
                        
                        lock (configurations) {
                                conf = (_Configuration) configurations [basePath];
                                if (conf == null) {
-                                       conf = ConfigurationFactory.Create (typeof(WebConfigurationHost), null, path, site, locationSubPath, server, userToken, password);
+                                       conf = ConfigurationFactory.Create (typeof(WebConfigurationHost), null, basePath, site, locationSubPath, server, userName, password);
                                        configurations [basePath] = conf;
                                }
                        }
@@ -148,12 +208,6 @@ namespace System.Web.Configuration {
                        return conf;
                }
 
-               [MonoTODO]
-               public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
-               {
-                       throw new NotImplementedException ();
-               }
-
                public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
                {
                        return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
@@ -176,45 +230,79 @@ namespace System.Web.Configuration {
                        return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
                }
 
-               [MonoTODO]
+               [MonoTODO ("need to handle locationSubPath")]
                public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
                                                                             string locationSubPath)
                {
-                       throw new NotImplementedException ();
+                       return OpenMappedMachineConfiguration (fileMap);
                }
 
-               [MonoTODO ("this shouldn't call ConfigurationManager.GetSection")]
                public static object GetSection (string sectionName)
                {
-                       return ConfigurationManager.GetSection (sectionName);
+                       _Configuration c;
+                       if (HttpContext.Current != null
+                           && HttpContext.Current.Request != null)
+                               c = OpenWebConfiguration (HttpContext.Current.Request.Path);
+                       else
+                               c = OpenWebConfiguration (HttpRuntime.AppDomainAppVirtualPath);
+
+                       if (c == null)
+                               return null;
+                       else
+                               return c.GetSection (sectionName);
                }
 
                [MonoTODO]
                public static object GetSection (string sectionName, string path)
                {
-                       throw new NotImplementedException ();
+                       try {
+                               _Configuration c = OpenWebConfiguration (path);
+                               return c.GetSection (sectionName);
+                       }
+                       catch {
+                               return null;
+                       }
                }
 
+               static _Configuration GetWebApplicationConfiguration ()
+               {
+                       _Configuration config;
+
+                       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);
+                       }
+
+                       return config;
+               }
+
+               static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
+
                [MonoTODO]
                public static object GetWebApplicationSection (string sectionName)
                {
-                       _Configuration config = OpenWebConfiguration (HttpContext.Current.Request.PhysicalApplicationPath);
+                       _Configuration config = GetWebApplicationConfiguration ();
+                       if (config == null)
+                               return null;
 
-                       return config.GetSection (sectionName);
+                       ConfigurationSection section = config.GetSection (sectionName);
+                       if (section == null)
+                               return null;
+                       
+                       return get_runtime_object.Invoke (section, new object [0]);
                }
 
-               [MonoTODO]
                public static NameValueCollection AppSettings {
-                       get {
-                               throw new NotImplementedException ();
-                       }
+                       get { return ConfigurationManager.AppSettings; }
                }
 
-               [MonoTODO]
                public static ConnectionStringSettingsCollection ConnectionStrings {
-                       get {
-                               throw new NotImplementedException ();
-                       }
+                       get { return ConfigurationManager.ConnectionStrings; }
                }
 
                internal static IInternalConfigConfigurationFactory ConfigurationFactory {
@@ -223,21 +311,168 @@ namespace System.Web.Configuration {
                
                static string GetBasePath (string path)
                {
-                       if (path == "/")
+                       if (path == "/" || path == "")
                                return path;
-                       
-                       string pd = HttpContext.Current.Request.MapPath (path);
 
-                       if (!Directory.Exists (pd)) {
-                               int i = path.LastIndexOf ('/');
-                               path = path.Substring (0, i);
-                       } 
+                       /* first if we can, map it to a physical path
+                        * to see if it corresponds to a file */
+                       if (HttpContext.Current != null
+                           && HttpContext.Current.Request != null) {
+                               string pd = HttpContext.Current.Request.MapPath (path);
+
+                               if (!Directory.Exists (pd)) {
+                                       /* if it does, remove the file from the url */
+                                       int i = path.LastIndexOf ('/');
+                                       path = path.Substring (0, i);
+                               } 
+                       }
                        
+                       if (path.Length == 0)
+                               return path;
+
+                       /* remove excess /'s from the end of the virtual path */
                        while (path [path.Length - 1] == '/')
                                path = path.Substring (0, path.Length - 1);
+
                        return path;
                }
+
+
+#region stuff copied from WebConfigurationSettings
+#if TARGET_J2EE
+               static internal IConfigurationSystem oldConfig {
+                       get {
+                               return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
+                       }
+                       set {
+                               AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
+                       }
+               }
+
+               static private Web20DefaultConfig config {
+                       get {
+                               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 ("IInternalConfigSystem.configSystem", value);
+                       }
+               }
+#else
+               static internal IConfigurationSystem oldConfig;
+               static Web20DefaultConfig config;
+               static IInternalConfigSystem configSystem;
+#endif
+               const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
+               static readonly object lockobj = new object ();
+
+               internal static void Init ()
+               {
+                       lock (lockobj) {
+                               if (config != null)
+                                       return;
+
+                               /* deal with the ConfigurationSettings stuff */
+                               {
+                                       Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
+                                       Type t = typeof (ConfigurationSettings);
+                                       MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
+                                                                              privStatic);
+
+                                       if (changeConfig == null)
+                                               throw new ConfigurationException ("Cannot find method CCS");
+
+                                       object [] args = new object [] {settings};
+                                       oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
+                                       config = settings;
+
+                                       config.Init ();
+                               }
+
+                               /* deal with the ConfigurationManager stuff */
+                               {
+                                       HttpConfigurationSystem system = new HttpConfigurationSystem ();
+                                       Type t = typeof (ConfigurationManager);
+                                       MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
+                                                                              privStatic);
+
+                                       if (changeConfig == null)
+                                               throw new ConfigurationException ("Cannot find method CCS");
+
+                                       object [] args = new object [] {system};
+                                       changeConfig.Invoke (null, args);
+                                       configSystem = system;
+                               }
+                       }
+               }
+       }
+
+       class Web20DefaultConfig : IConfigurationSystem
+       {
+#if TARGET_J2EE
+               static private Web20DefaultConfig instance {
+                       get {
+                               Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
+                               if (val == null) {
+                                       val = new Web20DefaultConfig();
+                                       AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
+                               }
+                               return val;
+                       }
+                       set {
+                               AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
+                       }
+               }
+#else
+               static Web20DefaultConfig instance;
+#endif
+
+               static Web20DefaultConfig ()
+               {
+                       instance = new Web20DefaultConfig ();
+               }
+
+               public static Web20DefaultConfig GetInstance ()
+               {
+                       return instance;
+               }
+
+               public object GetConfig (string sectionName)
+               {
+                       object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
+
+                       if (o == null || o is IgnoreSection) {
+                               /* this can happen when the section
+                                * handler doesn't subclass from
+                                * ConfigurationSection.  let's be
+                                * nice and try to load it using the
+                                * 1.x style routines in case there's
+                                * a 1.x section handler registered
+                                * for it.
+                                */
+                               object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
+                               if (o1 != null)
+                                       return o1;
+                       }
+
+                       return o;
+               }
+
+               public void Init ()
+               {
+                       // nothing. We need a context.
+               }
        }
+
+#endregion
 }
 
 #endif