89adbe2589101044f97e5213389bd42f7dd8bb65
[mono.git] / mcs / class / System / System.Configuration / ConfigHelper.cs
1 //
2 // System.Configuration.ConfigHelper
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002 Ximian, Inc (http://www.ximian.com)
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 using System.Collections;
32 using System.Collections.Specialized;
33 #if (XML_DEP)
34 using System.Xml;
35 #endif
36
37 namespace System.Configuration
38 {
39         class ConfigHelper
40         {
41                 class CollectionWrapper
42                 {
43                         IDictionary dict;
44                         NameValueCollection collection;
45                         bool isDict;
46
47                         public CollectionWrapper (IDictionary dict)
48                         {
49                                 this.dict = dict;
50                                 isDict = true;
51                         }
52
53                         public CollectionWrapper (NameValueCollection collection)
54                         {
55                                 this.collection = collection;
56                                 isDict = false;
57                         }
58
59                         public void Remove (string s)
60                         {
61                                 if (isDict)
62                                         dict.Remove (s);
63                                 else
64                                         collection.Remove (s);
65                         }
66
67                         public void Clear ()
68                         {
69                                 if (isDict)
70                                         dict.Clear ();
71                                 else
72                                         collection.Clear ();
73                         }
74
75                         public string this [string key]
76                         {
77                                 set {
78                                         if (isDict)
79                                                 dict [key] = value;
80                                         else
81                                                 collection [key] = value;
82                                 }
83                         }
84
85                         public object UnWrap ()
86                         {
87                                 if (isDict)
88                                         return dict;
89                                 else
90                                         return collection;
91                         }
92                 }
93 #if (XML_DEP)
94                 internal static IDictionary GetDictionary (IDictionary prev,
95                                                            XmlNode region,
96                                                            string nameAtt,
97                                                            string valueAtt)
98                 {
99                         Hashtable hash;
100                         if (prev == null)
101                                 hash = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
102                                                       CaseInsensitiveComparer.Default);
103                         else {
104                                 Hashtable aux = (Hashtable) prev;
105                                 hash = (Hashtable) aux.Clone ();
106                         }
107
108                         CollectionWrapper result = new CollectionWrapper (hash);
109                         result = GoGetThem (result, region, nameAtt, valueAtt);
110                         if (result == null)
111                                 return null;
112
113                         return result.UnWrap () as IDictionary;
114                 }
115
116                 internal static ConfigNameValueCollection GetNameValueCollection (NameValueCollection prev,
117                                                                             XmlNode region,
118                                                                             string nameAtt,
119                                                                             string valueAtt)
120                 {
121                         ConfigNameValueCollection coll =
122                                         new ConfigNameValueCollection (CaseInsensitiveHashCodeProvider.Default,
123                                                                  CaseInsensitiveComparer.Default);
124
125                         if (prev != null)
126                                 coll.Add (prev);
127
128                         CollectionWrapper result = new CollectionWrapper (coll);
129                         result = GoGetThem (result, region, nameAtt, valueAtt);
130                         if (result == null)
131                                 return null;
132
133                         return result.UnWrap () as ConfigNameValueCollection;
134                 }
135
136                 private static CollectionWrapper GoGetThem (CollectionWrapper result,
137                                                             XmlNode region,
138                                                             string nameAtt,
139                                                             string valueAtt)
140                 {
141                         if (region.Attributes != null && region.Attributes.Count != 0) {
142                                 if (region.Attributes.Count != 1 || region.Attributes[0].Name != "xmlns") {
143                                         throw new ConfigurationException ("Unknown attribute", region);
144                                 }
145                         }
146
147                         XmlNode keyNode;
148                         XmlNode valueNode;
149                         XmlNodeList childs = region.ChildNodes;
150                         foreach (XmlNode node in childs) {
151                                 XmlNodeType ntype = node.NodeType;
152                                 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
153                                         continue;
154
155                                 if (ntype != XmlNodeType.Element)
156                                         throw new ConfigurationException ("Only XmlElement allowed", node);
157                                         
158                                 string nodeName = node.Name;
159                                 if (nodeName == "clear") {
160                                         if (node.Attributes != null && node.Attributes.Count != 0)
161                                                 throw new ConfigurationException ("Unknown attribute", node);
162
163                                         result.Clear ();
164                                 } else if (nodeName == "remove") {
165                                         keyNode = null;
166                                         if (node.Attributes != null)
167                                                 keyNode = node.Attributes.RemoveNamedItem (nameAtt);
168
169                                         if (keyNode == null)
170                                                 throw new ConfigurationException ("Required attribute not found",
171                                                                                   node);
172                                         if (keyNode.Value == String.Empty)
173                                                 throw new ConfigurationException ("Required attribute is empty",
174                                                                                   node);
175
176                                         if (node.Attributes.Count != 0)
177                                                 throw new ConfigurationException ("Unknown attribute", node);
178                                         
179                                         result.Remove (keyNode.Value);
180                                 } else if (nodeName == "add") {
181                                         keyNode = null;
182                                         if (node.Attributes != null)
183                                                 keyNode = node.Attributes.RemoveNamedItem (nameAtt);
184
185                                         if (keyNode == null)
186                                                 throw new ConfigurationException ("Required attribute not found",
187                                                                                   node);
188                                         if (keyNode.Value == String.Empty)
189                                                 throw new ConfigurationException ("Required attribute is empty",
190                                                                                   node);
191
192                                         valueNode = node.Attributes.RemoveNamedItem (valueAtt);
193                                         if (valueNode == null)
194                                                 throw new ConfigurationException ("Required attribute not found",
195                                                                                   node);
196
197                                         if (node.Attributes.Count != 0)
198                                                 throw new ConfigurationException ("Unknown attribute", node);
199
200                                         result [keyNode.Value] = valueNode.Value;
201                                 } else {
202                                         throw new ConfigurationException ("Unknown element", node);
203                                 }
204                         }
205
206                         return result;
207                 }
208 #endif
209         }
210         
211         internal class ConfigNameValueCollection: NameValueCollection
212         {
213                 bool modified;
214                 
215                 public ConfigNameValueCollection ()
216                 {
217                 }
218                 
219                 public ConfigNameValueCollection (ConfigNameValueCollection col)
220                 : base (col.Count, col)
221                 {
222                 }
223                 
224                 public ConfigNameValueCollection (IHashCodeProvider hashProvider, IComparer comparer)
225                         : base(hashProvider, comparer)
226                 {
227                 }
228                 
229                 public void ResetModified ()
230                 {
231                         modified = false;
232                 }
233                 
234                 public bool IsModified {
235                         get { return modified; }
236                 }
237                 
238                 public override void Set (string name, string value)
239                 {
240                         base.Set (name, value);
241                         modified = true;
242                 }
243         }
244
245 }