* ConfigurationElement.cs: Implemented Equals and GetHashCode.
authorLluis Sanchez <lluis@novell.com>
Tue, 9 Nov 2004 17:42:55 +0000 (17:42 -0000)
committerLluis Sanchez <lluis@novell.com>
Tue, 9 Nov 2004 17:42:55 +0000 (17:42 -0000)
Only reflect properties from type's members if the type does not
override Properties.
* ConfigurationElementCollection.cs: Implemented Equals and GetHashCode.
Other minor fixes.
* ConfigurationProperty.cs: It is not a subclass of ConfigurationElement.
* NonEmptyStringConfigurationProperty.cs, NonEmptyStringFlags.cs:
Implemented.

svn path=/trunk/mcs/; revision=35903

mcs/class/System/System.Configuration/ChangeLog
mcs/class/System/System.Configuration/ConfigurationElement.cs
mcs/class/System/System.Configuration/ConfigurationElementCollection.cs
mcs/class/System/System.Configuration/ConfigurationProperty.cs
mcs/class/System/System.Configuration/NonEmptyStringConfigurationProperty.cs [new file with mode: 0644]
mcs/class/System/System.Configuration/NonEmptyStringFlags.cs [new file with mode: 0644]

index 9bcee990fc01bbb57fc41d0a827bc96774b17175..58dea83473b21150055c9a506b8634e12d3a4f24 100644 (file)
@@ -1,3 +1,14 @@
+2004-11-09  Lluis Sanchez Gual <lluis@novell.com>
+
+       * ConfigurationElement.cs: Implemented Equals and GetHashCode.
+       Only reflect properties from type's members if the type does not
+       override Properties.
+       * ConfigurationElementCollection.cs: Implemented Equals and GetHashCode.
+       Other minor fixes.
+       * ConfigurationProperty.cs: It is not a subclass of ConfigurationElement.
+       * NonEmptyStringConfigurationProperty.cs, NonEmptyStringFlags.cs:
+       Implemented.
+       
 2004-11-09  Lluis Sanchez Gual <lluis@novell.com>
 
        * AppSettingsSection.cs: Mostly implemented (missing support for
index b216db51a8a618ea6538e228338e35129aa9658f..91d117062352556e8edbc9dbf3152b3e3e95279b 100644 (file)
@@ -45,10 +45,10 @@ namespace System.Configuration
                string rawXml;
                bool modified;
                ElementMap map;
+               ConfigurationPropertyCollection keyProps;
                
                protected ConfigurationElement ()
                {
-                       map = GetMap (GetType());
                }
                
                internal string RawXml {
@@ -58,9 +58,27 @@ namespace System.Configuration
 
                protected internal virtual ConfigurationPropertyCollection CollectionKeyProperties {
                        get {
-                               return map.KeyProperties;
+                               return null;
                        }
                }
+               
+               internal ConfigurationPropertyCollection GetKeyProperties ()
+               {
+                       if (keyProps != null) return keyProps;
+                       keyProps = CollectionKeyProperties;
+                       if (keyProps != null) return keyProps;
+                       
+                       if (map.Properties == Properties)
+                               keyProps = map.KeyProperties;
+                       else {
+                               keyProps = new ConfigurationPropertyCollection ();
+                               foreach (ConfigurationProperty prop in Properties) {
+                                       if (prop.IsKey)
+                                               keyProps.Add (prop);
+                               }
+                       }
+                       return keyProps;
+               }
 
                protected internal object this [ConfigurationProperty property] {
                        get {
@@ -92,13 +110,13 @@ namespace System.Configuration
 
                protected internal object this [string property_name] {
                        get {
-                               ConfigurationProperty prop = map.Properties [property_name];
+                               ConfigurationProperty prop = Properties [property_name];
                                if (prop == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration section");
                                return this [prop];
                        }
 
                        set {
-                               ConfigurationProperty prop = map.Properties [property_name];
+                               ConfigurationProperty prop = Properties [property_name];
                                if (prop == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration section");
                                this [prop] = value;
                        }
@@ -106,31 +124,42 @@ namespace System.Configuration
 
                protected internal virtual ConfigurationPropertyCollection Properties {
                        get {
+                               if (map == null)
+                                       map = GetMap (GetType());
                                return map.Properties;
                        }
                }
 
-               [MonoTODO]
                public override bool Equals (object compareTo)
                {
-                       return base.Equals (compareTo);
+                       ConfigurationElement other = compareTo as ConfigurationElement;
+                       if (other == null) return false;
+                       if (GetType() != other.GetType()) return false;
+                       
+                       foreach (ConfigurationProperty prop in Properties) {
+                               if (!object.Equals (this [prop], other [prop]))
+                                       return false;
+                       }
+                       return true;
                }
 
-               [MonoTODO]
                public override int GetHashCode ()
                {
-                       return base.GetHashCode ();
+                       int code = 0;
+                       foreach (ConfigurationProperty prop in Properties)
+                               code += this [prop].GetHashCode ();
+                       return code;
                }
 
                public bool HasValue (string key)
                {
                        if (values == null) return false;
-                       ConfigurationProperty prop = map.Properties [key];
+                       ConfigurationProperty prop = Properties [key];
                        if (prop == null) return false;
                        return values.ContainsKey (prop);
                }
                
-               internal bool HasValues ()
+               internal virtual bool HasValues ()
                {
                        return values != null && values.Count > 0;
                }
@@ -153,21 +182,16 @@ namespace System.Configuration
                        Hashtable readProps = new Hashtable ();
                        
                        reader.MoveToContent ();
-                       if (!map.HasProperties) {
-                               reader.Skip ();
-                               return;
-                       }
-                       
                        while (reader.MoveToNextAttribute ())
                        {
-                               ConfigurationProperty prop = map.Properties [reader.LocalName];
+                               ConfigurationProperty prop = Properties [reader.LocalName];
                                if (prop == null || (serializeCollectionKey && !prop.IsKey)) {
                                        if (!HandleUnrecognizedAttribute (reader.LocalName, reader.Value))
                                                throw new ConfigurationException ("Unrecognized attribute '" + reader.LocalName + "'.");
                                        continue;
                                }
                                
-                               if (readProps.Contains (prop))
+                               if (readProps.ContainsKey (prop))
                                        throw new ConfigurationException ("The attribute '" + prop.Name + "' may only appear once in this element.");
                                
                                object val = prop.ConvertFromString (reader.Value);
@@ -191,7 +215,7 @@ namespace System.Configuration
                                                continue;
                                        }
                                        
-                                       ConfigurationProperty prop = map.Properties [reader.LocalName];
+                                       ConfigurationProperty prop = Properties [reader.LocalName];
                                        if (prop == null || (serializeCollectionKey && !prop.IsKey)) {
                                                if (!HandleUnrecognizedElement (reader.LocalName, reader))
                                                        throw new ConfigurationException ("Unrecognized element '" + reader.LocalName + "'.");
@@ -246,9 +270,8 @@ namespace System.Configuration
                protected internal virtual void Reset (ConfigurationElement parentElement, object context)
                {
                        if (parentElement != null) {
-                               if (!map.HasProperties) return;
                                values = null;
-                               foreach (ConfigurationProperty prop in map.Properties) {
+                               foreach (ConfigurationProperty prop in Properties) {
                                        if (parentElement.HasValue (prop.Name)) {
                                                if (prop.IsElement) {
                                                        ConfigurationElement parentValue = parentElement [prop.Name] as ConfigurationElement;
@@ -273,19 +296,23 @@ namespace System.Configuration
                [MonoTODO ("Return value?")]
                protected internal virtual bool Serialize (XmlWriter writer, bool serializeCollectionKey)
                {
-                       if (values == null || !map.HasProperties) return true;
+                       if (values == null) return true;
+                       
+                       if (serializeCollectionKey) {
+                               foreach (ConfigurationProperty prop in GetKeyProperties ())
+                                       writer.WriteAttributeString (prop.Name, prop.ConvertToString (this[prop]));
+                               return true;
+                       }
                        
                        ArrayList elems = new ArrayList ();
                        foreach (DictionaryEntry entry in values)
                        {
                                ConfigurationProperty prop = (ConfigurationProperty) entry.Key;
-                               if (serializeCollectionKey && !prop.IsKey) continue;
                                if (prop.IsElement) continue;
                                
                                if (!object.Equals (entry.Value, prop.DefaultValue))
                                        writer.WriteAttributeString (prop.Name, prop.ConvertToString (entry.Value));
                        }
-                       if (serializeCollectionKey) return true;
                        
                        foreach (DictionaryEntry entry in values)
                        {
@@ -320,18 +347,15 @@ namespace System.Configuration
                                bool serializeCollectionKey, object context,
                                ConfigurationUpdateMode updateMode)
                {
-                       if (source.map != parent.map)
+                       if (source.GetType() != parent.GetType())
                                throw new ConfigurationException ("Can't unmerge two elements of different type");
                        
-                       ElementMap map = source.map;
-                       if (!map.HasProperties) return;
-                       
-                       foreach (ConfigurationProperty prop in map.Properties)
+                       foreach (ConfigurationProperty prop in source.Properties)
                        {
                                if (!source.HasValue (prop.Name)) continue;
                                
                                object sourceValue = source [prop];
-                               if      (!parent.HasValue (prop.Name) || updateMode == ConfigurationUpdateMode.Full) {
+                               if      (!parent.HasValue (prop.Name)) {
                                        this [prop] = sourceValue;
                                        continue;
                                }
@@ -348,6 +372,7 @@ namespace System.Configuration
                                        }
                                        else {
                                                if (!object.Equals (sourceValue, parentValue) || 
+                                                       (updateMode == ConfigurationUpdateMode.Full) ||
                                                        (updateMode == ConfigurationUpdateMode.Modified && source.IsReadFromConfig (prop.Name)))
                                                        this [prop] = sourceValue;
                                        }
@@ -394,11 +419,7 @@ namespace System.Configuration
                        lock (elementMaps) {
                                ElementMap map = elementMaps [t] as ElementMap;
                                if (map != null) return map;
-                               
-                               if (typeof(ConfigurationElementCollection).IsAssignableFrom (t))
-                                       map = new CollectionElementMap (t);
-                               else
-                                       map = new ElementMap (t);
+                               map = new ElementMap (t);
                                elementMaps [t] = map;
                                return map;
                        }
@@ -459,13 +480,6 @@ namespace System.Configuration
                        }
                }
        }
-       
-       internal class CollectionElementMap: ElementMap
-       {
-               public CollectionElementMap (Type t): base (t)
-               {
-               }
-       }
 }
 
 #endif
index 9a6dc051a63b7ae6a3cea726ded223bb2a382b80..a550fdfba1d8793fa71aa532b94ce4cc6540b8d7 100644 (file)
@@ -93,16 +93,16 @@ namespace System.Configuration
 
                protected virtual void BaseAdd (ConfigurationElement element, bool throwIfExists)
                {
-                       if (throwIfExists && BaseIndexOf (element) != -1)
-                               throw new ConfigurationException ("Duplicate element in collection");
+//                     if (throwIfExists && BaseIndexOf (element) != -1)
+//                             throw new ConfigurationException ("Duplicate element in collection");
                        list.Add (element);
                        modified = true;
                }
 
                protected virtual void BaseAdd (int index, ConfigurationElement element)
                {
-                       if (ThrowOnDuplicate && BaseIndexOf (element) != -1)
-                               throw new ConfigurationException ("Duplicate element in collection");
+//                     if (ThrowOnDuplicate && BaseIndexOf (element) != -1)
+//                             throw new ConfigurationException ("Duplicate element in collection");
                        list.Insert (index, element);
                        modified = true;
                }
@@ -193,19 +193,28 @@ namespace System.Configuration
                        return CreateNewElement ();
                }
                
-               [MonoTODO]
                public override bool Equals (object compareTo)
                {
-                       return base.Equals (compareTo);
+                       ConfigurationElementCollection other = compareTo as ConfigurationElementCollection;
+                       if (other == null) return false;
+                       if (GetType() != other.GetType()) return false;
+                       if (Count != other.Count) return false;
+                       
+                       for (int n=0; n<Count; n++) {
+                               if (!BaseGet (n).Equals (other.BaseGet (n)))
+                                       return false;
+                       }
+                       return true;
                }
-               
 
                protected abstract object GetElementKey (ConfigurationElement element);
 
-               [MonoTODO]
                public override int GetHashCode ()
                {
-                       return base.GetHashCode ();
+                       int code = 0;
+                       for (int n=0; n<Count; n++)
+                               code += BaseGet (n).GetHashCode ();
+                       return code;
                }
                
                void ICollection.CopyTo (Array arr, int index)
@@ -234,6 +243,11 @@ namespace System.Configuration
                        return modified;
                }
 
+               internal override bool HasValues ()
+               {
+                       return list.Count > 0;
+               }
+
                [MonoTODO ("parentItem.GetType().Name ??")]
                protected internal override void Reset (ConfigurationElement parentElement, object context)
                {
@@ -256,6 +270,10 @@ namespace System.Configuration
                [MonoTODO ("Support for BasicMap. Return value.")]
                protected internal override bool Serialize (XmlWriter writer, bool serializeCollectionKey)
                {
+                       if (serializeCollectionKey) {
+                               return base.Serialize (writer, serializeCollectionKey);
+                       }
+                       
                        if (emitClear)
                                writer.WriteElementString ("clear","");
                        
@@ -277,6 +295,7 @@ namespace System.Configuration
                {
                        if (elementName == "clear") {
                                BaseClear ();
+                               emitClear = true;
                                modified = false;
                                return true;
                        }
@@ -320,6 +339,16 @@ namespace System.Configuration
                        
                        if (updateMode == ConfigurationUpdateMode.Full)
                                EmitClear = true;
+                       else {
+                               for (int n=0; n<parent.Count; n++) {
+                                       ConfigurationElement pitem = parent.BaseGet (n);
+                                       object key = parent.GetElementKey (pitem);
+                                       if (source.IndexOfKey (key) == -1) {
+                                               if (removed == null) removed = new ArrayList ();
+                                               removed.Add (pitem);
+                                       }
+                               }
+                       }
                }
 
                #endregion // Methods
index 5ec94f386d5f9ec365ee2d038a6bdde37d2ff993..f1f44b8886f39415c05ea2481409c4ebcf7b0690 100644 (file)
@@ -34,7 +34,7 @@ using System.ComponentModel;
 
 namespace System.Configuration
 {
-       public class ConfigurationProperty : ConfigurationElement
+       public class ConfigurationProperty
        {
                string name;
                Type type;
diff --git a/mcs/class/System/System.Configuration/NonEmptyStringConfigurationProperty.cs b/mcs/class/System/System.Configuration/NonEmptyStringConfigurationProperty.cs
new file mode 100644 (file)
index 0000000..a1396cd
--- /dev/null
@@ -0,0 +1,71 @@
+//
+// System.Configuration.NonEmptyStringConfigurationProperty.cs
+//
+// Authors:
+//  Lluis Sanchez Gual (lluis@novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+using System;
+
+namespace System.Configuration
+{
+       public sealed class NonEmptyStringConfigurationProperty : ConfigurationProperty
+       {
+               NonEmptyStringFlags stringFlags;
+               
+               public NonEmptyStringConfigurationProperty (string name, string defaultValue, ConfigurationPropertyFlags flags)
+                       : base (name, typeof(string), defaultValue, flags)
+               {
+               }
+
+               public NonEmptyStringConfigurationProperty (string name, string defaultValue, ConfigurationPropertyFlags flags, NonEmptyStringFlags nonEmptyStringFlags)
+                       : base (name, typeof(string), defaultValue, flags)
+               {
+                       stringFlags = nonEmptyStringFlags;
+               }
+
+               protected internal override object ConvertFromString (string value)
+               {
+                       return Check (value);
+               }
+
+               protected internal override string ConvertToString (object value)
+               {
+                       return Check (value as string);
+               }
+               
+               string Check (string s)
+               {
+                       if (s == string.Empty || s == null)
+                               throw new ConfigurationException ("The property '" + Name + "' can't be empty");
+                       
+                       if (stringFlags == NonEmptyStringFlags.TrimWhitespace)
+                               return s.Trim ();
+                       else
+                               return s;
+               }
+       }
+}
+#endif
diff --git a/mcs/class/System/System.Configuration/NonEmptyStringFlags.cs b/mcs/class/System/System.Configuration/NonEmptyStringFlags.cs
new file mode 100644 (file)
index 0000000..f189039
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// System.Configuration.NonEmptyStringFlags.cs
+//
+// Authors:
+//  Lluis Sanchez Gual (lluis@novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+
+#if NET_2_0
+
+namespace System.Configuration
+{
+       public enum NonEmptyStringFlags
+       {
+               None,
+               TrimWhitespace
+       }
+}
+#endif