importing messaging-2008 branch to trunk, going on.
[mono.git] / mcs / class / System.Configuration / System.Configuration / ConfigurationManager.cs
index 35241f264a7dbbfc75269032c2e1ea0dea588990..9785b38353470002e454259f3ab439b4e4417d11 100644 (file)
@@ -43,8 +43,11 @@ namespace System.Configuration {
 
        public static class ConfigurationManager
        {
+               static bool systemWebInUse;
                static InternalConfigurationFactory configFactory = new InternalConfigurationFactory ();
-
+               static IInternalConfigSystem configSystem = new ClientConfigurationSystem ();
+               static object lockobj = new object ();
+               
                [MonoTODO ("Evidence and version still needs work")]
                static string GetAssemblyInfo (Assembly a)
                {
@@ -77,7 +80,7 @@ namespace System.Configuration {
                        return Path.Combine (String.Format ("{0}_{1}", app_name, evidence_str), version);
                }
 
-               static Configuration OpenExeConfigurationInternal (ConfigurationUserLevel userLevel, Assembly calling_assembly, string exePath)
+               internal static Configuration OpenExeConfigurationInternal (ConfigurationUserLevel userLevel, Assembly calling_assembly, string exePath)
                {
                        ExeConfigurationFileMap map = new ExeConfigurationFileMap ();
 
@@ -90,14 +93,17 @@ namespace System.Configuration {
 
                        switch (userLevel) {
                        case ConfigurationUserLevel.None:
-                               if (exePath == null)
-                                       exePath = Assembly.GetCallingAssembly ().Location;
-                               else if (!File.Exists (exePath))
-                                       exePath = "";
-
-                               if (exePath != "")
+                               if (exePath == null || exePath.Length == 0) {
+                                       map.ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
+                               } else {
+                                       if (!Path.IsPathRooted (exePath))
+                                               exePath = Path.GetFullPath (exePath);
+                                       if (!File.Exists (exePath)) {
+                                               Exception cause = new ArgumentException ("The specified path does not exist.", "exePath");
+                                               throw new ConfigurationErrorsException ("Error Initializing the configuration system:", cause);
+                                       }
                                        map.ExeConfigFilename = exePath + ".config";
-
+                               }
                                break;
                        case ConfigurationUserLevel.PerUserRoaming:
                                map.RoamingUserConfigFilename = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), GetAssemblyInfo(calling_assembly));
@@ -110,23 +116,26 @@ namespace System.Configuration {
                                break;
                        }
 
-                       return ConfigurationFactory.Create (typeof(ExeConfigurationHost), map);
+                       return ConfigurationFactory.Create (typeof(ExeConfigurationHost), map, userLevel);
                }
 
+#if TARGET_JVM
+               [MonoLimitation ("Supported only when the userLevel parameter is set to ConfigurationUserLevel.None. Other values are not supported because Environment.GetFolderPath method is not implemented.")]
+#endif
                public static Configuration OpenExeConfiguration (ConfigurationUserLevel userLevel)
                {
-                       return OpenExeConfigurationInternal (userLevel, Assembly.GetCallingAssembly (), Assembly.GetCallingAssembly ().Location);
+                       return OpenExeConfigurationInternal (userLevel, Assembly.GetEntryAssembly () ?? Assembly.GetCallingAssembly (), null);
                }
                
                public static Configuration OpenExeConfiguration (string exePath)
                {
-                       return OpenExeConfigurationInternal (ConfigurationUserLevel.None, Assembly.GetCallingAssembly (), exePath);
+                       return OpenExeConfigurationInternal (ConfigurationUserLevel.None, Assembly.GetEntryAssembly () ?? Assembly.GetCallingAssembly (), exePath);
                }
 
-               [MonoTODO ("userLevel")]
+               [MonoLimitation("ConfigurationUserLevel parameter is not supported.")]
                public static Configuration OpenMappedExeConfiguration (ExeConfigurationFileMap fileMap, ConfigurationUserLevel userLevel)
                {
-                       return ConfigurationFactory.Create (typeof(ExeConfigurationHost), fileMap);
+                       return ConfigurationFactory.Create (typeof(ExeConfigurationHost), fileMap, userLevel);
                }
 
                public static Configuration OpenMachineConfiguration ()
@@ -144,30 +153,27 @@ namespace System.Configuration {
                        get { return configFactory; }
                }
 
-               [MonoTODO ("this assembly stuff is probably wrong")]
+               internal static IInternalConfigSystem ConfigurationSystem {
+                       get { return configSystem; }
+               }
+
                public static object GetSection (string sectionName)
                {
-                       Assembly a = Assembly.GetEntryAssembly ();
-                       if (a == null)
-                               a = Assembly.GetCallingAssembly ();
-                       Configuration cfg = OpenExeConfigurationInternal (ConfigurationUserLevel.None,
-                                                                         a, a.Location);
-
-                       if (cfg == null)
-                               return null;
-
-                       return cfg.GetSection (sectionName);
+                       object o = ConfigurationSystem.GetSection (sectionName);
+                       if (o is ConfigurationSection)
+                               return ((ConfigurationSection) o).GetRuntimeObject ();
+                       else
+                               return o;
                }
 
-               [MonoTODO]
                public static void RefreshSection (string sectionName)
                {
+                       ConfigurationSystem.RefreshConfig (sectionName);
                }
 
                public static NameValueCollection AppSettings {
                        get {
-                               AppSettingsSection appsettings = (AppSettingsSection) GetSection ("appSettings");
-                               return (NameValueCollection)appsettings.GetRuntimeObject ();
+                               return (NameValueCollection) GetSection ("appSettings");
                        }
                }
 
@@ -175,10 +181,31 @@ namespace System.Configuration {
                public static ConnectionStringSettingsCollection ConnectionStrings {
                        get {
                                ConnectionStringsSection connectionStrings = (ConnectionStringsSection) GetSection ("connectionStrings");
-
                                return connectionStrings.ConnectionStrings;
                        }
                }
+
+               /* invoked from System.Web */
+               internal static IInternalConfigSystem ChangeConfigurationSystem (IInternalConfigSystem newSystem)
+               {
+                       if (newSystem == null)
+                               throw new ArgumentNullException ("newSystem");
+
+                       lock (lockobj) {
+                               // KLUDGE!! We need that when an assembly loaded inside an ASP.NET
+                               // domain does OpenExeConfiguration ("") - we must return the path
+                               // to web.config in that instance.
+                               string t = newSystem.GetType ().ToString ();
+                               if (String.Compare (t, "System.Web.Configuration.HttpConfigurationSystem", StringComparison.OrdinalIgnoreCase) == 0)
+                                       systemWebInUse = true;
+                               else
+                                       systemWebInUse = false;
+
+                               IInternalConfigSystem old = configSystem;
+                               configSystem = newSystem;
+                               return old;
+                       }
+               }
        }
 }