PageRenderTime 63ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Web/Nalarium.Web.Processing/ConfigurationLoader.cs

https://bitbucket.org/davidbetz/nalarium
C# | 956 lines | 855 code | 25 blank | 76 comment | 194 complexity | 5aa095f375afb1d243a3e840438c5475 MD5 | raw file
  1. #region Copyright
  2. //+ Nalarium Pro 3.0 - Web Module
  3. //+ Copyright © Jampad Technology, Inc. 2008-2010
  4. #endregion
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Configuration;
  8. using System.Globalization;
  9. using System.Linq;
  10. using System.Threading;
  11. using Nalarium.Activation;
  12. using Nalarium.Configuration;
  13. using Nalarium.Web.Globalization;
  14. using Nalarium.Web.Processing.Configuration;
  15. using Nalarium.Web.Processing.Data;
  16. using Nalarium.Web.Security;
  17. using ParameterCollection = Nalarium.Web.Processing.Configuration.ParameterCollection;
  18. using ParameterElement = Nalarium.Configuration.ParameterElement;
  19. //+
  20. namespace Nalarium.Web.Processing
  21. {
  22. internal static class ConfigurationLoader
  23. {
  24. //- ~Info -//
  25. //+
  26. private static ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim();
  27. //+
  28. //- ~InitWebDomain -//
  29. internal static void InitWebDomain(String webDomainName, WebDomainElement webDomainElement, WebDomainDataList webDomainDataList)
  30. {
  31. //+ based on
  32. WebDomainData data = null;
  33. if (!webDomainElement.IsAbstract && webDomainName != Info.Root)
  34. {
  35. if (String.IsNullOrEmpty(webDomainElement.Path) && String.IsNullOrEmpty(webDomainElement.Subdomain))
  36. {
  37. throw new ConfigurationErrorsException(Resource.WebDomain_PathAndSubdomainNotFound);
  38. }
  39. }
  40. if (!String.IsNullOrEmpty(webDomainElement.BasedOn))
  41. {
  42. data = CopyWebDomain(webDomainElement.BasedOn.ToLower(CultureInfo.CurrentCulture), webDomainDataList);
  43. if (data == null)
  44. {
  45. throw new InvalidOperationException(String.Format(Resource.WebDomain_Invalid, webDomainElement.BasedOn));
  46. }
  47. data.BasedOn = webDomainElement.BasedOn;
  48. //++ non-subdomain web domain based on subdomain web domain?
  49. if (String.IsNullOrEmpty(webDomainElement.Subdomain) && !String.IsNullOrEmpty(data.Subdomain))
  50. {
  51. data.Subdomain = String.Empty;
  52. }
  53. }
  54. if (data == null)
  55. {
  56. data = new WebDomainData();
  57. }
  58. //++ important note:
  59. //++ there is no way to know if the person wants to set false or just didn't set it.
  60. //++ therefore, you cannot disable this setting in web domain inheritance. You must
  61. //++ create the web domain fresh.
  62. data.CatchAllMode = webDomainElement.CatchAllMode;
  63. data.CatchAllInitParameter = webDomainElement.CatchAllInitParameter;
  64. data.Name = webDomainName;
  65. if (!String.IsNullOrEmpty(webDomainElement.AccessRuleGroup))
  66. {
  67. data.AccessRuleGroup = webDomainElement.AccessRuleGroup;
  68. }
  69. if (!String.IsNullOrEmpty(webDomainElement.Default))
  70. {
  71. DefaultType type;
  72. String parameter;
  73. String customParameter;
  74. ParseDefault(webDomainElement.Default, webDomainElement.DefaultParameter, out parameter, out type, out customParameter);
  75. //+
  76. if (String.IsNullOrEmpty(parameter))
  77. {
  78. parameter = webDomainElement.DefaultParameter;
  79. }
  80. if (!String.IsNullOrEmpty(customParameter))
  81. {
  82. data.CustomParameter = customParameter;
  83. }
  84. data.DefaultParameter = UrlCleaner.CleanWebPathHead(parameter);
  85. data.DefaultType = type;
  86. }
  87. if (webDomainName == Info.Root)
  88. {
  89. data.Path = String.Empty;
  90. data.Subdomain = String.Empty;
  91. }
  92. else
  93. {
  94. data.Path = UrlCleaner.CleanWebPath(webDomainElement.Path.ToLower(CultureInfo.CurrentCulture));
  95. data.Subdomain = webDomainElement.Subdomain;
  96. }
  97. data.IsSealed = webDomainElement.IsSealed;
  98. data.ProcessorDataList = new ProcessorDataList();
  99. data.FactoryDataList = new FactoryDataList();
  100. //+ parameter
  101. data.ParameterDataList = GetWebDomainParameterData(webDomainElement.Parameters);
  102. //+ reset
  103. ResetFlags flags = ResetFlagReader.Read(webDomainElement.ResetSeries);
  104. if (data.ComponentDataList == null || (flags & ResetFlags.Component) == ResetFlags.Component)
  105. {
  106. data.ComponentDataList = new ComponentDataList();
  107. }
  108. if (data.InitProcessorDataList == null || (flags & ResetFlags.Init) == ResetFlags.Init)
  109. {
  110. data.InitProcessorDataList = new InitProcessorDataList();
  111. }
  112. if (data.ErrorProcessorDataList == null || (flags & ResetFlags.Error) == ResetFlags.Error)
  113. {
  114. data.ErrorProcessorDataList = new ErrorProcessorDataList();
  115. }
  116. if (data.SelectionProcessorDataList == null || (flags & ResetFlags.Selection) == ResetFlags.Selection)
  117. {
  118. data.SelectionProcessorDataList = new SelectionProcessorDataList();
  119. }
  120. if (data.OverrideProcessorDataList == null || (flags & ResetFlags.Override) == ResetFlags.Override)
  121. {
  122. data.OverrideProcessorDataList = new OverrideProcessorDataList();
  123. }
  124. if (data.StateProcessorDataList == null || (flags & ResetFlags.State) == ResetFlags.State)
  125. {
  126. data.StateProcessorDataList = new StateProcessorDataList();
  127. }
  128. if (data.PostRenderProcessorDataList == null || (flags & ResetFlags.PostRender) == ResetFlags.PostRender)
  129. {
  130. data.PostRenderProcessorDataList = new PostRenderProcessorDataList();
  131. }
  132. if (data.HandlerFactoryDataList == null || (flags & ResetFlags.HandlerFactory) == ResetFlags.HandlerFactory)
  133. {
  134. data.HandlerFactoryDataList = new EndpointFactoryDataList();
  135. }
  136. if (data.ProcessorFactoryDataList == null || (flags & ResetFlags.ProcessorFactory) == ResetFlags.ProcessorFactory)
  137. {
  138. data.ProcessorFactoryDataList = new ProcessorFactoryDataList();
  139. }
  140. if (data.EndpointDataList == null || (flags & ResetFlags.Endpoint) == ResetFlags.Endpoint)
  141. {
  142. data.EndpointDataList = new EndpointDataList();
  143. }
  144. if (data.ObjectFactoryDataList == null || (flags & ResetFlags.ObjectFactory) == ResetFlags.ObjectFactory)
  145. {
  146. data.ObjectFactoryDataList = new ObjectFactoryDataList();
  147. }
  148. if (data.SecurityData == null || (flags & ResetFlags.Security) == ResetFlags.Security)
  149. {
  150. data.SecurityData = new SecurityData();
  151. }
  152. if (data.SecurityData.SecurityExceptionDataList == null)
  153. {
  154. data.SecurityData.SecurityExceptionDataList = new SecurityExceptionDataList();
  155. }
  156. if (data.CatchAllEndpoint == null)
  157. {
  158. data.CatchAllEndpoint = new EndpointData();
  159. }
  160. //+ rule
  161. //LoadAccessRuleData(data, webDomainElement.AccessRules);
  162. //+ component
  163. LoadComponentData(data, webDomainElement.Components, webDomainElement.BasedOn);
  164. //+ factory
  165. LoadFactoryData(data, webDomainElement.Factories);
  166. //+ processor
  167. LoadProcessorData(data, webDomainElement.Processors);
  168. //+ handler
  169. LoadEndpointData(data, webDomainElement.Endpoints);
  170. //+ favicon
  171. FaviconMode faviconMode = ProcessingSection.GetConfigSection().WebDomain.FaviconMode;
  172. switch (faviconMode)
  173. {
  174. case FaviconMode.PassThrough:
  175. data.EndpointDataList.Add(EndpointData.Create(SelectorType.EndsWith, "/Favicon.ico", "{ForcePassThrough}"));
  176. PassThroughHttpHandler.ForceUse = true;
  177. break;
  178. case FaviconMode.Exclusion:
  179. data.EndpointDataList.Add(EndpointData.Create(SelectorType.EndsWith, "/Favicon.ico", "{Exclusion}"));
  180. break;
  181. }
  182. data.EndpointDataList.Add(EndpointData.Create(SelectorType.Contains, "/WebResource.axd?d=", "{Exclusion}"));
  183. //+ security
  184. LoadSecurityData(data, webDomainElement.Security);
  185. //+
  186. webDomainDataList.Add(data);
  187. }
  188. private static void ParseDefault(String text, String specifiedParameter, out String actualParameter, out DefaultType type, out String customParameter)
  189. {
  190. customParameter = String.Empty;
  191. //++
  192. //TODO: Consider creating a markup extension system for this.
  193. //++
  194. if (text.Equals("page", StringComparison.InvariantCultureIgnoreCase))
  195. {
  196. type = DefaultType.Page;
  197. actualParameter = specifiedParameter;
  198. }
  199. else if (text.Equals("sequence", StringComparison.InvariantCultureIgnoreCase))
  200. {
  201. type = DefaultType.Sequence;
  202. actualParameter = specifiedParameter;
  203. }
  204. else if (text.Equals("mvc", StringComparison.InvariantCultureIgnoreCase))
  205. {
  206. type = DefaultType.Mvc;
  207. actualParameter = String.Empty;
  208. }
  209. else if (text.StartsWith("{page ", StringComparison.InvariantCultureIgnoreCase))
  210. {
  211. type = DefaultType.Page;
  212. //+
  213. Int32 indexOfSpace = text.IndexOf(' ');
  214. actualParameter = text.Substring(indexOfSpace + 1, text.Length - indexOfSpace - 2);
  215. }
  216. else if (text.StartsWith("{sequence ", StringComparison.InvariantCultureIgnoreCase))
  217. {
  218. type = DefaultType.Sequence;
  219. //+
  220. Int32 indexOfSpace = text.IndexOf(' ');
  221. actualParameter = text.Substring(indexOfSpace + 1, text.Length - indexOfSpace - 2);
  222. }
  223. else if (text.StartsWith("{handler ", StringComparison.InvariantCultureIgnoreCase))
  224. {
  225. type = DefaultType.Handler;
  226. //+
  227. Int32 indexOfSpace = text.IndexOf(' ');
  228. actualParameter = text.Substring(indexOfSpace + 1, text.Length - indexOfSpace - 2);
  229. }
  230. else if (text.EndsWith("}") && text.Contains(" "))
  231. {
  232. type = DefaultType.Handler;
  233. //+
  234. Int32 indexOfSpace = text.IndexOf(' ');
  235. customParameter = text.Substring(1, indexOfSpace - 1);
  236. actualParameter = text.Substring(indexOfSpace + 1, text.Length - indexOfSpace - 2);
  237. }
  238. else if (text.StartsWith("{", StringComparison.InvariantCultureIgnoreCase))
  239. {
  240. type = DefaultType.Sequence;
  241. actualParameter = text;
  242. }
  243. else if (text.Contains("/"))
  244. {
  245. type = DefaultType.Page;
  246. actualParameter = text;
  247. }
  248. else
  249. {
  250. type = DefaultType.Unknown;
  251. actualParameter = String.Empty;
  252. }
  253. }
  254. //- ~LoadSecurityData -//
  255. internal static void LoadSecurityData(WebDomainData data, SecurityElement securityElement)
  256. {
  257. if (securityElement.Disabled || securityElement.DefaultAccessMode == null)
  258. {
  259. data.SecurityData = new SecurityData
  260. {
  261. Disabled = true
  262. };
  263. //+
  264. return;
  265. }
  266. data.SecurityData.Disabled = false;
  267. data.SecurityData.DefaultAccessMode = securityElement.DefaultAccessMode ?? DefaultAccessMode.Block;
  268. data.SecurityData.ValidatorType = securityElement.ValidatorType;
  269. data.SecurityData.LoginText = securityElement.LoginText;
  270. data.SecurityData.LogoutText = securityElement.LogoutText;
  271. data.SecurityData.DefaultLoggedInTarget = securityElement.DefaultLoggedInTarget;
  272. SecurityExceptionCollection collection = securityElement.Exceptions;
  273. if (String.IsNullOrEmpty(securityElement.LoginPage))
  274. {
  275. throw new ArgumentException(ResourceAccessor.GetString("Security_LoginTargetRequired"));
  276. }
  277. data.SecurityData.LoginPage = securityElement.LoginPage;
  278. data.SecurityData.LogoutPage = securityElement.LogoutPage;
  279. List<SecurityExceptionElement> elementList = collection.ToList();
  280. foreach (SecurityExceptionElement element in elementList)
  281. {
  282. if (data.SecurityData.SecurityExceptionDataList.Any(p => p.Key == element.Key))
  283. {
  284. continue;
  285. }
  286. data.SecurityData.SecurityExceptionDataList.Add(new SecurityExceptionData
  287. {
  288. Key = element.Key
  289. });
  290. }
  291. String type;
  292. if (data.SecurityData.LoginText.StartsWith("{"))
  293. {
  294. type = "sequence";
  295. }
  296. else
  297. {
  298. type = "page";
  299. }
  300. data.EndpointDataList.Insert(0, new EndpointData
  301. {
  302. Type = type,
  303. Text = UrlCleaner.CleanWebPathTail(data.SecurityData.LoginText) + "/",
  304. TextWithoutSlash = UrlCleaner.CleanWebPathTail(data.SecurityData.LoginText),
  305. Selector = SelectorType.EndsWith,
  306. ParameterValue = data.SecurityData.LoginPage
  307. });
  308. if (!String.IsNullOrEmpty(data.SecurityData.LogoutPage))
  309. {
  310. data.EndpointDataList.Insert(0, new EndpointData
  311. {
  312. Type = type,
  313. Text = UrlCleaner.CleanWebPathTail(data.SecurityData.LogoutText) + "/",
  314. TextWithoutSlash = UrlCleaner.CleanWebPathTail(data.SecurityData.LogoutText),
  315. Selector = SelectorType.EndsWith,
  316. ParameterValue = data.SecurityData.LogoutPage
  317. });
  318. }
  319. }
  320. internal static void LoadComponentData(WebDomainData data, ComponentCollection componentCollection, String webDomainBasedOn)
  321. {
  322. List<ComponentElement> componentList = componentCollection.OrderBy(p => p.Priority).ToList();
  323. foreach (ComponentElement element in componentList)
  324. {
  325. ComponentData activeComponent = null;
  326. String componentType = element.ComponentType;
  327. String key = element.Key;
  328. ParameterDataList parameterDataList;
  329. //+ load
  330. if (String.IsNullOrEmpty(webDomainBasedOn))
  331. {
  332. parameterDataList = GetComponentParameterData(element.Parameters);
  333. //+
  334. activeComponent = new ComponentData
  335. {
  336. ComponentType = componentType,
  337. Key = key,
  338. ParameterDataList = parameterDataList
  339. };
  340. //+ No base
  341. data.ComponentDataList.Add(activeComponent);
  342. }
  343. else
  344. {
  345. //+ Has base
  346. ComponentElement newElement = element;
  347. //+ find new
  348. ComponentData existingData = data.ComponentDataList.FirstOrDefault(p => p.Key == key);
  349. componentType = existingData.ComponentType;
  350. activeComponent = existingData;
  351. if (existingData == null)
  352. {
  353. continue;
  354. }
  355. if (String.IsNullOrEmpty(existingData.ComponentType))
  356. {
  357. throw new InvalidOperationException(Resource.General_NotFound);
  358. }
  359. //+ copy new
  360. parameterDataList = existingData.ParameterDataList;
  361. if (newElement.Parameters.ResetCollection)
  362. {
  363. parameterDataList = GetComponentParameterData(newElement.Parameters);
  364. }
  365. Boolean hasDifferentParameter = false;
  366. ComponentParameterCollection parameterCollection = newElement.Parameters;
  367. foreach (ParameterElement parameterElement in parameterCollection)
  368. {
  369. ParameterData existingParameterData = parameterDataList.FirstOrDefault(p => p.Name == parameterElement.Name);
  370. if (existingParameterData != null)
  371. {
  372. if (!parameterElement.Value.Equals(existingParameterData.Value))
  373. {
  374. hasDifferentParameter = true;
  375. }
  376. existingParameterData.Value = parameterElement.Value;
  377. }
  378. }
  379. if (hasDifferentParameter)
  380. {
  381. RemoveEachPartInstalledByComponent(data, key);
  382. }
  383. }
  384. //+
  385. try
  386. {
  387. var component = ObjectCreator.CreateAs<Component>(componentType);
  388. if (component == null)
  389. {
  390. throw new EntityNotFoundException(String.Format(Resource.General_NotFound, componentType));
  391. }
  392. component.Key = key;
  393. //+
  394. if (component != null)
  395. {
  396. if (!activeComponent.IsInstalled)
  397. {
  398. component.Connect(data.FactoryDataList, data.ProcessorDataList, data.EndpointDataList);
  399. component.ParameterMap = parameterDataList.GetMap();
  400. component.Register();
  401. activeComponent.IsInstalled = true;
  402. }
  403. }
  404. }
  405. catch (Exception ex)
  406. {
  407. if (WebProcessingReportController.Reporter.Initialized)
  408. {
  409. var map = new Map();
  410. map.Add("Section", "Component");
  411. map.Add("Type", componentType);
  412. map.Add("Message", ex.Message);
  413. map.Add("Exception Type", ex.GetType().FullName);
  414. //+
  415. WebProcessingReportController.Reporter.AddMap(map);
  416. }
  417. }
  418. }
  419. }
  420. //- $RemoveEachPartInstalledByComponent -//
  421. private static void RemoveEachPartInstalledByComponent(WebDomainData data, String componentKey)
  422. {
  423. data.HandlerFactoryDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  424. data.ProcessorFactoryDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  425. //+
  426. data.InitProcessorDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  427. data.SelectionProcessorDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  428. data.OverrideProcessorDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  429. data.StateProcessorDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  430. data.ErrorProcessorDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  431. //+
  432. data.EndpointDataList.RemoveAll(f => !String.IsNullOrEmpty(f.Source) && f.Source.Equals(componentKey));
  433. }
  434. //- ~LoadFactoryData -//
  435. internal static void LoadFactoryData(WebDomainData data, FactoryCollection collection)
  436. {
  437. List<FactoryElement> elementList = collection.ToList();
  438. foreach (FactoryElement factory in elementList)
  439. {
  440. if (!factory.Enabled)
  441. {
  442. continue;
  443. }
  444. LoadSingleFactoryData(data, factory.FactoryType, factory.GetParameterArray(), factory.GetParameterMap(), String.Empty);
  445. }
  446. foreach (FactoryData factory in data.FactoryDataList)
  447. {
  448. LoadSingleFactoryData(data, factory.FactoryType, factory.ParameterArray, factory.ParameterMap, factory.Source);
  449. }
  450. //+
  451. data.HandlerFactoryDataList.OriginalCount = data.HandlerFactoryDataList.Count;
  452. data.ProcessorFactoryDataList.OriginalCount = data.ProcessorFactoryDataList.Count;
  453. }
  454. //- $LoadSingleFactoryData -//
  455. private static void LoadSingleFactoryData(WebDomainData data, String factoryType, Object[] parameterArray, Map parameterMap, String source)
  456. {
  457. var readerWriterLockSlim = new ReaderWriterLockSlim();
  458. try
  459. {
  460. IFactory factory = null;
  461. //+
  462. readerWriterLockSlim.EnterUpgradeableReadLock();
  463. if (!RouteCache.HandlerFactoryCache.ContainsKey(factoryType) && !RouteCache.ProcessorFactoryCache.ContainsKey(factoryType))
  464. {
  465. readerWriterLockSlim.EnterWriteLock();
  466. //+
  467. try
  468. {
  469. if (!RouteCache.HandlerFactoryCache.ContainsKey(factoryType) && !RouteCache.ProcessorFactoryCache.ContainsKey(factoryType))
  470. {
  471. factory = ObjectCreator.CreateAs<IFactory>(factoryType);
  472. if (factory == null)
  473. {
  474. throw new InvalidFactoryException(String.Format(Resource.Factory_Invalid, factoryType));
  475. }
  476. //+
  477. FactoryData factoryData = FactoryData.Create(factoryType, parameterArray, parameterMap);
  478. factoryData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  479. if (factory is HandlerFactory)
  480. {
  481. data.HandlerFactoryDataList.Add(factoryData);
  482. RouteCache.HandlerFactoryCache.Add(factoryType, factory);
  483. }
  484. else if (factory is ProcessorFactory)
  485. {
  486. data.ProcessorFactoryDataList.Add(factoryData);
  487. RouteCache.ProcessorFactoryCache.Add(factoryType, factory);
  488. }
  489. }
  490. }
  491. finally
  492. {
  493. readerWriterLockSlim.ExitWriteLock();
  494. }
  495. }
  496. }
  497. catch (Exception ex)
  498. {
  499. if (WebProcessingReportController.Reporter.Initialized)
  500. {
  501. var map = new Map();
  502. map.Add("Section", "Factory");
  503. map.Add("Type", factoryType);
  504. map.Add("Message", ex.Message);
  505. map.Add("Exception Type", ex.GetType().FullName);
  506. //+
  507. WebProcessingReportController.Reporter.AddMap(map);
  508. }
  509. }
  510. finally
  511. {
  512. readerWriterLockSlim.ExitUpgradeableReadLock();
  513. }
  514. }
  515. //- ~LoadProcessorData -//
  516. internal static void LoadProcessorData(WebDomainData data, ProcessorCollection collection)
  517. {
  518. var readerWriterLockSlim = new ReaderWriterLockSlim();
  519. List<ProcessorElement> elementList = collection.ToList();
  520. foreach (ProcessorElement processor in elementList)
  521. {
  522. if (!processor.Enabled)
  523. {
  524. continue;
  525. }
  526. LoadSingleProcessorData(data, processor.ProcessorType, processor.GetParameterArray(), String.Empty);
  527. }
  528. foreach (ProcessorData processor in data.ProcessorDataList)
  529. {
  530. LoadSingleProcessorData(data, processor.ProcessorType, processor.ParameterArray, processor.Source);
  531. }
  532. //+
  533. data.InitProcessorDataList.OriginalCount = data.InitProcessorDataList.Count;
  534. data.SelectionProcessorDataList.OriginalCount = data.SelectionProcessorDataList.Count;
  535. data.OverrideProcessorDataList.OriginalCount = data.OverrideProcessorDataList.Count;
  536. data.StateProcessorDataList.OriginalCount = data.StateProcessorDataList.Count;
  537. data.ErrorProcessorDataList.OriginalCount = data.ErrorProcessorDataList.Count;
  538. }
  539. private static void LoadSingleProcessorData(WebDomainData data, String processorType, Object[] parameterArray, String source)
  540. {
  541. ProcessEachSettingToken(parameterArray);
  542. //+
  543. var readerWriterLockSlim = new ReaderWriterLockSlim();
  544. try
  545. {
  546. readerWriterLockSlim.EnterUpgradeableReadLock();
  547. try
  548. {
  549. IProcessor processor = null;
  550. //+
  551. if (RouteCache.ProcessorCache.ContainsKey(processorType))
  552. {
  553. processor = RouteCache.ProcessorCache[processorType];
  554. }
  555. else
  556. {
  557. readerWriterLockSlim.EnterWriteLock();
  558. //+
  559. try
  560. {
  561. if (!RouteCache.ProcessorCache.ContainsKey(processorType))
  562. {
  563. processor = ProcessorActivator.Create<IProcessor>(processorType, RouteCache.ProcessorFactoryCache);
  564. if (processor == null)
  565. {
  566. throw new InvalidProcessorException(String.Format(Resource.Processor_Invalid, processorType));
  567. }
  568. //+
  569. RouteCache.ProcessorCache.Add(processorType, processor);
  570. }
  571. }
  572. finally
  573. {
  574. readerWriterLockSlim.ExitWriteLock();
  575. }
  576. }
  577. if (processor == null)
  578. {
  579. return;
  580. }
  581. ProcessorData processorData;
  582. if (processor is InitProcessor)
  583. {
  584. processorData = new ProcessorData
  585. {
  586. ProcessorType = processorType, ParameterArray = parameterArray
  587. };
  588. processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  589. data.InitProcessorDataList.Add(processorData);
  590. }
  591. else if (processor is SelectionProcessor)
  592. {
  593. processorData = new ProcessorData
  594. {
  595. ProcessorType = processorType, ParameterArray = parameterArray
  596. };
  597. processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  598. data.SelectionProcessorDataList.Add(processorData);
  599. }
  600. else if (processor is OverrideProcessor)
  601. {
  602. processorData = new ProcessorData
  603. {
  604. ProcessorType = processorType, ParameterArray = parameterArray
  605. };
  606. processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  607. data.OverrideProcessorDataList.Add(processorData);
  608. }
  609. else if (processor is StateProcessor)
  610. {
  611. processorData = new ProcessorData
  612. {
  613. ProcessorType = processorType, ParameterArray = parameterArray
  614. };
  615. processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  616. data.StateProcessorDataList.Add(processorData);
  617. }
  618. else if (processor is PostRenderProcessor)
  619. {
  620. processorData = new ProcessorData
  621. {
  622. ProcessorType = processorType, ParameterArray = parameterArray
  623. };
  624. processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  625. data.PostRenderProcessorDataList.Add(processorData);
  626. }
  627. else if (processor is ErrorProcessor)
  628. {
  629. processorData = new ErrorProcessorData
  630. {
  631. ProcessorType = processorType, ParameterArray = parameterArray
  632. };
  633. processorData.Source = String.IsNullOrEmpty(source) ? Info.System : source;
  634. var epd = ((ErrorProcessorData)processorData);
  635. epd.Init();
  636. data.ErrorProcessorDataList.Add(epd);
  637. }
  638. }
  639. finally
  640. {
  641. readerWriterLockSlim.ExitUpgradeableReadLock();
  642. }
  643. }
  644. catch (Exception ex)
  645. {
  646. if (WebProcessingReportController.Reporter.Initialized)
  647. {
  648. var map = new Map();
  649. map.Add("Section", "Processor");
  650. map.Add("Type", processorType);
  651. map.Add("Message", ex.Message);
  652. map.Add("Exception Type", ex.GetType().FullName);
  653. //+
  654. WebProcessingReportController.Reporter.AddMap(map);
  655. }
  656. }
  657. }
  658. //- $ProcessEachSettingToken -//
  659. private static void ProcessEachSettingToken(Object[] parameterArray)
  660. {
  661. if (parameterArray == null)
  662. {
  663. return;
  664. }
  665. for (Int32 i = 0; i < parameterArray.Length; i++)
  666. {
  667. var parameter = parameterArray[i] as String;
  668. if (parameter == null)
  669. {
  670. continue;
  671. }
  672. parameterArray[i] = ProcessSingleSettingToken(parameter);
  673. }
  674. }
  675. //- $ProcessSingleSettingToken -//
  676. private static string ProcessSingleSettingToken(String parameter)
  677. {
  678. if (parameter[0] == '{' && parameter[parameter.Length - 1] == '}')
  679. {
  680. parameter = parameter.Substring(1, parameter.Length - 2);
  681. if (parameter.StartsWith("AppSetting ", StringComparison.CurrentCultureIgnoreCase))
  682. {
  683. parameter = parameter.Substring(11, parameter.Length - 11);
  684. return ConfigAccessor.ApplicationSettings(parameter) ?? String.Empty;
  685. }
  686. else if (parameter.StartsWith("ConnectionString ", StringComparison.CurrentCultureIgnoreCase))
  687. {
  688. parameter = parameter.Substring(17, parameter.Length - 17);
  689. return ConfigAccessor.ConnectionString(parameter) ?? String.Empty;
  690. }
  691. }
  692. //+
  693. return parameter;
  694. }
  695. //- ~LoadEndpointData -//
  696. internal static void LoadEndpointData(WebDomainData data, EndpointCollection collection)
  697. {
  698. List<EndpointElement> elementList = collection.ToList();
  699. var matchTextList = new List<String>();
  700. var referenceKeyList = new List<String>();
  701. if (collection.Count(p => p.Text == "*") > 1)
  702. {
  703. throw new ConfigurationErrorsException(ResourceAccessor.GetString("WebDomain_DuplicateCatchAll"));
  704. }
  705. foreach (EndpointElement element in elementList)
  706. {
  707. if (element.Disabled)
  708. {
  709. continue;
  710. }
  711. String matchText = element.Text;
  712. Boolean requireSlash = element.RequireSlash;
  713. String withoutSlash = EndpointData.GetTextWithoutSlash(matchText);
  714. SelectorType matchType = element.Selector;
  715. String originalMatchText = matchText;
  716. EndpointData newElement = AdjustMatchType(element.Text);
  717. if (newElement != null)
  718. {
  719. matchText = newElement.Text;
  720. matchType = newElement.Selector;
  721. }
  722. matchTextList.Add(matchText);
  723. if (element.Text == "*")
  724. {
  725. data.CatchAllEndpoint = new EndpointData
  726. {
  727. AccessRuleGroup = element.AccessRuleGroup,
  728. OriginalMatchText = originalMatchText,
  729. Text = matchText,
  730. TextWithoutSlash = withoutSlash,
  731. Selector = matchType,
  732. Type = element.Type,
  733. ParameterValue = element.Parameter,
  734. ParameterMap = element.GetParameterMap(),
  735. Source = Info.System
  736. };
  737. }
  738. else
  739. {
  740. var endpointData = new EndpointData
  741. {
  742. AccessRuleGroup = element.AccessRuleGroup,
  743. OriginalMatchText = originalMatchText,
  744. Text = matchText,
  745. TextWithoutSlash = withoutSlash,
  746. Selector = matchType,
  747. Type = element.Type,
  748. RequireSlash = element.RequireSlash,
  749. ParameterValue = element.Parameter,
  750. ParameterMap = element.GetParameterMap(),
  751. Source = Info.System
  752. };
  753. endpointData.SubEndpointDataList = new EndpointDataList();
  754. foreach (EndpointElement subElement in element.SubEndpoints)
  755. {
  756. String subWithoutSlash = EndpointData.GetTextWithoutSlash(matchText);
  757. endpointData.SubEndpointDataList.Add(new EndpointData
  758. {
  759. Text = subElement.Text,
  760. TextWithoutSlash = subWithoutSlash,
  761. Selector = subElement.Selector,
  762. Type = subElement.Type,
  763. ParameterValue = subElement.Parameter,
  764. ParameterMap = subElement.GetParameterMap(),
  765. Source = Info.System
  766. });
  767. }
  768. data.EndpointDataList.Add(endpointData);
  769. }
  770. }
  771. EndpointDataList handlerList = data.EndpointDataList.Clone();
  772. data.EndpointDataList = new EndpointDataList();
  773. handlerList.Where(p => p.Selector == SelectorType.PathEquals).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  774. handlerList.Where(p => p.Selector == SelectorType.EndsWith).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  775. handlerList.Where(p => p.Selector == SelectorType.WebDomainPathStartsWith).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  776. handlerList.Where(p => p.Selector == SelectorType.WebDomainPathEquals).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  777. handlerList.Where(p => p.Selector == SelectorType.PathStartsWith).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  778. handlerList.Where(p => p.Selector == SelectorType.StartsWith).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  779. handlerList.Where(p => p.Selector == SelectorType.PathContains).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  780. handlerList.Where(p => p.Selector == SelectorType.Contains).OrderByDescending(p => p.Text.Length).ToList().ForEach(p => data.EndpointDataList.Add(p));
  781. //+
  782. data.EndpointDataList.OriginalCount = data.EndpointDataList.Count;
  783. }
  784. //- ~LoadSequenceData -//
  785. internal static void LoadSequenceData(SequenceDataList data, SequenceCollection collection)
  786. {
  787. List<SequenceElement> elementList = collection.ToList();
  788. foreach (SequenceElement element in elementList)
  789. {
  790. if (data.Any(p => p.Name == element.Name))
  791. {
  792. throw new ConfigurationErrorsException(String.Format(CultureInfo.CurrentCulture, Resource.Sequence_DuplicateNameInConfig, element.Name));
  793. }
  794. var sequenceData = new SequenceData
  795. {
  796. Name = element.Name
  797. };
  798. sequenceData.ViewList = new ViewDataList();
  799. data.Add(sequenceData);
  800. foreach (ViewElement viewElement in element.Views)
  801. {
  802. var viewData = new ViewData
  803. {
  804. Name = viewElement.Name,
  805. ViewUsed = viewElement.ViewUsed
  806. };
  807. sequenceData.ViewList.Add(viewData);
  808. }
  809. sequenceData.VersionList = new VersionDataList();
  810. sequenceData.VersionList.ExplicitVersion = element.ExplicitVersion;
  811. foreach (VersionElement versionElement in element.Versions)
  812. {
  813. sequenceData.VersionList.Add(new VersionData
  814. {
  815. Name = versionElement.Name,
  816. Weight = versionElement.Weight
  817. });
  818. }
  819. }
  820. }
  821. //- ~GetParameterData -//
  822. internal static ParameterDataList GetWebDomainParameterData(ParameterCollection collection)
  823. {
  824. List<Configuration.ParameterElement> elementList = collection.ToList();
  825. var dataList = new ParameterDataList();
  826. foreach (Configuration.ParameterElement element in elementList)
  827. {
  828. //+ parameter
  829. String value = ProcessSingleSettingToken(element.Value);
  830. dataList.Add(new ParameterData
  831. {
  832. Category = element.Category,
  833. Name = element.Name,
  834. Value = value
  835. });
  836. }
  837. //+
  838. return dataList;
  839. }
  840. //- ~GetParameterData -//
  841. internal static ParameterDataList GetComponentParameterData(ComponentParameterCollection collection)
  842. {
  843. List<ParameterElement> elementList = collection.ToList();
  844. var dataList = new ParameterDataList();
  845. foreach (ParameterElement element in elementList)
  846. {
  847. //+ parameter
  848. String value = ProcessSingleSettingToken(element.Value);
  849. dataList.Add(new ParameterData
  850. {
  851. Name = element.Name,
  852. Value = value
  853. });
  854. }
  855. //+
  856. return dataList;
  857. }
  858. //- ~CopyWebDomain -//
  859. internal static WebDomainData CopyWebDomain(String webDomainName, List<WebDomainData> dataList)
  860. {
  861. WebDomainData data = dataList.SingleOrDefault(p => p.Name.Equals(webDomainName, StringComparison.InvariantCultureIgnoreCase));
  862. if (data == null)
  863. {
  864. return null;
  865. }
  866. if (data.IsSealed)
  867. {
  868. throw new InvalidOperationException(String.Format(Resource.WebDomain_CannotInheritFromSealed, data.Name));
  869. }
  870. data.IsBasedOn = true;
  871. //+
  872. return data.Clone();
  873. }
  874. //- ~AdjustMatchType -//
  875. internal static EndpointData AdjustMatchType(String matchText)
  876. {
  877. EndpointData element = null;
  878. if (matchText.StartsWith("wdp^", StringComparison.OrdinalIgnoreCase) && matchText.EndsWith("$", StringComparison.OrdinalIgnoreCase))
  879. {
  880. element = new EndpointData();
  881. element.Selector = SelectorType.WebDomainPathEquals;
  882. element.Text = matchText.Substring(3, matchText.Length - 4);
  883. }
  884. if (matchText.StartsWith("p^", StringComparison.OrdinalIgnoreCase) && matchText.EndsWith("$", StringComparison.OrdinalIgnoreCase))
  885. {
  886. element = new EndpointData();
  887. element.Selector = SelectorType.PathEquals;
  888. element.Text = matchText.Substring(2, matchText.Length - 3);
  889. }
  890. if (matchText.StartsWith("^", StringComparison.OrdinalIgnoreCase) && matchText.EndsWith("$", StringComparison.OrdinalIgnoreCase))
  891. {
  892. element = new EndpointData();
  893. element.Selector = SelectorType.Equals;
  894. element.Text = matchText.Substring(1, matchText.Length - 2);
  895. }
  896. if (matchText.StartsWith("wdp^", StringComparison.OrdinalIgnoreCase))
  897. {
  898. element = new EndpointData();
  899. element.Selector = SelectorType.WebDomainPathStartsWith;
  900. element.Text = matchText.Substring(4, matchText.Length - 4);
  901. }
  902. if (matchText.StartsWith("p^", StringComparison.OrdinalIgnoreCase))
  903. {
  904. element = new EndpointData();
  905. element.Selector = SelectorType.PathStartsWith;
  906. element.Text = matchText.Substring(2, matchText.Length - 2);
  907. }
  908. if (matchText.EndsWith("$", StringComparison.OrdinalIgnoreCase))
  909. {
  910. element = new EndpointData();
  911. element.Selector = SelectorType.EndsWith;
  912. element.Text = matchText.Substring(0, matchText.Length - 1);
  913. }
  914. if (matchText.StartsWith("^", StringComparison.OrdinalIgnoreCase))
  915. {
  916. element = new EndpointData();
  917. element.Selector = SelectorType.StartsWith;
  918. element.Text = matchText.Substring(1, matchText.Length - 1);
  919. }
  920. //+
  921. return element;
  922. }
  923. #region Nested type: Info
  924. internal class Info
  925. {
  926. public const String System = "System";
  927. public const String Root = "root";
  928. }
  929. #endregion
  930. }
  931. }