Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System / System.ComponentModel / PropertyDescriptorCollection.cs
1 //
2 // System.ComponentModel.PropertyDescriptorCollection.cs
3 //
4 // Authors:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (C) Rodrigo Moya, 2002
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) 2003 Andreas Nahr
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34 using System.Collections;
35 namespace System.ComponentModel
36 {
37         /// <summary>
38         /// Represents a collection of PropertyDescriptor objects.
39         /// </summary>
40         public class PropertyDescriptorCollection : IList, ICollection, IEnumerable, IDictionary
41         {
42                 public static readonly PropertyDescriptorCollection Empty = new PropertyDescriptorCollection (null, true);
43                 private ArrayList properties;
44                 private bool readOnly;
45
46                 public PropertyDescriptorCollection (PropertyDescriptor[] properties)
47                 {
48                         this.properties = new ArrayList ();
49                         if (properties == null)
50                                 return;
51
52                         this.properties.AddRange (properties);
53                 }
54
55                 public PropertyDescriptorCollection (PropertyDescriptor[] properties, bool readOnly) : this (properties)
56                 {
57                         this.readOnly = readOnly;
58                 }
59                 
60                 private PropertyDescriptorCollection ()
61                 {
62                 }
63
64                 public int Add (PropertyDescriptor value)
65                 {
66                         if (readOnly) {
67                                 throw new NotSupportedException ();
68                         }
69                         properties.Add (value);
70                         return properties.Count - 1;
71                 }
72
73                 int IList.Add (object value)
74                 {
75                         return Add ((PropertyDescriptor) value);
76                 }
77
78                 void IDictionary.Add (object key, object value)
79                 {
80                         if ((value as PropertyDescriptor) == null) {
81                                 throw new ArgumentException ("value");
82                         }
83
84                         Add ((PropertyDescriptor) value);
85                 }
86
87                 public void Clear ()
88                 {
89                         if (readOnly) {
90                                 throw new NotSupportedException ();
91                         }
92                         properties.Clear ();
93                 }
94
95                 void IList.Clear ()
96                 {
97                         Clear ();
98                 }
99
100                 void IDictionary.Clear ()
101                 {
102                         Clear ();
103                 }
104
105                 public bool Contains (PropertyDescriptor value)
106                 {
107                         return properties.Contains (value);
108                 }
109
110
111                 bool IList.Contains (object value)
112                 {
113                         return Contains ((PropertyDescriptor) value);
114                 }
115
116                 bool IDictionary.Contains (object value)
117                 {
118                         return Contains ((PropertyDescriptor) value);
119                 }
120
121                 public void CopyTo (Array array, int index)
122                 {
123                         properties.CopyTo (array, index);
124                 }
125
126                 public virtual PropertyDescriptor Find (string name, bool ignoreCase)
127                 {
128                         if (name == null)
129                                 throw new ArgumentNullException ("name");
130
131                         for (int i = 0; i < properties.Count; ++i) {
132                                 PropertyDescriptor p = (PropertyDescriptor)properties [i];
133                                 if (ignoreCase) {
134                                         if (0 == String.Compare (name, p.Name, StringComparison.OrdinalIgnoreCase))
135                                                 return p;
136                                 }
137                                 else {
138                                         if (0 == String.Compare (name, p.Name, StringComparison.Ordinal))
139                                                 return p;
140                                 }
141                         }
142                         return null;
143                 }
144
145                 public virtual IEnumerator GetEnumerator ()
146                 {
147                         return properties.GetEnumerator ();
148                 }
149
150                 IEnumerator IEnumerable.GetEnumerator ()
151                 {
152                         return GetEnumerator ();
153                 }
154
155                 [MonoTODO]
156                 IDictionaryEnumerator IDictionary.GetEnumerator ()
157                 {
158                         throw new NotImplementedException ();
159                 }
160
161                 public int IndexOf (PropertyDescriptor value)
162                 {
163                         return properties.IndexOf (value);
164                 }
165
166                 int IList.IndexOf (object value)
167                 {
168                         return IndexOf ((PropertyDescriptor) value);
169                 }
170
171                 public void Insert (int index, PropertyDescriptor value)
172                 {
173                         if (readOnly) {
174                                 throw new NotSupportedException ();
175                         }
176                         properties.Insert (index, value);
177                 }
178
179                 void IList.Insert (int index, object value)
180                 {
181                         Insert (index, (PropertyDescriptor) value);
182                 }
183
184                 public void Remove (PropertyDescriptor value)
185                 {
186                         if (readOnly) {
187                                 throw new NotSupportedException ();
188                         }
189                         properties.Remove (value);
190                 }
191
192                 void IDictionary.Remove (object value)
193                 {
194                         Remove ((PropertyDescriptor) value);
195                 }
196
197                 void IList.Remove (object value)
198                 {
199                         Remove ((PropertyDescriptor) value);
200                 }
201                 public void RemoveAt (int index)
202                 {
203                         if (readOnly) {
204                                 throw new NotSupportedException ();
205                         }
206                         properties.RemoveAt (index);
207                 }
208
209                 void IList.RemoveAt (int index)
210                 {
211                         RemoveAt (index);
212                 }
213
214                 private PropertyDescriptorCollection CloneCollection ()
215                 {
216                         PropertyDescriptorCollection col = new PropertyDescriptorCollection ();
217                         col.properties = (ArrayList) properties.Clone ();
218                         return col;
219                 }
220                 
221                 public virtual PropertyDescriptorCollection Sort ()
222                 {
223                         PropertyDescriptorCollection col = CloneCollection ();
224                         col.InternalSort ((IComparer) null);
225                         return col;
226                 }
227
228                 public virtual PropertyDescriptorCollection Sort (IComparer comparer)
229                 {
230                         PropertyDescriptorCollection col = CloneCollection ();
231                         col.InternalSort (comparer);
232                         return col;
233                 }
234
235                 public virtual PropertyDescriptorCollection Sort (string[] order) 
236                 {
237                         PropertyDescriptorCollection col = CloneCollection ();
238                         col.InternalSort (order);
239                         return col;
240                 }
241
242                 public virtual PropertyDescriptorCollection Sort (string[] order, IComparer comparer) 
243                 {
244                         PropertyDescriptorCollection col = CloneCollection ();
245                         if (order != null) {
246                                 ArrayList sorted = col.ExtractItems (order);
247                                 col.InternalSort (comparer);
248                                 sorted.AddRange (col.properties);
249                                 col.properties = sorted;
250                         } else {
251                                 col.InternalSort (comparer);
252                         }
253                         return col;
254                 }
255
256                 protected void InternalSort (IComparer ic)
257                 {
258                         if (ic == null)
259                                 ic = MemberDescriptor.DefaultComparer;
260                         properties.Sort (ic);
261                 }
262
263                 protected void InternalSort (string [] order)
264                 {
265                         if (order != null) {
266                                 ArrayList sorted = ExtractItems (order);
267                                 InternalSort ((IComparer) null);
268                                 sorted.AddRange (properties);
269                                 properties = sorted;
270                         } else {
271                                 InternalSort ((IComparer) null);
272                         }
273                 }
274                 
275                 ArrayList ExtractItems (string[] names)
276                 {
277                         ArrayList sorted = new ArrayList (properties.Count);
278                         object[] ext = new object [names.Length];
279                         
280                         for (int n=0; n<properties.Count; n++)
281                         {
282                                 PropertyDescriptor ed = (PropertyDescriptor) properties[n];
283                                 int i = Array.IndexOf (names, ed.Name);
284                                 if (i != -1) {
285                                         ext[i] = ed;
286                                         properties.RemoveAt (n);
287                                         n--;
288                                 }
289                         }
290                         foreach (object ob in ext)
291                                 if (ob != null) sorted.Add (ob);
292                                 
293                         return sorted;
294                 }
295                 
296                 internal PropertyDescriptorCollection Filter (Attribute[] attributes)
297                 {
298                         ArrayList list = new ArrayList ();
299                         foreach (PropertyDescriptor pd in properties) {
300                                 if (pd.Attributes.Contains (attributes)) {
301                                         list.Add (pd);
302                                 }
303                         }
304                         PropertyDescriptor[] descriptors = new PropertyDescriptor[list.Count];
305                         list.CopyTo (descriptors);
306                         return new PropertyDescriptorCollection (descriptors, true);
307                 }
308
309                 bool IDictionary.IsFixedSize
310                 {
311                         get {return ((IList)this).IsFixedSize;}
312                 }
313                 bool IList.IsFixedSize
314                 {
315                         get 
316                         {
317                                 return readOnly;
318                         }
319                 }
320                 bool IDictionary.IsReadOnly
321                 {
322                         get {return ((IList)this).IsReadOnly;}
323                 }
324                 bool IList.IsReadOnly
325                 {
326                         get 
327                         {
328                                 return readOnly;
329                         }
330                 }
331
332                 bool ICollection.IsSynchronized
333                 {
334                         get {
335                                 return false;
336                         }
337                 }
338
339                 int ICollection.Count {
340                         get { return Count; }
341                 }
342
343                 public int Count
344                 {
345                         get {
346                                 return properties.Count;
347                         }
348                 }
349
350                 object ICollection.SyncRoot
351                 {
352                         get {
353                                 return null;
354                         }
355                 }
356
357                 ICollection IDictionary.Keys
358                 {
359                         get {
360                                 string [] keys = new string [properties.Count];
361                                 int i = 0;
362                                 foreach (PropertyDescriptor p in properties)
363                                         keys [i++] = p.Name;
364                                 return keys;
365                         }
366                 }
367
368                 ICollection IDictionary.Values
369                 {
370                         get {
371                                 return (ICollection) properties.Clone ();
372                         }
373                 }
374
375                 object IDictionary.this [object key]
376                 {
377                         get {
378                                 if (!(key is string))
379                                         return null;
380                                 return this [(string) key];
381                         }
382                         set {
383                                 if (readOnly) {
384                                         throw new NotSupportedException ();
385                                 }
386
387                                 if (!(key is string) || (value as PropertyDescriptor) == null)
388                                         throw new ArgumentException ();
389                                 int idx = properties.IndexOf (value);
390                                 if (idx == -1)
391                                         Add ((PropertyDescriptor) value);
392                                 else
393                                         properties [idx] = value;
394                         }
395                 }
396
397                 public virtual PropertyDescriptor this [string s]
398                 {
399                         get {
400                                 return Find (s, false);
401                         }
402                 }
403
404                 object IList.this [int index]
405                 {
406                         get {
407                                 return properties [index];
408                         }
409                         set {
410                                 if (readOnly) {
411                                         throw new NotSupportedException ();
412                                 }
413                                 properties [index] = value;
414                         }
415                 }
416
417                 public virtual PropertyDescriptor this [int index]
418                 {
419                         get {
420                                 return (PropertyDescriptor) properties [index];
421                         }
422                 }
423         }
424 }
425