(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System / System.Configuration / ConfigurationElement.cs
blobaed14911479af45fbebeacb2f367d99d821879bc
1 //
2 // System.Configuration.ConfigurationElement.cs
3 //
4 // Authors:
5 // Duncan Mak (duncan@ximian.com)
6 // Lluis Sanchez Gual (lluis@novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
30 #if NET_2_0 && XML_DEP
31 #if XML_DEP
32 using System.Collections;
33 using System.Xml;
34 using System.Reflection;
35 using System.IO;
36 using System.ComponentModel;
38 namespace System.Configuration
40 public abstract class ConfigurationElement
42 static Hashtable elementMaps = new Hashtable ();
43 Hashtable values;
44 string[] readProperties;
45 string rawXml;
46 bool modified;
47 ElementMap map;
49 protected ConfigurationElement ()
51 map = GetMap (GetType());
54 internal string RawXml {
55 get { return rawXml; }
56 set { rawXml = value; }
59 protected internal virtual ConfigurationPropertyCollection CollectionKeyProperties {
60 get {
61 return map.KeyProperties;
65 protected internal object this [ConfigurationProperty property] {
66 get {
67 if (values == null || !values.ContainsKey (property)) {
68 if (property.IsElement) {
69 object elem = Activator.CreateInstance (property.Type);
70 this [property] = elem;
71 return elem;
73 else
74 return property.DefaultValue;
76 else
77 return values [property];
80 set {
81 if (object.Equals (value, property.DefaultValue)) {
82 if (values == null) return;
83 values.Remove (property);
85 else {
86 if (values == null) values = new Hashtable ();
87 values [property] = value;
89 modified = true;
93 protected internal object this [string property_name] {
94 get {
95 ConfigurationProperty prop = map.Properties [property_name];
96 if (prop == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration section");
97 return this [prop];
100 set {
101 ConfigurationProperty prop = map.Properties [property_name];
102 if (prop == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration section");
103 this [prop] = value;
107 protected internal virtual ConfigurationPropertyCollection Properties {
108 get {
109 return map.Properties;
113 [MonoTODO]
114 public override bool Equals (object compareTo)
116 return base.Equals (compareTo);
119 [MonoTODO]
120 public override int GetHashCode ()
122 return base.GetHashCode ();
125 public bool HasValue (string key)
127 if (values == null) return false;
128 ConfigurationProperty prop = map.Properties [key];
129 if (prop == null) return false;
130 return values.ContainsKey (prop);
133 internal bool HasValues ()
135 return values != null && values.Count > 0;
138 [MonoTODO]
139 public string PropertyFileName ()
141 throw new NotImplementedException ();
144 [MonoTODO]
145 public int PropertyLineNumber ()
147 throw new NotImplementedException ();
150 [MonoTODO]
151 protected internal virtual void Deserialize (XmlReader reader, bool serializeCollectionKey)
153 Hashtable readProps = new Hashtable ();
155 reader.MoveToContent ();
156 if (!map.HasProperties) {
157 reader.Skip ();
158 return;
161 while (reader.MoveToNextAttribute ())
163 ConfigurationProperty prop = map.Properties [reader.LocalName];
164 if (prop == null) {
165 if (!HandleUnrecognizedAttribute (reader.LocalName, reader.Value))
166 throw new ConfigurationException ("Unrecognized attribute '" + reader.LocalName + "'.");
167 continue;
170 if (readProps.Contains (prop))
171 throw new ConfigurationException ("The attribute '" + prop.Name + "' may only appear once in this element.");
173 object val = prop.ConvertFromString (reader.Value);
174 if (!object.Equals (val, prop.DefaultValue))
175 this [prop] = val;
176 readProps [prop] = prop.Name;
179 reader.MoveToElement ();
180 if (reader.IsEmptyElement) {
181 reader.Skip ();
183 else {
184 reader.ReadStartElement ();
185 reader.MoveToContent ();
187 while (reader.NodeType != XmlNodeType.EndElement)
189 if (reader.NodeType != XmlNodeType.Element) {
190 reader.Skip ();
191 continue;
194 ConfigurationProperty prop = map.Properties [reader.LocalName];
195 if (prop == null) {
196 if (!HandleUnrecognizedElement (reader.LocalName, reader))
197 throw new ConfigurationException ("Unrecognized element '" + reader.LocalName + "'.");
198 continue;
201 if (!prop.IsElement)
202 throw new ConfigurationException ("Property '" + prop.Name + "' is not a ConfigurationElement.");
204 if (readProps.Contains (prop))
205 throw new ConfigurationException ("The element <" + prop.Name + "> may only appear once in this section.");
207 ConfigurationElement val = this [prop] as ConfigurationElement;
208 val.Deserialize (reader, serializeCollectionKey);
209 readProps [prop] = prop.Name;
213 modified = false;
215 if (readProps.Count > 0) {
216 readProperties = new string [readProps.Count];
217 readProps.Values.CopyTo ((object[])readProperties, 0);
221 protected virtual bool HandleUnrecognizedAttribute (string name, string value)
223 return false;
226 protected virtual bool HandleUnrecognizedElement (string element, XmlReader reader)
228 return false;
231 [MonoTODO]
232 protected internal virtual void InitializeDefault ()
234 values = null;
237 protected internal virtual bool IsModified ()
239 return modified;
242 [MonoTODO]
243 protected internal virtual void ReadXml (XmlReader reader, object context)
245 Deserialize (reader, false);
248 [MonoTODO]
249 protected internal virtual void Reset (ConfigurationElement parent_element, object context)
251 if (parent_element != null) {
252 if (!map.HasProperties) return;
253 values = null;
254 foreach (ConfigurationProperty prop in map.Properties) {
255 if (parent_element.HasValue (prop.Name))
256 this [prop] = parent_element [prop.Name];
259 else
260 InitializeDefault ();
263 protected internal virtual void ResetModified ()
265 modified = false;
268 [MonoTODO ("Return value?")]
269 protected internal virtual bool Serialize (XmlWriter writer, bool serializeCollectionKey)
271 if (values == null || !map.HasProperties) return true;
273 ArrayList elems = new ArrayList ();
274 foreach (DictionaryEntry entry in values)
276 ConfigurationProperty prop = (ConfigurationProperty) entry.Key;
277 if (serializeCollectionKey && !prop.IsKey) continue;
278 if (prop.IsElement) continue;
280 if (!object.Equals (entry.Value, prop.DefaultValue))
281 writer.WriteAttributeString (prop.Name, prop.ConvertToString (entry.Value));
283 if (serializeCollectionKey) return true;
285 foreach (DictionaryEntry entry in values)
287 ConfigurationProperty prop = (ConfigurationProperty) entry.Key;
288 if (!prop.IsElement) continue;
290 ConfigurationElement val = entry.Value as ConfigurationElement;
291 if (val != null && val.HasValues ())
292 val.SerializeToXmlElement (writer, prop.Name);
294 return true;
297 [MonoTODO]
298 protected internal virtual bool SerializeAttributeOnRemove (
299 ConfigurationProperty property)
301 throw new NotImplementedException ();
304 protected internal virtual bool SerializeToXmlElement (
305 XmlWriter writer, string elementName)
307 writer.WriteStartElement (elementName);
308 Serialize (writer, false);
309 writer.WriteEndElement ();
310 return true;
313 protected internal virtual void UnMerge (
314 ConfigurationElement source, ConfigurationElement parent,
315 bool serializeCollectionKey, object context,
316 ConfigurationUpdateMode updateMode)
318 if (source.map != parent.map)
319 throw new ConfigurationException ("Can't unmerge two elements of different type");
321 ElementMap map = source.map;
322 if (!map.HasProperties) return;
324 foreach (ConfigurationProperty prop in map.Properties)
326 if (!source.HasValue (prop.Name)) continue;
328 object sourceValue = source [prop];
329 if (!parent.HasValue (prop.Name) || updateMode == ConfigurationUpdateMode.Full) {
330 this [prop] = sourceValue;
331 continue;
333 else if (sourceValue != null) {
334 object parentValue = parent [prop];
335 if (prop.IsElement) {
336 if (parentValue != null) {
337 ConfigurationElement copy = (ConfigurationElement) Activator.CreateInstance (prop.Type);
338 copy.UnMerge ((ConfigurationElement) sourceValue, (ConfigurationElement) parentValue, serializeCollectionKey, context, updateMode);
339 this [prop] = copy;
341 else
342 this [prop] = sourceValue;
344 else {
345 if (!object.Equals (sourceValue, parentValue) ||
346 (updateMode == ConfigurationUpdateMode.Modified && source.IsReadFromConfig (prop.Name)))
347 this [prop] = sourceValue;
353 bool IsReadFromConfig (string propName)
355 return readProperties != null && Array.IndexOf (readProperties, propName) != -1;
358 [MonoTODO]
359 protected virtual void ValidateRequiredProperties (
360 ConfigurationPropertyCollection properties,
361 bool serialize_collection_key)
363 throw new NotImplementedException ();
366 protected internal virtual string WriteXml (
367 ConfigurationElement parent,
368 object context, string name,
369 ConfigurationUpdateMode updateMode)
371 ConfigurationElement elem;
372 if (parent != null) {
373 elem = (ConfigurationElement) Activator.CreateInstance (GetType());
374 elem.UnMerge (this, parent, false, context, updateMode);
376 else
377 elem = this;
379 StringWriter sw = new StringWriter ();
380 XmlTextWriter tw = new XmlTextWriter (sw);
381 tw.Formatting = Formatting.Indented;
382 elem.SerializeToXmlElement (tw, name);
383 tw.Close ();
384 return sw.ToString ();
387 internal static ElementMap GetMap (Type t)
389 lock (elementMaps) {
390 ElementMap map = elementMaps [t] as ElementMap;
391 if (map != null) return map;
393 if (typeof(ConfigurationElementCollection).IsAssignableFrom (t))
394 map = new CollectionElementMap (t);
395 else
396 map = new ElementMap (t);
397 elementMaps [t] = map;
398 return map;
403 internal class ElementMap
405 ConfigurationPropertyCollection properties;
406 ConfigurationPropertyCollection keyProperties;
408 public ElementMap (Type t)
410 ReflectProperties (t);
413 protected void ReflectProperties (Type t)
415 PropertyInfo[] props = t.GetProperties ();
416 foreach (PropertyInfo prop in props)
418 ConfigurationPropertyAttribute at = (ConfigurationPropertyAttribute) Attribute.GetCustomAttribute (prop, typeof(ConfigurationPropertyAttribute)) as ConfigurationPropertyAttribute;
419 if (at == null) continue;
420 string name = at.Name != null ? at.Name : prop.Name;
422 ConfigurationValidationAttribute validator = (ConfigurationValidationAttribute) Attribute.GetCustomAttribute (t, typeof(ConfigurationValidationAttribute)) as ConfigurationValidationAttribute;
423 TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType);
424 ConfigurationProperty cp = new ConfigurationProperty (name, prop.PropertyType, at.DefaultValue, converter, validator, at.Flags);
426 if (properties == null) properties = new ConfigurationPropertyCollection ();
427 properties.Add (cp);
431 public bool HasProperties
433 get { return properties != null && properties.Count > 0; }
436 public ConfigurationPropertyCollection Properties
438 get {
439 if (properties == null) properties = new ConfigurationPropertyCollection ();
440 return properties;
444 public ConfigurationPropertyCollection KeyProperties {
445 get {
446 if (keyProperties == null) {
447 keyProperties = new ConfigurationPropertyCollection ();
449 if (properties != null)
450 foreach (ConfigurationProperty p in properties)
451 if (p.IsKey) keyProperties.Add (p);
453 return keyProperties;
458 internal class CollectionElementMap: ElementMap
460 public CollectionElementMap (Type t): base (t)
466 #endif
467 #endif