Skip to content

Commit

Permalink
* ConfigurationElement.cs: Implemented Equals and GetHashCode.
Browse files Browse the repository at this point in the history
	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
  • Loading branch information
slluis committed Nov 9, 2004
1 parent 82eb66b commit 248f9d5
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 51 deletions.
11 changes: 11 additions & 0 deletions mcs/class/System/System.Configuration/ChangeLog
@@ -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
Expand Down
96 changes: 55 additions & 41 deletions mcs/class/System/System.Configuration/ConfigurationElement.cs
Expand Up @@ -45,10 +45,10 @@ public abstract class ConfigurationElement
string rawXml;
bool modified;
ElementMap map;
ConfigurationPropertyCollection keyProps;

protected ConfigurationElement ()
{
map = GetMap (GetType());
}

internal string RawXml {
Expand All @@ -58,9 +58,27 @@ protected ConfigurationElement ()

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 {
Expand Down Expand Up @@ -92,45 +110,56 @@ protected ConfigurationElement ()

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;
}
}

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;
}
Expand All @@ -153,21 +182,16 @@ protected internal virtual void Deserialize (XmlReader reader, bool serializeCol
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);
Expand All @@ -191,7 +215,7 @@ protected internal virtual void Deserialize (XmlReader reader, bool serializeCol
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 + "'.");
Expand Down Expand Up @@ -246,9 +270,8 @@ protected internal virtual void ReadXml (XmlReader reader, object context)
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;
Expand All @@ -273,19 +296,23 @@ protected internal virtual void ResetModified ()
[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)
{
Expand Down Expand Up @@ -320,18 +347,15 @@ protected internal virtual bool Serialize (XmlWriter writer, bool serializeColle
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;
}
Expand All @@ -348,6 +372,7 @@ protected internal virtual bool Serialize (XmlWriter writer, bool serializeColle
}
else {
if (!object.Equals (sourceValue, parentValue) ||
(updateMode == ConfigurationUpdateMode.Full) ||
(updateMode == ConfigurationUpdateMode.Modified && source.IsReadFromConfig (prop.Name)))
this [prop] = sourceValue;
}
Expand Down Expand Up @@ -394,11 +419,7 @@ internal static ElementMap GetMap (Type t)
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;
}
Expand Down Expand Up @@ -459,13 +480,6 @@ public ConfigurationPropertyCollection Properties
}
}
}

internal class CollectionElementMap: ElementMap
{
public CollectionElementMap (Type t): base (t)
{
}
}
}

#endif
Expand Down
Expand Up @@ -93,16 +93,16 @@ protected virtual void BaseAdd (ConfigurationElement element)

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;
}
Expand Down Expand Up @@ -193,19 +193,28 @@ protected virtual ConfigurationElement CreateNewElement (string elementName)
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)
Expand Down Expand Up @@ -234,6 +243,11 @@ protected internal override bool IsModified ()
return modified;
}

internal override bool HasValues ()
{
return list.Count > 0;
}

[MonoTODO ("parentItem.GetType().Name ??")]
protected internal override void Reset (ConfigurationElement parentElement, object context)
{
Expand All @@ -256,6 +270,10 @@ protected internal override void ResetModified ()
[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","");

Expand All @@ -277,6 +295,7 @@ protected override bool HandleUnrecognizedElement (string elementName, XmlReader
{
if (elementName == "clear") {
BaseClear ();
emitClear = true;
modified = false;
return true;
}
Expand Down Expand Up @@ -320,6 +339,16 @@ protected internal override void UnMerge (ConfigurationElement sourceElement, Co

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
Expand Down
Expand Up @@ -34,7 +34,7 @@

namespace System.Configuration
{
public class ConfigurationProperty : ConfigurationElement
public class ConfigurationProperty
{
string name;
Type type;
Expand Down

0 comments on commit 248f9d5

Please sign in to comment.