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