PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/referencesource/System.Activities/System/Activities/Hosting/SymbolResolver.cs

https://github.com/pruiz/mono
C# | 424 lines | 340 code | 68 blank | 16 comment | 32 complexity | bb6b29e8c47fcf60692067af2e913267 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.Activities.Hosting
  5. {
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Diagnostics.CodeAnalysis;
  9. using System.Runtime;
  10. [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldHaveCorrectSuffix,
  11. Justification = "Approved name")]
  12. public sealed class SymbolResolver : IDictionary<string, object>
  13. {
  14. Dictionary<string, ExternalLocationReference> symbols;
  15. public SymbolResolver()
  16. {
  17. this.symbols = new Dictionary<string, ExternalLocationReference>();
  18. }
  19. public int Count
  20. {
  21. get { return this.symbols.Count; }
  22. }
  23. public bool IsReadOnly
  24. {
  25. get { return false; }
  26. }
  27. public ICollection<string> Keys
  28. {
  29. get { return this.symbols.Keys; }
  30. }
  31. public ICollection<object> Values
  32. {
  33. get
  34. {
  35. List<object> values = new List<object>(this.symbols.Count);
  36. foreach (ExternalLocationReference reference in this.symbols.Values)
  37. {
  38. values.Add(reference.Value);
  39. }
  40. return values;
  41. }
  42. }
  43. public object this[string key]
  44. {
  45. get
  46. {
  47. // We don't need to do any existence checks since we want the dictionary exception to bubble up
  48. return this.symbols[key].Value;
  49. }
  50. set
  51. {
  52. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  53. this.symbols[key] = CreateReference(key, value);
  54. }
  55. }
  56. public void Add(string key, object value)
  57. {
  58. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  59. this.symbols.Add(key, CreateReference(key, value));
  60. }
  61. public void Add(string key, Type type)
  62. {
  63. if (type == null)
  64. {
  65. throw FxTrace.Exception.ArgumentNull("type");
  66. }
  67. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  68. this.symbols.Add(key, new ExternalLocationReference(key, type, TypeHelper.GetDefaultValueForType(type)));
  69. }
  70. public void Add(string key, object value, Type type)
  71. {
  72. if (type == null)
  73. {
  74. throw FxTrace.Exception.ArgumentNull("type");
  75. }
  76. if (!TypeHelper.AreTypesCompatible(value, type))
  77. {
  78. throw FxTrace.Exception.Argument("value", SR.ValueMustBeAssignableToType);
  79. }
  80. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  81. this.symbols.Add(key, new ExternalLocationReference(key, type, value));
  82. }
  83. ExternalLocationReference CreateReference(string name, object value)
  84. {
  85. Type valueType = TypeHelper.ObjectType;
  86. if (value != null)
  87. {
  88. valueType = value.GetType();
  89. }
  90. return new ExternalLocationReference(name, valueType, value);
  91. }
  92. public void Add(KeyValuePair<string, object> item)
  93. {
  94. Add(item.Key, item.Value);
  95. }
  96. public void Clear()
  97. {
  98. this.symbols.Clear();
  99. }
  100. public bool Contains(KeyValuePair<string, object> item)
  101. {
  102. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  103. ExternalLocationReference reference;
  104. if (this.symbols.TryGetValue(item.Key, out reference))
  105. {
  106. return item.Value == reference.Value;
  107. }
  108. return false;
  109. }
  110. public bool ContainsKey(string key)
  111. {
  112. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  113. return this.symbols.ContainsKey(key);
  114. }
  115. public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
  116. {
  117. if (array == null)
  118. {
  119. throw FxTrace.Exception.ArgumentNull("array");
  120. }
  121. if (arrayIndex < 0)
  122. {
  123. throw FxTrace.Exception.ArgumentOutOfRange("arrayIndex", arrayIndex, SR.CopyToIndexOutOfRange);
  124. }
  125. if (array.Rank > 1)
  126. {
  127. throw FxTrace.Exception.Argument("array", SR.CopyToRankMustBeOne);
  128. }
  129. if (this.symbols.Count > array.Length - arrayIndex)
  130. {
  131. throw FxTrace.Exception.Argument("array", SR.CopyToNotEnoughSpaceInArray);
  132. }
  133. foreach (KeyValuePair<string, ExternalLocationReference> pair in this.symbols)
  134. {
  135. Fx.Assert(arrayIndex < array.Length, "We must have room since we validated it.");
  136. array[arrayIndex] = new KeyValuePair<string, object>(pair.Key, pair.Value.Value);
  137. arrayIndex++;
  138. }
  139. }
  140. public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
  141. {
  142. foreach (KeyValuePair<string, ExternalLocationReference> pair in this.symbols)
  143. {
  144. yield return new KeyValuePair<string, object>(pair.Key, pair.Value.Value);
  145. }
  146. }
  147. internal IEnumerable<KeyValuePair<string, LocationReference>> GetLocationReferenceEnumerator()
  148. {
  149. foreach (KeyValuePair<string, ExternalLocationReference> pair in this.symbols)
  150. {
  151. yield return new KeyValuePair<string, LocationReference>(pair.Key, pair.Value);
  152. }
  153. }
  154. IEnumerator IEnumerable.GetEnumerator()
  155. {
  156. return GetEnumerator();
  157. }
  158. public bool Remove(string key)
  159. {
  160. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  161. return this.symbols.Remove(key);
  162. }
  163. public bool Remove(KeyValuePair<string, object> item)
  164. {
  165. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  166. ExternalLocationReference reference;
  167. if (this.symbols.TryGetValue(item.Key, out reference))
  168. {
  169. if (reference.Value == item.Value)
  170. {
  171. this.symbols.Remove(item.Key);
  172. return true;
  173. }
  174. }
  175. return false;
  176. }
  177. public bool TryGetValue(string key, out object value)
  178. {
  179. // We don't need to check key for null since we want the exception to bubble up from the inner dictionary
  180. ExternalLocationReference reference;
  181. if (this.symbols.TryGetValue(key, out reference))
  182. {
  183. value = reference.Value;
  184. return true;
  185. }
  186. value = null;
  187. return false;
  188. }
  189. internal bool TryGetLocationReference(string name, out LocationReference result)
  190. {
  191. ExternalLocationReference reference;
  192. if (this.symbols.TryGetValue(name, out reference))
  193. {
  194. result = reference;
  195. return true;
  196. }
  197. result = null;
  198. return false;
  199. }
  200. internal bool IsVisible(LocationReference locationReference)
  201. {
  202. // We only check for null since string.Empty is
  203. // actually allowed.
  204. if (locationReference.Name == null)
  205. {
  206. return false;
  207. }
  208. else
  209. {
  210. ExternalLocationReference externalLocationReference;
  211. if (this.symbols.TryGetValue(locationReference.Name, out externalLocationReference))
  212. {
  213. if (externalLocationReference.Type == locationReference.Type)
  214. {
  215. return true;
  216. }
  217. }
  218. }
  219. return false;
  220. }
  221. Location GetLocation(string name, Type type)
  222. {
  223. ExternalLocationReference reference;
  224. if (this.symbols.TryGetValue(name, out reference))
  225. {
  226. if (reference.Type == type)
  227. {
  228. // We're the same reference
  229. return reference.Location;
  230. }
  231. }
  232. throw FxTrace.Exception.AsError(new InvalidOperationException(SR.SymbolResolverDoesNotHaveSymbol(name, type)));
  233. }
  234. public LocationReferenceEnvironment AsLocationReferenceEnvironment()
  235. {
  236. return new SymbolResolverLocationReferenceEnvironment(this);
  237. }
  238. class SymbolResolverLocationReferenceEnvironment : LocationReferenceEnvironment
  239. {
  240. SymbolResolver symbolResolver;
  241. public SymbolResolverLocationReferenceEnvironment(SymbolResolver symbolResolver)
  242. {
  243. this.symbolResolver = symbolResolver;
  244. }
  245. public override Activity Root
  246. {
  247. get
  248. {
  249. return null;
  250. }
  251. }
  252. public override bool IsVisible(LocationReference locationReference)
  253. {
  254. if (locationReference == null)
  255. {
  256. throw FxTrace.Exception.ArgumentNull("locationReference");
  257. }
  258. return this.symbolResolver.IsVisible(locationReference);
  259. }
  260. public override bool TryGetLocationReference(string name, out LocationReference result)
  261. {
  262. if (string.IsNullOrEmpty(name))
  263. {
  264. throw FxTrace.Exception.ArgumentNullOrEmpty("name");
  265. }
  266. return this.symbolResolver.TryGetLocationReference(name, out result);
  267. }
  268. public override IEnumerable<LocationReference> GetLocationReferences()
  269. {
  270. List<LocationReference> list = new List<LocationReference>();
  271. foreach (ExternalLocationReference item in this.symbolResolver.symbols.Values)
  272. {
  273. list.Add(item);
  274. }
  275. return list;
  276. }
  277. }
  278. class ExternalLocationReference : LocationReference
  279. {
  280. ExternalLocation location;
  281. string name;
  282. Type type;
  283. public ExternalLocationReference(string name, Type type, object value)
  284. {
  285. this.name = name;
  286. this.type = type;
  287. this.location = new ExternalLocation(this.type, value);
  288. }
  289. public object Value
  290. {
  291. get
  292. {
  293. return this.location.Value;
  294. }
  295. }
  296. public Location Location
  297. {
  298. get
  299. {
  300. return this.location;
  301. }
  302. }
  303. protected override string NameCore
  304. {
  305. get
  306. {
  307. return this.name;
  308. }
  309. }
  310. protected override Type TypeCore
  311. {
  312. get
  313. {
  314. return this.type;
  315. }
  316. }
  317. public override Location GetLocation(ActivityContext context)
  318. {
  319. SymbolResolver resolver = context.GetExtension<SymbolResolver>();
  320. if (resolver == null)
  321. {
  322. throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CanNotFindSymbolResolverInWorkflowInstanceExtensions));
  323. }
  324. return resolver.GetLocation(this.Name, this.Type);
  325. }
  326. class ExternalLocation : Location
  327. {
  328. Type type;
  329. object value;
  330. public ExternalLocation(Type type, object value)
  331. {
  332. this.type = type;
  333. this.value = value;
  334. }
  335. public override Type LocationType
  336. {
  337. get
  338. {
  339. return this.type;
  340. }
  341. }
  342. protected override object ValueCore
  343. {
  344. get
  345. {
  346. return this.value;
  347. }
  348. set
  349. {
  350. throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ExternalLocationsGetOnly));
  351. }
  352. }
  353. }
  354. }
  355. }
  356. }