PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.Web/System.Web.UI/StateManagedCollection.cs

https://bitbucket.org/foobar22/mono
C# | 370 lines | 276 code | 64 blank | 30 comment | 51 complexity | 723624f2472a8b06f0ee327a890493a3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0, Unlicense, Apache-2.0, LGPL-2.0
  1. //
  2. // System.Web.UI.StateManagedCollection
  3. //
  4. // Authors:
  5. // Ben Maurer (bmaurer@users.sourceforge.net)
  6. // Sebastien Pouliot <sebastien@ximian.com>
  7. // Marek Habersack (mhabersack@novell.com)
  8. //
  9. // (C) 2003 Ben Maurer
  10. // Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com)
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. using System.Collections;
  32. using System.Collections.Generic;
  33. namespace System.Web.UI {
  34. public abstract class StateManagedCollection : IList, IStateManager
  35. {
  36. ArrayList items = new ArrayList ();
  37. bool saveEverything = false;
  38. protected virtual object CreateKnownType (int index)
  39. {
  40. return null;
  41. }
  42. public void SetDirty ()
  43. {
  44. saveEverything = true;
  45. for (int i = 0; i < items.Count; i++)
  46. SetDirtyObject (items[i]);
  47. }
  48. protected abstract void SetDirtyObject (object o);
  49. protected virtual Type [] GetKnownTypes ()
  50. {
  51. return null;
  52. }
  53. #region OnXXX
  54. protected virtual void OnClear ()
  55. {
  56. }
  57. protected virtual void OnClearComplete ()
  58. {
  59. }
  60. protected virtual void OnInsert (int index, object value)
  61. {
  62. }
  63. protected virtual void OnInsertComplete (int index, object value)
  64. {
  65. }
  66. protected virtual void OnRemove (int index, object value)
  67. {
  68. }
  69. protected virtual void OnRemoveComplete (int index, object value)
  70. {
  71. }
  72. protected virtual void OnValidate (object value)
  73. {
  74. if (value == null)
  75. throw new ArgumentNullException ("value");
  76. }
  77. #endregion
  78. #region IStateManager
  79. void IStateManager.LoadViewState (object savedState)
  80. {
  81. if (savedState == null) {
  82. foreach (IStateManager i in items)
  83. i.LoadViewState (null);
  84. return;
  85. }
  86. Triplet state = savedState as Triplet;
  87. if (state == null)
  88. throw new InvalidOperationException ("Internal error.");
  89. List <int> indices = state.First as List <int>;
  90. List <object> states = state.Second as List <object>;
  91. List <object> types = state.Third as List <object>;
  92. IList list = this as IList;
  93. IStateManager item;
  94. object t;
  95. saveEverything = indices == null;
  96. if (saveEverything) {
  97. Clear ();
  98. for (int i = 0; i < states.Count; i++) {
  99. t = types [i];
  100. if (t is Type)
  101. item = (IStateManager) Activator.CreateInstance ((Type) t);
  102. else if (t is int)
  103. item = (IStateManager) CreateKnownType ((int) t);
  104. else
  105. continue;
  106. item.TrackViewState ();
  107. item.LoadViewState (states [i]);
  108. list.Add (item);
  109. }
  110. return;
  111. }
  112. int idx;
  113. for (int i = 0; i < indices.Count; i++) {
  114. idx = indices [i];
  115. if (idx < Count) {
  116. item = list [idx] as IStateManager;
  117. item.TrackViewState ();
  118. item.LoadViewState (states [i]);
  119. continue;
  120. }
  121. t = types [i];
  122. if (t is Type)
  123. item = (IStateManager) Activator.CreateInstance ((Type) t);
  124. else if (t is int)
  125. item = (IStateManager) CreateKnownType ((int) t);
  126. else
  127. continue;
  128. item.TrackViewState ();
  129. item.LoadViewState (states [i]);
  130. list.Add (item);
  131. }
  132. }
  133. void AddListItem <T> (ref List <T> list, T item)
  134. {
  135. if (list == null)
  136. list = new List <T> ();
  137. list.Add (item);
  138. }
  139. object IStateManager.SaveViewState ()
  140. {
  141. Type[] knownTypes = GetKnownTypes ();
  142. bool haveData = false, haveKnownTypes = knownTypes != null && knownTypes.Length > 0;
  143. int count = items.Count;
  144. IStateManager item;
  145. object itemState;
  146. Type type;
  147. int idx;
  148. List <int> indices = null;
  149. List <object> states = null;
  150. List <object> types = null;
  151. for (int i = 0; i < count; i++) {
  152. item = items [i] as IStateManager;
  153. if (item == null)
  154. continue;
  155. item.TrackViewState ();
  156. itemState = item.SaveViewState ();
  157. if (saveEverything || itemState != null) {
  158. haveData = true;
  159. type = item.GetType ();
  160. idx = haveKnownTypes ? Array.IndexOf (knownTypes, type) : -1;
  161. if (!saveEverything)
  162. AddListItem <int> (ref indices, i);
  163. AddListItem <object> (ref states, itemState);
  164. if (idx == -1)
  165. AddListItem <object> (ref types, type);
  166. else
  167. AddListItem <object> (ref types, idx);
  168. }
  169. }
  170. if (!haveData)
  171. return null;
  172. return new Triplet (indices, states, types);
  173. }
  174. void IStateManager.TrackViewState ()
  175. {
  176. isTrackingViewState = true;
  177. if (items != null && items.Count > 0) {
  178. IStateManager item;
  179. foreach (object o in items) {
  180. item = o as IStateManager;
  181. if (item == null)
  182. continue;
  183. item.TrackViewState ();
  184. }
  185. }
  186. }
  187. bool isTrackingViewState;
  188. bool IStateManager.IsTrackingViewState {
  189. get { return isTrackingViewState; }
  190. }
  191. #endregion
  192. #region ICollection, IList, IEnumerable
  193. public void Clear ()
  194. {
  195. this.OnClear ();
  196. items.Clear ();
  197. this.OnClearComplete ();
  198. if (isTrackingViewState)
  199. SetDirty ();
  200. }
  201. public IEnumerator GetEnumerator ()
  202. {
  203. return items.GetEnumerator ();
  204. }
  205. public void CopyTo (Array array, int index)
  206. {
  207. items.CopyTo (array, index);
  208. }
  209. IEnumerator IEnumerable.GetEnumerator ()
  210. {
  211. return GetEnumerator ();
  212. }
  213. int IList.Add (object value)
  214. {
  215. OnValidate(value);
  216. if (isTrackingViewState) {
  217. ((IStateManager) value).TrackViewState ();
  218. SetDirtyObject (value);
  219. }
  220. OnInsert (-1, value);
  221. items.Add (value);
  222. OnInsertComplete (-1, value);
  223. return Count - 1;
  224. }
  225. void IList.Insert (int index, object value)
  226. {
  227. OnValidate(value);
  228. if (isTrackingViewState) {
  229. ((IStateManager) value).TrackViewState ();
  230. SetDirty ();
  231. }
  232. OnInsert (index, value);
  233. items.Insert (index, value);
  234. OnInsertComplete(index, value);
  235. }
  236. void IList.Remove (object value)
  237. {
  238. if (value == null)
  239. return;
  240. OnValidate (value);
  241. IList list = (IList)this;
  242. int i = list.IndexOf (value);
  243. if (i >= 0)
  244. list.RemoveAt (i);
  245. }
  246. void IList.RemoveAt (int index)
  247. {
  248. object o = items [index];
  249. OnRemove (index, o);
  250. items.RemoveAt (index);
  251. OnRemoveComplete(index, o);
  252. if (isTrackingViewState)
  253. SetDirty ();
  254. }
  255. void IList.Clear ()
  256. {
  257. this.Clear ();
  258. }
  259. bool IList.Contains (object value)
  260. {
  261. if (value == null)
  262. return false;
  263. OnValidate (value);
  264. return items.Contains (value);
  265. }
  266. int IList.IndexOf (object value)
  267. {
  268. if (value == null)
  269. return -1;
  270. OnValidate (value);
  271. return items.IndexOf (value);
  272. }
  273. public int Count {
  274. get { return items.Count; }
  275. }
  276. int ICollection.Count {
  277. get { return items.Count; }
  278. }
  279. bool ICollection.IsSynchronized {
  280. get { return false; }
  281. }
  282. object ICollection.SyncRoot {
  283. get { return this; }
  284. }
  285. bool IList.IsFixedSize {
  286. get { return false; }
  287. }
  288. bool IList.IsReadOnly {
  289. get { return false; }
  290. }
  291. object IList.this [int index] {
  292. get { return items [index]; }
  293. set {
  294. if (index < 0 || index >= Count)
  295. throw new ArgumentOutOfRangeException ("index");
  296. OnValidate (value);
  297. if (isTrackingViewState) {
  298. ((IStateManager) value).TrackViewState ();
  299. SetDirty ();
  300. }
  301. items [index] = value;
  302. }
  303. }
  304. #endregion
  305. }
  306. }