PageRenderTime 38ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/Implementation/TokenManager.cs

http://orchardtoken.codeplex.com
C# | 304 lines | 263 code | 41 blank | 0 comment | 20 complexity | 5b24a33b15852bfef7f9ace4d8aaf37f MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using Orchard.Localization;
  6. namespace Orchard.Tokens.Implementation
  7. {
  8. public class TokenManager : ITokenManager
  9. {
  10. private readonly IEnumerable<ITokenProvider> _providers;
  11. public TokenManager(IEnumerable<ITokenProvider> providers)
  12. {
  13. _providers = providers;
  14. }
  15. public IEnumerable<TokenTypeDescriptor> Describe(IEnumerable<string> targets)
  16. {
  17. var context = new DescribeContextImpl();
  18. foreach (var provider in _providers)
  19. {
  20. provider.Describe(context);
  21. }
  22. return context.Describe();
  23. }
  24. public IDictionary<string, object> Evaluate(string target, IDictionary<string, string> tokens, IDictionary<string, object> data)
  25. {
  26. var context = new EvaluateContextImpl(target, tokens, data, this);
  27. foreach (var provider in _providers)
  28. {
  29. provider.Evaluate(context);
  30. }
  31. return context.Produce();
  32. }
  33. private class EvaluateContextImpl : EvaluateContext
  34. {
  35. private readonly string _target;
  36. private readonly IDictionary<string, string> _tokens;
  37. private readonly IDictionary<string, object> _data;
  38. private readonly ITokenManager _manager;
  39. private readonly IDictionary<string, object> _values = new Dictionary<string, object>();
  40. public EvaluateContextImpl(string target, IDictionary<string, string> tokens, IDictionary<string, object> data, ITokenManager manager)
  41. {
  42. _target = target;
  43. _tokens = tokens;
  44. _data = data;
  45. _manager = manager;
  46. }
  47. public IDictionary<string, object> Produce()
  48. {
  49. return _values;
  50. }
  51. public override string Target
  52. {
  53. get { return _target; }
  54. }
  55. public override IDictionary<string, string> Tokens
  56. {
  57. get { return _tokens; }
  58. }
  59. public override IDictionary<string, object> Data
  60. {
  61. get { return _data; }
  62. }
  63. public override IDictionary<string, object> Values
  64. {
  65. get { return _values; }
  66. }
  67. public override EvaluateFor<TData> For<TData>(string target)
  68. {
  69. if (_data != null && string.Equals(target, _target, StringComparison.InvariantCulture))
  70. {
  71. object value;
  72. if (_data.TryGetValue(target, out value))
  73. {
  74. return new EvaluateForImpl<TData>(this, (TData)value);
  75. }
  76. }
  77. return new EvaluateForSilent<TData>();
  78. }
  79. public override EvaluateFor<TData> For<TData>(string target, TData defaultData)
  80. {
  81. return For(target, () => defaultData);
  82. }
  83. public override EvaluateFor<TData> For<TData>(string target, Func<TData> defaultData)
  84. {
  85. if (string.Equals(target, _target, StringComparison.InvariantCulture))
  86. {
  87. var data = default(TData);
  88. object value;
  89. if (_data != null && _data.TryGetValue(target, out value))
  90. {
  91. data = (TData)value;
  92. }
  93. else if (defaultData != null)
  94. {
  95. data = defaultData();
  96. }
  97. return new EvaluateForImpl<TData>(this, data);
  98. }
  99. return new EvaluateForSilent<TData>();
  100. }
  101. private class EvaluateForImpl<TData> : EvaluateFor<TData>
  102. {
  103. private readonly EvaluateContextImpl _context;
  104. private readonly TData _data;
  105. public EvaluateForImpl(EvaluateContextImpl context, TData data)
  106. {
  107. _context = context;
  108. _data = data;
  109. }
  110. public override TData Data
  111. {
  112. get { return _data; }
  113. }
  114. public override EvaluateFor<TData> Token(string token, Func<TData, object> tokenValue)
  115. {
  116. string originalToken;
  117. if (_context.Tokens.TryGetValue(token, out originalToken))
  118. {
  119. try
  120. {
  121. _context.Values[originalToken] = tokenValue(_data);
  122. }
  123. catch (NullReferenceException)
  124. {
  125. _context.Values[originalToken] = null;
  126. }
  127. }
  128. return this;
  129. }
  130. public override EvaluateFor<TData> Token(Func<string, TData, object> tokenValue)
  131. {
  132. return Token(null, tokenValue);
  133. }
  134. public override EvaluateFor<TData> Token(Func<string,string> filter, Func<string, TData, object> tokenValue)
  135. {
  136. foreach (var token in _context.Tokens)
  137. {
  138. var tokenName = token.Key;
  139. if (filter != null)
  140. {
  141. tokenName = filter(token.Key);
  142. if (tokenName == null)
  143. continue;
  144. }
  145. var value = tokenValue(tokenName, _data);
  146. if (value != null)
  147. {
  148. _context.Values[token.Value] = value;
  149. }
  150. }
  151. return this;
  152. }
  153. public override EvaluateFor<TData> Chain(string token, string chainTarget, Func<TData, object> chainValue)
  154. {
  155. var subTokens = _context.Tokens
  156. .Where(kv => kv.Key.StartsWith(token + "."))
  157. .ToDictionary(kv => kv.Key.Substring(token.Length + 1), kv => kv.Value);
  158. if (!subTokens.Any())
  159. {
  160. return this;
  161. }
  162. var subValues = _context._manager.Evaluate(chainTarget, subTokens, new Dictionary<string, object> { { chainTarget, chainValue(_data) } });
  163. foreach (var subValue in subValues)
  164. {
  165. _context.Values[subValue.Key] = subValue.Value;
  166. }
  167. return this;
  168. }
  169. }
  170. private class EvaluateForSilent<TData> : EvaluateFor<TData>
  171. {
  172. public override TData Data
  173. {
  174. get { return default(TData); }
  175. }
  176. public override EvaluateFor<TData> Token(string token, Func<TData, object> tokenValue)
  177. {
  178. return this;
  179. }
  180. public override EvaluateFor<TData> Token(Func<string, TData, object> tokenValue)
  181. {
  182. return this;
  183. }
  184. public override EvaluateFor<TData> Token(Func<string, string> filter, Func<string, TData, object> tokenValue)
  185. {
  186. return this;
  187. }
  188. public override EvaluateFor<TData> Chain(string token, string chainTarget, Func<TData, object> chainValue)
  189. {
  190. return this;
  191. }
  192. }
  193. }
  194. private class DescribeContextImpl : DescribeContext
  195. {
  196. private readonly Dictionary<string, DescribeFor> _describes = new Dictionary<string, DescribeFor>();
  197. public override IEnumerable<TokenTypeDescriptor> Describe()
  198. {
  199. return _describes.Select(kp => new TokenTypeDescriptor
  200. {
  201. Target = kp.Key,
  202. Name = kp.Value.Name,
  203. Description = kp.Value.Description,
  204. Tokens = kp.Value.Tokens
  205. });
  206. }
  207. public override DescribeFor For(string target)
  208. {
  209. return For(target, null, null);
  210. }
  211. public override DescribeFor For(string target, LocalizedString name, LocalizedString description)
  212. {
  213. DescribeFor describeFor;
  214. if (!_describes.TryGetValue(target, out describeFor))
  215. {
  216. describeFor = new DescribeForImpl(target, name, description);
  217. _describes[target] = describeFor;
  218. }
  219. return describeFor;
  220. }
  221. }
  222. private class DescribeForImpl : DescribeFor
  223. {
  224. private readonly LocalizedString _name;
  225. private readonly LocalizedString _description;
  226. private readonly string _target;
  227. private readonly List<TokenDescriptor> _tokens = new List<TokenDescriptor>();
  228. public DescribeForImpl(string target, LocalizedString name, LocalizedString description)
  229. {
  230. _target = target;
  231. _name = name;
  232. _description = description;
  233. }
  234. public override LocalizedString Name
  235. {
  236. get
  237. {
  238. return _name;
  239. }
  240. }
  241. public override LocalizedString Description
  242. {
  243. get
  244. {
  245. return _description;
  246. }
  247. }
  248. public override IEnumerable<TokenDescriptor> Tokens
  249. {
  250. get { return _tokens; }
  251. }
  252. public override DescribeFor Token(string token, LocalizedString name, LocalizedString description)
  253. {
  254. return Token(token, name, description, null);
  255. }
  256. public override DescribeFor Token(string token, LocalizedString name, LocalizedString description, string chainTarget)
  257. {
  258. _tokens.Add(new TokenDescriptor { Token = token, Name = name, Description = description, Target = _target, ChainTarget = chainTarget });
  259. return this;
  260. }
  261. }
  262. }
  263. }