WebConfigurationManager.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. //
  2. // System.Web.Configuration.WebConfigurationManager.cs
  3. //
  4. // Authors:
  5. // Lluis Sanchez Gual ([email protected])
  6. // Chris Toshok ([email protected])
  7. // Marek Habersack <[email protected]>
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. // Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
  29. //
  30. #if NET_2_0
  31. using System;
  32. using System.IO;
  33. using System.Collections;
  34. using System.Collections.Generic;
  35. using System.Collections.Specialized;
  36. using System.Reflection;
  37. #if MONOWEB_DEP
  38. using Mono.Web.Util;
  39. #endif
  40. using System.Xml;
  41. using System.Configuration;
  42. using System.Configuration.Internal;
  43. using _Configuration = System.Configuration.Configuration;
  44. using System.Web.Util;
  45. using System.Threading;
  46. namespace System.Web.Configuration {
  47. public static class WebConfigurationManager
  48. {
  49. const int SAVE_LOCATIONS_CHECK_INTERVAL = 6000; // milliseconds
  50. static readonly char[] pathTrimChars = { '/' };
  51. static readonly object suppressAppReloadLock = new object ();
  52. static readonly object saveLocationsCacheLock = new object ();
  53. static readonly ReaderWriterLockSlim sectionCacheLock;
  54. #if !TARGET_J2EE
  55. static IInternalConfigConfigurationFactory configFactory;
  56. static Hashtable configurations = Hashtable.Synchronized (new Hashtable ());
  57. static Dictionary <int, object> sectionCache = new Dictionary <int, object> ();
  58. static Hashtable configPaths = Hashtable.Synchronized (new Hashtable ());
  59. static bool suppressAppReload;
  60. #else
  61. const string AppSettingsKey = "WebConfigurationManager.AppSettings";
  62. static internal IInternalConfigConfigurationFactory configFactory
  63. {
  64. get{
  65. IInternalConfigConfigurationFactory factory = (IInternalConfigConfigurationFactory)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory");
  66. if (factory == null){
  67. lock (AppDomain.CurrentDomain){
  68. object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory.initialized");
  69. if (initialized == null){
  70. PropertyInfo prop = typeof(ConfigurationManager).GetProperty("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
  71. if (prop != null){
  72. factory = prop.GetValue(null, null) as IInternalConfigConfigurationFactory;
  73. configFactory = factory;
  74. }
  75. }
  76. }
  77. }
  78. return factory != null ? factory : configFactory;
  79. }
  80. set{
  81. AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory", value);
  82. AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory.initialized", true);
  83. }
  84. }
  85. static internal Hashtable configurations
  86. {
  87. get{
  88. Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations");
  89. if (table == null){
  90. lock (AppDomain.CurrentDomain){
  91. object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized");
  92. if (initialized == null){
  93. table = Hashtable.Synchronized (new Hashtable (StringComparer.OrdinalIgnoreCase));
  94. configurations = table;
  95. }
  96. }
  97. }
  98. return table != null ? table : configurations;
  99. }
  100. set{
  101. AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value);
  102. AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
  103. }
  104. }
  105. static Dictionary <int, object> sectionCache
  106. {
  107. get
  108. {
  109. Dictionary <int, object> sectionCache = AppDomain.CurrentDomain.GetData ("sectionCache") as Dictionary <int, object>;
  110. if (sectionCache == null) {
  111. sectionCache = new Dictionary <int, object> ();
  112. AppDomain.CurrentDomain.SetData ("sectionCache", sectionCache);
  113. }
  114. return sectionCache;
  115. }
  116. set
  117. {
  118. AppDomain.CurrentDomain.SetData ("sectionCache", value);
  119. }
  120. }
  121. static internal Hashtable configPaths
  122. {
  123. get{
  124. Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configPaths");
  125. if (table == null){
  126. lock (AppDomain.CurrentDomain){
  127. object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configPaths.initialized");
  128. if (initialized == null){
  129. table = Hashtable.Synchronized (new Hashtable (StringComparer.OrdinalIgnoreCase));
  130. configPaths = table;
  131. }
  132. }
  133. }
  134. return table != null ? table : configPaths;
  135. }
  136. set{
  137. AppDomain.CurrentDomain.SetData("WebConfigurationManager.configPaths", value);
  138. AppDomain.CurrentDomain.SetData("WebConfigurationManager.configPaths.initialized", true);
  139. }
  140. }
  141. #endif
  142. static Dictionary <string, DateTime> saveLocationsCache;
  143. static Timer saveLocationsTimer;
  144. static ArrayList extra_assemblies = null;
  145. static internal ArrayList ExtraAssemblies {
  146. get {
  147. if (extra_assemblies == null)
  148. extra_assemblies = new ArrayList();
  149. return extra_assemblies;
  150. }
  151. }
  152. static bool hasConfigErrors = false;
  153. static object hasConfigErrorsLock = new object ();
  154. static internal bool HasConfigErrors {
  155. get {
  156. lock (hasConfigErrorsLock) {
  157. return hasConfigErrors;
  158. }
  159. }
  160. }
  161. static WebConfigurationManager ()
  162. {
  163. configFactory = ConfigurationManager.ConfigurationFactory;
  164. _Configuration.SaveStart += ConfigurationSaveHandler;
  165. _Configuration.SaveEnd += ConfigurationSaveHandler;
  166. // Part of fix for bug #491531
  167. Type type = Type.GetType ("System.Configuration.CustomizableFileSettingsProvider, System", false);
  168. if (type != null) {
  169. FieldInfo fi = type.GetField ("webConfigurationFileMapType", BindingFlags.Static | BindingFlags.NonPublic);
  170. if (fi != null && fi.FieldType == Type.GetType ("System.Type"))
  171. fi.SetValue (null, typeof (ApplicationSettingsConfigurationFileMap));
  172. }
  173. sectionCacheLock = new ReaderWriterLockSlim ();
  174. }
  175. static void ReenableWatcherOnConfigLocation (object state)
  176. {
  177. string path = state as string;
  178. if (String.IsNullOrEmpty (path))
  179. return;
  180. DateTime lastWrite;
  181. lock (saveLocationsCacheLock) {
  182. if (!saveLocationsCache.TryGetValue (path, out lastWrite))
  183. lastWrite = DateTime.MinValue;
  184. }
  185. DateTime now = DateTime.Now;
  186. if (lastWrite == DateTime.MinValue || now.Subtract (lastWrite).TotalMilliseconds >= SAVE_LOCATIONS_CHECK_INTERVAL) {
  187. saveLocationsTimer.Dispose ();
  188. saveLocationsTimer = null;
  189. HttpApplicationFactory.EnableWatcher (VirtualPathUtility.RemoveTrailingSlash (HttpRuntime.AppDomainAppPath), "?eb.?onfig");
  190. } else
  191. saveLocationsTimer.Change (SAVE_LOCATIONS_CHECK_INTERVAL, SAVE_LOCATIONS_CHECK_INTERVAL);
  192. }
  193. static void ConfigurationSaveHandler (_Configuration sender, ConfigurationSaveEventArgs args)
  194. {
  195. bool locked = false;
  196. try {
  197. sectionCacheLock.EnterWriteLock ();
  198. locked = true;
  199. sectionCache.Clear ();
  200. } finally {
  201. if (locked)
  202. sectionCacheLock.ExitWriteLock ();
  203. }
  204. lock (suppressAppReloadLock) {
  205. string rootConfigPath = WebConfigurationHost.GetWebConfigFileName (HttpRuntime.AppDomainAppPath);
  206. if (String.Compare (args.StreamPath, rootConfigPath, StringComparison.OrdinalIgnoreCase) == 0) {
  207. SuppressAppReload (args.Start);
  208. if (args.Start) {
  209. HttpApplicationFactory.DisableWatcher (VirtualPathUtility.RemoveTrailingSlash (HttpRuntime.AppDomainAppPath), "?eb.?onfig");
  210. lock (saveLocationsCacheLock) {
  211. if (saveLocationsCache == null)
  212. saveLocationsCache = new Dictionary <string, DateTime> (StringComparer.Ordinal);
  213. if (saveLocationsCache.ContainsKey (rootConfigPath))
  214. saveLocationsCache [rootConfigPath] = DateTime.Now;
  215. else
  216. saveLocationsCache.Add (rootConfigPath, DateTime.Now);
  217. if (saveLocationsTimer == null)
  218. saveLocationsTimer = new Timer (ReenableWatcherOnConfigLocation,
  219. rootConfigPath,
  220. SAVE_LOCATIONS_CHECK_INTERVAL,
  221. SAVE_LOCATIONS_CHECK_INTERVAL);
  222. }
  223. }
  224. }
  225. }
  226. }
  227. public static _Configuration OpenMachineConfiguration ()
  228. {
  229. return ConfigurationManager.OpenMachineConfiguration ();
  230. }
  231. [MonoLimitation ("locationSubPath is not handled")]
  232. public static _Configuration OpenMachineConfiguration (string locationSubPath)
  233. {
  234. return OpenMachineConfiguration ();
  235. }
  236. [MonoLimitation("Mono does not support remote configuration")]
  237. public static _Configuration OpenMachineConfiguration (string locationSubPath,
  238. string server)
  239. {
  240. if (server == null)
  241. return OpenMachineConfiguration (locationSubPath);
  242. throw new NotSupportedException ("Mono doesn't support remote configuration");
  243. }
  244. [MonoLimitation("Mono does not support remote configuration")]
  245. public static _Configuration OpenMachineConfiguration (string locationSubPath,
  246. string server,
  247. IntPtr userToken)
  248. {
  249. if (server == null)
  250. return OpenMachineConfiguration (locationSubPath);
  251. throw new NotSupportedException ("Mono doesn't support remote configuration");
  252. }
  253. [MonoLimitation("Mono does not support remote configuration")]
  254. public static _Configuration OpenMachineConfiguration (string locationSubPath,
  255. string server,
  256. string userName,
  257. string password)
  258. {
  259. if (server == null)
  260. return OpenMachineConfiguration (locationSubPath);
  261. throw new NotSupportedException ("Mono doesn't support remote configuration");
  262. }
  263. public static _Configuration OpenWebConfiguration (string path)
  264. {
  265. return OpenWebConfiguration (path, null, null, null, null, null);
  266. }
  267. public static _Configuration OpenWebConfiguration (string path, string site)
  268. {
  269. return OpenWebConfiguration (path, site, null, null, null, null);
  270. }
  271. public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
  272. {
  273. return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
  274. }
  275. public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server)
  276. {
  277. return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
  278. }
  279. public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
  280. {
  281. return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
  282. }
  283. public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
  284. {
  285. return OpenWebConfiguration (path, site, locationSubPath, server, null, null, false);
  286. }
  287. static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password, bool fweb)
  288. {
  289. if (String.IsNullOrEmpty (path))
  290. path = "/";
  291. if (!fweb && !String.IsNullOrEmpty (path))
  292. path = FindWebConfig (path);
  293. string confKey = path + site + locationSubPath + server + userName + password;
  294. _Configuration conf = null;
  295. conf = (_Configuration) configurations [confKey];
  296. if (conf == null) {
  297. try {
  298. conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password);
  299. configurations [confKey] = conf;
  300. } catch (Exception ex) {
  301. lock (hasConfigErrorsLock) {
  302. hasConfigErrors = true;
  303. }
  304. throw ex;
  305. }
  306. }
  307. return conf;
  308. }
  309. public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
  310. {
  311. return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
  312. }
  313. public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site)
  314. {
  315. return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site);
  316. }
  317. public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath)
  318. {
  319. return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath);
  320. }
  321. public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap)
  322. {
  323. return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
  324. }
  325. public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
  326. string locationSubPath)
  327. {
  328. return OpenMappedMachineConfiguration (fileMap);
  329. }
  330. internal static object SafeGetSection (string sectionName, Type configSectionType)
  331. {
  332. try {
  333. return GetSection (sectionName);
  334. } catch (Exception) {
  335. if (configSectionType != null)
  336. return Activator.CreateInstance (configSectionType);
  337. return null;
  338. }
  339. }
  340. internal static object SafeGetSection (string sectionName, string path, Type configSectionType)
  341. {
  342. try {
  343. return GetSection (sectionName, path);
  344. } catch (Exception) {
  345. if (configSectionType != null)
  346. return Activator.CreateInstance (configSectionType);
  347. return null;
  348. }
  349. }
  350. public static object GetSection (string sectionName)
  351. {
  352. HttpContext context = HttpContext.Current;
  353. return GetSection (sectionName, GetCurrentPath (context), context);
  354. }
  355. public static object GetSection (string sectionName, string path)
  356. {
  357. return GetSection (sectionName, path, HttpContext.Current);
  358. }
  359. static bool LookUpLocation (string relativePath, ref _Configuration defaultConfiguration)
  360. {
  361. if (String.IsNullOrEmpty (relativePath))
  362. return false;
  363. _Configuration cnew = defaultConfiguration.FindLocationConfiguration (relativePath, defaultConfiguration);
  364. if (cnew == defaultConfiguration)
  365. return false;
  366. defaultConfiguration = cnew;
  367. return true;
  368. }
  369. internal static object GetSection (string sectionName, string path, HttpContext context)
  370. {
  371. if (String.IsNullOrEmpty (sectionName))
  372. return null;
  373. _Configuration c = OpenWebConfiguration (path, null, null, null, null, null, false);
  374. string configPath = c.ConfigPath;
  375. int baseCacheKey = 0;
  376. int cacheKey;
  377. bool pathPresent = !String.IsNullOrEmpty (path);
  378. string locationPath = null;
  379. bool locked = false;
  380. if (pathPresent)
  381. locationPath = "location_" + path;
  382. baseCacheKey = sectionName.GetHashCode ();
  383. if (configPath != null)
  384. baseCacheKey ^= configPath.GetHashCode ();
  385. try {
  386. sectionCacheLock.EnterReadLock ();
  387. locked = true;
  388. object o;
  389. if (pathPresent) {
  390. cacheKey = baseCacheKey ^ locationPath.GetHashCode ();
  391. if (sectionCache.TryGetValue (cacheKey, out o))
  392. return o;
  393. cacheKey = baseCacheKey ^ path.GetHashCode ();
  394. if (sectionCache.TryGetValue (cacheKey, out o))
  395. return o;
  396. }
  397. if (sectionCache.TryGetValue (baseCacheKey, out o))
  398. return o;
  399. } finally {
  400. if (locked)
  401. sectionCacheLock.ExitReadLock ();
  402. }
  403. string cachePath = null;
  404. if (pathPresent) {
  405. string relPath;
  406. if (VirtualPathUtility.IsRooted (path)) {
  407. if (path [0] == '~')
  408. relPath = path.Length > 1 ? path.Substring (2) : String.Empty;
  409. else if (path [0] == '/')
  410. relPath = path.Substring (1);
  411. else
  412. relPath = path;
  413. } else
  414. relPath = path;
  415. HttpRequest req = context != null ? context.Request : null;
  416. if (req != null) {
  417. string vdir = VirtualPathUtility.GetDirectory (req.PathNoValidation);
  418. if (vdir != null) {
  419. vdir = vdir.TrimEnd (pathTrimChars);
  420. if (String.Compare (c.ConfigPath, vdir, StringComparison.Ordinal) != 0 && LookUpLocation (vdir.Trim (pathTrimChars), ref c))
  421. cachePath = path;
  422. }
  423. }
  424. if (LookUpLocation (relPath, ref c))
  425. cachePath = locationPath;
  426. else
  427. cachePath = path;
  428. }
  429. ConfigurationSection section = c.GetSection (sectionName);
  430. if (section == null)
  431. return null;
  432. #if TARGET_J2EE
  433. object value = get_runtime_object.Invoke (section, new object [0]);
  434. if (String.CompareOrdinal ("appSettings", sectionName) == 0) {
  435. NameValueCollection collection;
  436. collection = new KeyValueMergedCollection (HttpContext.Current, (NameValueCollection) value);
  437. value = collection;
  438. }
  439. #else
  440. #if MONOWEB_DEP
  441. object value = SettingsMappingManager.MapSection (get_runtime_object.Invoke (section, new object [0]));
  442. #else
  443. object value = null;
  444. #endif
  445. #endif
  446. if (cachePath != null)
  447. cacheKey = baseCacheKey ^ cachePath.GetHashCode ();
  448. else
  449. cacheKey = baseCacheKey;
  450. AddSectionToCache (cacheKey, value);
  451. return value;
  452. }
  453. static string MapPath (HttpRequest req, string virtualPath)
  454. {
  455. if (req != null)
  456. return req.MapPath (virtualPath);
  457. string appRoot = HttpRuntime.AppDomainAppVirtualPath;
  458. if (!String.IsNullOrEmpty (appRoot) && virtualPath.StartsWith (appRoot, StringComparison.Ordinal)) {
  459. if (String.Compare (virtualPath, appRoot, StringComparison.Ordinal) == 0)
  460. return HttpRuntime.AppDomainAppPath;
  461. return UrlUtils.Combine (HttpRuntime.AppDomainAppPath, virtualPath.Substring (appRoot.Length));
  462. }
  463. return null;
  464. }
  465. static string GetParentDir (string rootPath, string curPath)
  466. {
  467. int len = curPath.Length - 1;
  468. if (len > 0 && curPath [len] == '/')
  469. curPath = curPath.Substring (0, len);
  470. if (String.Compare (curPath, rootPath, StringComparison.Ordinal) == 0)
  471. return null;
  472. int idx = curPath.LastIndexOf ('/');
  473. if (idx == -1)
  474. return curPath;
  475. if (idx == 0)
  476. return "/";
  477. return curPath.Substring (0, idx);
  478. }
  479. internal static string FindWebConfig (string path)
  480. {
  481. if (String.IsNullOrEmpty (path))
  482. return path;
  483. string dir;
  484. if (path [path.Length - 1] == '/')
  485. dir = path;
  486. else {
  487. dir = VirtualPathUtility.GetDirectory (path, false);
  488. if (dir == null)
  489. return path;
  490. }
  491. string curPath = configPaths [dir] as string;
  492. if (curPath != null)
  493. return curPath;
  494. HttpContext ctx = HttpContext.Current;
  495. HttpRequest req = ctx != null ? ctx.Request : null;
  496. if (req == null)
  497. return path;
  498. curPath = path;
  499. string rootPath = HttpRuntime.AppDomainAppVirtualPath;
  500. string physPath;
  501. while (String.Compare (curPath, rootPath, StringComparison.Ordinal) != 0) {
  502. physPath = MapPath (req, curPath);
  503. if (physPath == null) {
  504. curPath = rootPath;
  505. break;
  506. }
  507. if (WebConfigurationHost.GetWebConfigFileName (physPath) != null)
  508. break;
  509. curPath = GetParentDir (rootPath, curPath);
  510. if (curPath == null || curPath == "~") {
  511. curPath = rootPath;
  512. break;
  513. }
  514. }
  515. configPaths [dir] = curPath;
  516. return curPath;
  517. }
  518. static string GetCurrentPath (HttpContext ctx)
  519. {
  520. HttpRequest req = ctx != null ? ctx.Request : null;
  521. return req != null ? req.PathNoValidation : HttpRuntime.AppDomainAppVirtualPath;
  522. }
  523. internal static bool SuppressAppReload (bool newValue)
  524. {
  525. bool ret;
  526. lock (suppressAppReloadLock) {
  527. ret = suppressAppReload;
  528. suppressAppReload = newValue;
  529. }
  530. return ret;
  531. }
  532. internal static void RemoveConfigurationFromCache (HttpContext ctx)
  533. {
  534. configurations.Remove (GetCurrentPath (ctx));
  535. }
  536. #if TARGET_J2EE || MONOWEB_DEP
  537. readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
  538. #endif
  539. public static object GetWebApplicationSection (string sectionName)
  540. {
  541. HttpContext ctx = HttpContext.Current;
  542. HttpRequest req = ctx != null ? ctx.Request : null;
  543. string applicationPath = req != null ? req.ApplicationPath : null;
  544. return GetSection (sectionName, String.IsNullOrEmpty (applicationPath) ? String.Empty : applicationPath);
  545. }
  546. public static NameValueCollection AppSettings {
  547. get { return ConfigurationManager.AppSettings; }
  548. }
  549. public static ConnectionStringSettingsCollection ConnectionStrings {
  550. get { return ConfigurationManager.ConnectionStrings; }
  551. }
  552. internal static IInternalConfigConfigurationFactory ConfigurationFactory {
  553. get { return configFactory; }
  554. }
  555. static void AddSectionToCache (int key, object section)
  556. {
  557. object cachedSection;
  558. bool locked = false;
  559. try {
  560. sectionCacheLock.EnterUpgradeableReadLock ();
  561. locked = true;
  562. if (sectionCache.TryGetValue (key, out cachedSection) && cachedSection != null)
  563. return;
  564. bool innerLocked = false;
  565. try {
  566. sectionCacheLock.EnterWriteLock ();
  567. innerLocked = true;
  568. sectionCache.Add (key, section);
  569. } finally {
  570. if (innerLocked)
  571. sectionCacheLock.ExitWriteLock ();
  572. }
  573. } finally {
  574. if (locked)
  575. sectionCacheLock.ExitUpgradeableReadLock ();
  576. }
  577. }
  578. #region stuff copied from WebConfigurationSettings
  579. #if TARGET_J2EE
  580. static internal IConfigurationSystem oldConfig {
  581. get {
  582. return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
  583. }
  584. set {
  585. AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
  586. }
  587. }
  588. static Web20DefaultConfig config {
  589. get {
  590. return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
  591. }
  592. set {
  593. AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
  594. }
  595. }
  596. static IInternalConfigSystem configSystem {
  597. get {
  598. return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
  599. }
  600. set {
  601. AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
  602. }
  603. }
  604. #else
  605. static internal IConfigurationSystem oldConfig;
  606. static Web20DefaultConfig config;
  607. //static IInternalConfigSystem configSystem;
  608. #endif
  609. const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
  610. static readonly object lockobj = new object ();
  611. internal static void Init ()
  612. {
  613. lock (lockobj) {
  614. if (config != null)
  615. return;
  616. /* deal with the ConfigurationSettings stuff */
  617. {
  618. Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
  619. Type t = typeof (ConfigurationSettings);
  620. MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
  621. privStatic);
  622. if (changeConfig == null)
  623. throw new ConfigurationException ("Cannot find method CCS");
  624. object [] args = new object [] {settings};
  625. oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
  626. config = settings;
  627. config.Init ();
  628. }
  629. /* deal with the ConfigurationManager stuff */
  630. {
  631. HttpConfigurationSystem system = new HttpConfigurationSystem ();
  632. Type t = typeof (ConfigurationManager);
  633. MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
  634. privStatic);
  635. if (changeConfig == null)
  636. throw new ConfigurationException ("Cannot find method CCS");
  637. object [] args = new object [] {system};
  638. changeConfig.Invoke (null, args);
  639. //configSystem = system;
  640. }
  641. }
  642. }
  643. }
  644. class Web20DefaultConfig : IConfigurationSystem
  645. {
  646. #if TARGET_J2EE
  647. static Web20DefaultConfig instance {
  648. get {
  649. Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
  650. if (val == null) {
  651. val = new Web20DefaultConfig();
  652. AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
  653. }
  654. return val;
  655. }
  656. set {
  657. AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
  658. }
  659. }
  660. #else
  661. static Web20DefaultConfig instance;
  662. #endif
  663. static Web20DefaultConfig ()
  664. {
  665. instance = new Web20DefaultConfig ();
  666. }
  667. public static Web20DefaultConfig GetInstance ()
  668. {
  669. return instance;
  670. }
  671. public object GetConfig (string sectionName)
  672. {
  673. object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
  674. if (o == null || o is IgnoreSection) {
  675. /* this can happen when the section
  676. * handler doesn't subclass from
  677. * ConfigurationSection. let's be
  678. * nice and try to load it using the
  679. * 1.x style routines in case there's
  680. * a 1.x section handler registered
  681. * for it.
  682. */
  683. object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
  684. if (o1 != null)
  685. return o1;
  686. }
  687. return o;
  688. }
  689. public void Init ()
  690. {
  691. // nothing. We need a context.
  692. }
  693. }
  694. #endregion
  695. }
  696. #endif