Merge pull request #347 from JamesB7/master
[mono.git] / mcs / class / System.Data / System.Data.Common / DataColumnMappingCollection.cs
1 //
2 // System.Data.Common.DataColumnMappingCollection
3 //
4 // Authors:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Tim Coleman (tim@timcoleman.com)
7 //
8 // (C) Ximian, Inc
9 // Copyright (C) Tim Coleman, 2002-2003
10 //
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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
35 using System;
36 using System.Collections;
37 using System.ComponentModel;
38 using System.Data;
39
40 namespace System.Data.Common
41 {
42         public sealed class DataColumnMappingCollection : MarshalByRefObject, IColumnMappingCollection , IList, ICollection, IEnumerable
43         {
44                 #region Fields
45
46                 readonly ArrayList list;
47                 readonly Hashtable sourceColumns;
48                 readonly Hashtable dataSetColumns;
49
50                 #endregion // Fields
51
52                 #region Constructors 
53
54                 public DataColumnMappingCollection ()
55                 {
56                         list = new ArrayList ();
57                         sourceColumns = new Hashtable ();
58                         dataSetColumns = new Hashtable ();
59                 }
60
61                 #endregion // Constructors
62
63                 #region Properties
64
65                 [Browsable (false)]
66 #if !NET_2_0
67                 [DataSysDescription ("The number of items in the collection")]
68 #endif
69                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
70                 public int Count {
71                         get { return list.Count; }
72                 }
73
74                 [Browsable (false)]
75 #if !NET_2_0
76                 [DataSysDescription ("The specified DataColumnMapping object.")]
77 #endif
78                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
79                 public DataColumnMapping this [int index] {
80                         get { return (DataColumnMapping)(list[index]); }
81                         set { 
82                                 DataColumnMapping mapping = (DataColumnMapping)(list[index]);
83                                 sourceColumns[mapping] = value;
84                                 dataSetColumns[mapping] = value;
85                                 list[index] = value;
86                         }
87                 }
88
89                 [Browsable (false)]
90 #if !NET_2_0
91                 [DataSysDescription ("The specified DataColumnMapping object.")]
92 #endif
93                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
94                 public DataColumnMapping this [string sourceColumn] {
95                         get {
96                                 if (!Contains(sourceColumn))
97                                         throw new IndexOutOfRangeException("DataColumnMappingCollection doesn't contain DataColumnMapping with SourceColumn '" + sourceColumn + "'.");
98                                 return (DataColumnMapping) sourceColumns [sourceColumn];
99                         }
100                         set {
101                                 this [list.IndexOf (sourceColumns [sourceColumn])] = value;
102                         }
103                 }
104
105                 object ICollection.SyncRoot {
106                         get { return list.SyncRoot; }
107                 }
108
109                 bool ICollection.IsSynchronized {
110                         get { return list.IsSynchronized; }
111                 }
112
113                 object IColumnMappingCollection.this [string index] {
114                         get { return this [index]; }
115                         set {
116                                 if (!(value is DataColumnMapping))
117                                         throw new ArgumentException ();
118                                 this [index] = (DataColumnMapping) value;
119                         }
120                 }
121
122                 object IList.this [int index] {
123                         get { return this [index]; }
124                         set {
125                                 if (!(value is DataColumnMapping))
126                                         throw new ArgumentException ();
127                                 this [index] = (DataColumnMapping) value;
128                         }
129                 }
130
131                 bool IList.IsReadOnly {
132                         get { return false; }
133                 }
134
135                 bool IList.IsFixedSize {
136                         get { return false; }
137                 }
138                 
139                 #endregion // Properties
140
141                 #region Methods
142
143                 public int Add (object value)
144                 {
145                         if (!(value is DataColumnMapping))
146                                 throw new InvalidCastException ();
147
148                         list.Add (value);
149                         sourceColumns [((DataColumnMapping) value).SourceColumn] = value;
150                         dataSetColumns [((DataColumnMapping )value).DataSetColumn] = value;
151                         return list.IndexOf (value);
152                 }
153
154                 public DataColumnMapping Add (string sourceColumn, string dataSetColumn)
155                 {
156                         DataColumnMapping mapping = new DataColumnMapping (sourceColumn, dataSetColumn);
157                         Add (mapping);
158                         return mapping;
159                 }
160
161 #if NET_2_0
162                 public void AddRange (Array values)
163                 {
164                         for (int i = 0; i < values.Length; ++i)
165                                 Add (values.GetValue (i));
166                 }
167 #endif
168
169                 public void AddRange (DataColumnMapping[] values)
170                 {
171                         foreach (DataColumnMapping mapping in values)
172                                 Add (mapping);
173                 }
174
175                 public void Clear ()
176                 {
177                         list.Clear ();
178                 }
179
180                 public bool Contains (object value)
181                 {
182                         if (!(value is DataColumnMapping))
183                                 throw new InvalidCastException("Object is not of type DataColumnMapping");
184                         return (list.Contains (value));
185                 }
186
187                 public bool Contains (string value)
188                 {
189                         return (sourceColumns.Contains (value));
190                 }
191
192                 public void CopyTo (Array array, int index)
193                 {
194                         list.CopyTo (array,index);
195                 }
196
197 #if NET_2_0
198                 public void CopyTo (DataColumnMapping [] array, int index)
199                 {
200                         list.CopyTo (array, index);
201                 }
202 #endif
203
204                 public DataColumnMapping GetByDataSetColumn (string value)
205                 {
206                         // this should work case-insenstive.
207                         if (!(dataSetColumns [value] == null))
208                                 return (DataColumnMapping) (dataSetColumns [value]);
209                         else {
210                                 string lowcasevalue = value.ToLower ();
211                                 object [] keyarray = new object [dataSetColumns.Count];
212                                 dataSetColumns.Keys.CopyTo (keyarray, 0);
213                                 for (int i = 0; i < keyarray.Length; i++) {
214                                         string temp = (string) keyarray [i];
215                                         if (lowcasevalue.Equals (temp.ToLower ()))
216                                                 return (DataColumnMapping) (dataSetColumns [keyarray [i]]);
217                                 }
218                                 return null;
219                         }
220                 }
221
222                 [EditorBrowsable (EditorBrowsableState.Advanced)]
223                 public static DataColumnMapping GetColumnMappingBySchemaAction (DataColumnMappingCollection columnMappings, string sourceColumn, MissingMappingAction mappingAction)
224                 {
225                         if (columnMappings.Contains (sourceColumn))
226                                 return columnMappings[sourceColumn];
227                         if (mappingAction == MissingMappingAction.Ignore)
228                                 return null;
229                         if (mappingAction == MissingMappingAction.Error)
230                                 throw new InvalidOperationException (String.Format ("Missing SourceColumn mapping for '{0}'", sourceColumn));
231                         return new DataColumnMapping (sourceColumn, sourceColumn);
232                 }
233
234 #if NET_2_0
235                 [MonoTODO]
236                 [EditorBrowsable (EditorBrowsableState.Advanced)]
237                 public static DataColumn GetDataColumn (DataColumnMappingCollection columnMappings, string sourceColumn, Type dataType, DataTable dataTable, MissingMappingAction mappingAction, MissingSchemaAction schemaAction)
238                 {
239                         throw new NotImplementedException ();
240                 }
241 #endif
242
243                 public IEnumerator GetEnumerator ()
244                 {
245                         return list.GetEnumerator ();
246                 }
247
248                 IColumnMapping IColumnMappingCollection.Add (string sourceColumnName, string dataSetColumnName)
249                 {
250                         return Add (sourceColumnName, dataSetColumnName);
251                 }
252
253                 IColumnMapping IColumnMappingCollection.GetByDataSetColumn (string dataSetColumnName)
254                 {
255                         return GetByDataSetColumn (dataSetColumnName);
256                 }
257
258                 public int IndexOf (object value)
259                 {
260                         return list.IndexOf (value);
261                 }
262
263                 public int IndexOf (string sourceColumn)
264                 {
265                         return list.IndexOf (sourceColumns [sourceColumn]);
266                 }
267
268                 public int IndexOfDataSetColumn (string dataSetColumn)
269                 {
270                         // this should work case-insensitive
271                         if (!(dataSetColumns [dataSetColumn] == null))
272                                 return list.IndexOf (dataSetColumns [dataSetColumn]);
273                         else {
274                                 string lowcasevalue = dataSetColumn.ToLower ();
275                                 object [] keyarray = new object[dataSetColumns.Count];
276                                 dataSetColumns.Keys.CopyTo (keyarray,0);
277                                 for (int i = 0; i < keyarray.Length; i++) {
278                                         string temp = (string) keyarray [i];
279                                         if (lowcasevalue.Equals (temp.ToLower ()))
280                                                 return list.IndexOf (dataSetColumns [keyarray [i]]);
281                                 }
282                                 return -1;
283                         }
284                 }
285
286                 public void Insert (int index, object value)
287                 {
288                         list.Insert (index, value);
289                         sourceColumns [((DataColumnMapping) value).SourceColumn] = value;
290                         dataSetColumns [((DataColumnMapping) value).DataSetColumn] = value;
291                 }
292
293 #if NET_2_0
294                 public void Insert (int index, DataColumnMapping value)
295                 {
296                         list.Insert (index, value);
297                         sourceColumns [value.SourceColumn] = value;
298                         dataSetColumns [value.DataSetColumn] = value;
299                 }
300 #endif
301
302                 public void Remove (object value)
303                 {
304                         int index = list.IndexOf (value);
305                         sourceColumns.Remove (((DataColumnMapping) value).SourceColumn);
306                         dataSetColumns.Remove (((DataColumnMapping) value).DataSetColumn);
307                         if (index < 0 || index >=list.Count)
308                                 throw new ArgumentException("There is no such element in collection.");
309                         list.Remove (value);
310                 }
311
312 #if NET_2_0
313                 public void Remove (DataColumnMapping value)
314                 {
315                         int index = list.IndexOf (value);
316                         sourceColumns.Remove (value.SourceColumn);
317                         dataSetColumns.Remove (value.DataSetColumn);
318                         if ( index < 0 || index >=list.Count)
319                                 throw new ArgumentException("There is no such element in collection.");
320                         list.Remove (value);
321                 }
322 #endif
323
324                 public void RemoveAt (int index)
325                 {
326                         if (index < 0 || index >=list.Count)
327                                 throw new IndexOutOfRangeException("There is no element in collection.");
328                         Remove (list [index]);
329                 }
330
331                 public void RemoveAt (string sourceColumn)
332                 {
333                         RemoveAt (list.IndexOf (sourceColumns [sourceColumn]));
334                 }
335
336                 #endregion // Methods
337         }
338 }