New test.
[mono.git] / mcs / class / System.Data / Mainsoft.Data.Configuration.jvm / KeyMapperBase.cs
1 //
2 // System.Data.OleDb.OleDbConnection
3 //
4 // Authors:
5 //      Konstantin Triger <kostat@mainsoft.com>
6 //      Boris Kirzner <borisk@mainsoft.com>
7 //      
8 // (C) 2006 Mainsoft Corporation (http://www.mainsoft.com)
9 //
10
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
32 using System;
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.Text;
36 using System.Globalization;
37
38 namespace Mainsoft.Data.Configuration
39 {
40         public class ConnectionStringDictionary: IConnectionStringDictionary
41         {
42                 #region Fields
43
44                 private readonly IDictionary _dictionary;
45                 private readonly NameValueCollection _mapping;
46                 private readonly NameValueCollection _actualKeys;
47
48                 #endregion // Fields
49
50                 #region Constructors
51
52                 public ConnectionStringDictionary(string connectionString, NameValueCollection defaultMapping)
53                 {
54                         _actualKeys = new NameValueCollection();
55                         _dictionary = Parse (connectionString);
56                         _mapping = defaultMapping;
57                 }
58
59                 #endregion // Constructors
60
61                 #region Methods
62
63                 public string GetConnectionStringKey (string key)
64                 {
65                         string cached = _actualKeys [key];
66                         if (cached != null)
67                                 return cached;
68
69                         if (_mapping != null)
70                         for(int i = 0, c = _mapping.Keys.Count; i < c; i++) {
71                                 if (string.Compare(key, _mapping.Keys[i], true,
72                                         CultureInfo.InvariantCulture) == 0) {
73                                         string[] values = _mapping.GetValues(i);
74                                         for(int j = 0; j < values.Length; j++) {
75                                                 string actualKey = values[j];
76                                                 if (_dictionary.Contains (actualKey)) {
77                                                         _actualKeys.Add (key, actualKey);
78                                                         return actualKey;
79                                                 }
80                                         }
81                                 }
82                         }
83
84                         if (_dictionary.Contains(key))
85                                 return key;
86
87                         return null;
88                 }
89
90                 public static IDictionary Parse (string connectionString)
91                 {
92                         IDictionary userParameters = CollectionsUtil.CreateCaseInsensitiveHashtable();
93
94                         if (connectionString == null || connectionString.Length == 0) {
95                                 return userParameters;
96                         }
97                         //connectionString += ";";
98
99                         bool inQuote = false;
100                         bool inDQuote = false;
101                         bool inName = true;
102
103                         string name = String.Empty;
104                         string value = String.Empty;
105                         StringBuilder sb = new StringBuilder (connectionString.Length);
106
107                         for (int i = 0; i < connectionString.Length; i ++) {
108                                 char c = connectionString [i];
109                                 char peek;
110                                 if (i == connectionString.Length - 1)
111                                         peek = '\0';
112                                 else
113                                         peek = connectionString [i + 1];
114
115                                 switch (c) {
116                                         case '\'':
117                                                 if (inDQuote)
118                                                         sb.Append (c);
119                                                 else if (peek == c) {
120                                                         sb.Append(c);
121                                                         i ++;
122                                                 }
123                                                 else
124                                                         inQuote = !inQuote;
125                                                 break;
126                                         case '"':
127                                                 if (inQuote)
128                                                         sb.Append(c);
129                                                 else if (peek == c) {
130                                                         sb.Append(c);
131                                                         i ++;
132                                                 }
133                                                 else
134                                                         inDQuote = !inDQuote;
135                                                 break;
136                                         case ';':
137                                                 if (inDQuote || inQuote)
138                                                         sb.Append(c);
139                                                 else {
140                                                         if (name != null && name.Length > 0) {
141                                                                 value = sb.ToString();
142                                                                 userParameters [name.Trim()] = value.Trim();
143                                                         }
144                                                         inName = true;
145                                                         name = String.Empty;
146                                                         value = String.Empty;
147                                                         sb.Length = 0;
148                                                 }
149                                                 break;
150                                         case '=':
151                                                 if (inDQuote || inQuote || !inName)
152                                                         sb.Append (c);
153                                                 else if (peek == c) {
154                                                         sb.Append (c);
155                                                         i += 1;
156                                                 }
157                                                 else {
158                                                         name = sb.ToString();
159                                                         sb.Length = 0;
160                                                         inName = false;
161                                                 }
162                                                 break;
163                                         case ' ':
164                                                 if (inQuote || inDQuote)
165                                                         sb.Append(c);
166                                                 else if (sb.Length > 0 && peek != ';')
167                                                         sb.Append(c);
168                                                 break;
169                                         default:
170                                                 sb.Append(c);
171                                                 break;
172                                 }
173                         }
174
175                         if (inDQuote || inQuote)
176                                 throw new ArgumentException("connectionString");
177
178                         if (name != null && name.Length > 0) {
179                                 value = sb.ToString();
180                                 userParameters [name.Trim()] = value.Trim();
181                         }
182
183                         return userParameters;
184                 }
185
186
187                 #endregion // Methods
188
189                 #region IDictionary Members
190
191                 public virtual bool IsFixedSize
192                 {
193                         get { return _dictionary.IsFixedSize; }
194                 }
195
196                 public virtual bool IsReadOnly
197                 {
198                         get { return _dictionary.IsReadOnly; }
199                 }
200
201                 public virtual ICollection Keys
202                 {
203                         get { 
204                                 return _dictionary.Keys; 
205                         }
206                 }
207
208                 public virtual object this [object key] {
209                         get { 
210
211                                 if (!(key is String))
212                                         throw new ArgumentException("key is not string");
213
214                                 string skey = (string)key;
215
216                                 skey = GetConnectionStringKey(skey);
217                                 if (skey == null)
218                                         return null;
219
220                                 return _dictionary[skey];
221                         }
222
223                         set {
224                                 if (!(key is String))
225                                         throw new ArgumentException("key is not string");
226
227                                 string skey = (string)key;
228
229                                 skey = GetConnectionStringKey(skey);
230                                 if (skey == null)
231                                         skey = (string)key;
232
233                                 _dictionary[skey] = value;
234                         }
235                 }
236
237                 public virtual ICollection Values
238                 {
239                         get { return _dictionary.Values; }
240                 }
241
242                 public virtual void Add (object key, object value)
243                 {
244                         _dictionary.Add ((string)key, (string)value);
245                 }
246
247                 public virtual void Clear ()
248                 {
249                         _dictionary.Clear ();
250                 }
251
252                 public virtual bool Contains (object key)
253                 {
254                         return _dictionary.Contains (key);
255                 }
256
257                 public virtual IDictionaryEnumerator GetEnumerator ()
258                 {
259                         return _dictionary.GetEnumerator ();
260                 }
261
262                 public virtual void Remove (object key)
263                 {
264                         _dictionary.Remove ((string)key);
265                 }
266
267                 #endregion // IDictionary Members
268
269                 #region IEnumerable Members
270
271                 IEnumerator IEnumerable.GetEnumerator () 
272                 {
273                         return this.GetEnumerator();
274                 }
275
276                 #endregion // IEnumerable Members
277
278                 #region ICollection Members
279
280                 public virtual bool IsSynchronized 
281                 {
282                         get { return ((ICollection)_dictionary).IsSynchronized; }
283                 }
284
285                 public virtual int Count 
286                 {
287                         get { return _dictionary.Count; }
288                 }
289
290                 public virtual void CopyTo (Array array, int index) 
291                 {
292                         _dictionary.CopyTo (array, index);
293                 }
294
295                 public virtual object SyncRoot 
296                 {
297                         get {return ((ICollection)_dictionary).SyncRoot; }
298                 }
299
300                 #endregion // ICollection Members
301         }
302 }