X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Configuration%2FSystem.Configuration%2FConfigurationElement.cs;h=afd9d1811c771349f6da23634cd304aa8443264d;hb=f9801d39ef6a6610d859207d2aee3b8081eee921;hp=fdcc11fac30b82465a83f57f6937c94b94a03a32;hpb=e2359b782979ca70861579d16cdc2d2dbad2e76e;p=mono.git diff --git a/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs b/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs index fdcc11fac30..afd9d1811c7 100644 --- a/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs +++ b/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs @@ -67,14 +67,19 @@ namespace System.Configuration internal string RawXml { get { return rawXml; } - set { rawXml = value; } + set { + // FIXME: this hack is nasty. We should make + // some refactory on the entire assembly. + if (rawXml == null || value != null) + rawXml = value; + } } protected internal virtual void Init () { } - public ConfigurationElementProperty ElementProperty { + protected internal virtual ConfigurationElementProperty ElementProperty { get { if (elementProperty == null) elementProperty = new ConfigurationElementProperty (ElementInformation.Validator); @@ -89,21 +94,28 @@ namespace System.Configuration } } - [MonoTODO] + ConfigurationLockCollection lockAllAttributesExcept; public ConfigurationLockCollection LockAllAttributesExcept { get { - throw new NotImplementedException (); + if (lockAllAttributesExcept == null) { + lockAllAttributesExcept = new ConfigurationLockCollection (this, ConfigurationLockType.Attribute | ConfigurationLockType.Exclude); + } + + return lockAllAttributesExcept; } } - [MonoTODO] + ConfigurationLockCollection lockAllElementsExcept; public ConfigurationLockCollection LockAllElementsExcept { get { - throw new NotImplementedException (); + if (lockAllElementsExcept == null) { + lockAllElementsExcept = new ConfigurationLockCollection (this, ConfigurationLockType.Element | ConfigurationLockType.Exclude); + } + + return lockAllElementsExcept; } } - [MonoTODO] ConfigurationLockCollection lockAttributes; public ConfigurationLockCollection LockAttributes { get { @@ -115,49 +127,60 @@ namespace System.Configuration } } - [MonoTODO] + ConfigurationLockCollection lockElements; public ConfigurationLockCollection LockElements { get { - throw new NotImplementedException (); + if (lockElements == null) { + lockElements = new ConfigurationLockCollection (this, ConfigurationLockType.Element); + } + + return lockElements; } } - [MonoTODO] + bool lockItem; public bool LockItem { - get { - throw new NotImplementedException (); - } - set { - throw new NotImplementedException (); - } + get { return lockItem; } + set { lockItem = value; } } [MonoTODO] - public void ListErrors (IList list) + protected virtual void ListErrors (IList list) { throw new NotImplementedException (); } [MonoTODO] - public void SetPropertyValue (ConfigurationProperty prop, object value, bool ignoreLocks) - { - throw new NotImplementedException (); + protected void SetPropertyValue (ConfigurationProperty prop, object value, bool ignoreLocks) + { + try { + /* XXX all i know for certain is that Validation happens here */ + prop.Validate (value); + + /* XXX presumably the actual setting of the + * property happens here instead of in the + * set_Item code below, but that would mean + * the Value needs to be stuffed in the + * property, not the propertyinfo (or else the + * property needs a ref to the property info + * to correctly set the value). */ + } + catch (Exception e) { + throw new ConfigurationErrorsException (String.Format ("The value for the property '{0}' is not valid. The error is: {1}", prop.Name, e.Message), e); + } } internal ConfigurationPropertyCollection GetKeyProperties () { if (keyProps != null) return keyProps; - if (map != null && map.Properties == Properties) - keyProps = map.KeyProperties; - else { - keyProps = new ConfigurationPropertyCollection (); + ConfigurationPropertyCollection tmpkeyProps = new ConfigurationPropertyCollection (); foreach (ConfigurationProperty prop in Properties) { if (prop.IsKey) - keyProps.Add (prop); + tmpkeyProps.Add (prop); } - } - return keyProps; + + return keyProps = tmpkeyProps; } internal ConfigurationElementCollection GetDefaultCollection () @@ -166,15 +189,10 @@ namespace System.Configuration ConfigurationProperty defaultCollectionProp = null; - if (map != null && map.Properties == Properties) { - defaultCollectionProp = map.DefaultCollectionProperty; - } - else { - foreach (ConfigurationProperty prop in Properties) { - if (prop.IsDefaultCollection) { - defaultCollectionProp = prop; - break; - } + foreach (ConfigurationProperty prop in Properties) { + if (prop.IsDefaultCollection) { + defaultCollectionProp = prop; + break; } } @@ -203,7 +221,9 @@ namespace System.Configuration PropertyInformation pi = ElementInformation.Properties [property_name]; if (pi == null) throw new InvalidOperationException ("Property '" + property_name + "' not found in configuration element"); - + + SetPropertyValue (pi.Property, value, false); + pi.Value = value; modified = true; } @@ -233,8 +253,16 @@ namespace System.Configuration public override int GetHashCode () { int code = 0; - foreach (ConfigurationProperty prop in Properties) - code += this [prop].GetHashCode (); + object o; + + foreach (ConfigurationProperty prop in Properties) { + o = this [prop]; + if (o == null) + continue; + + code += o.GetHashCode (); + } + return code; } @@ -255,28 +283,60 @@ namespace System.Configuration { PropertyInformation prop = ElementInformation.Properties [reader.LocalName]; if (prop == null || (serializeCollectionKey && !prop.IsKey)) { - if (!OnDeserializeUnrecognizedAttribute (reader.LocalName, reader.Value)) + /* handle the built in ConfigurationElement attributes here */ + if (reader.LocalName == "lockAllAttributesExcept") { + LockAllAttributesExcept.SetFromList (reader.Value); + } + else if (reader.LocalName == "lockAllElementsExcept") { + LockAllElementsExcept.SetFromList (reader.Value); + } + else if (reader.LocalName == "lockAttributes") { + LockAttributes.SetFromList (reader.Value); + } + else if (reader.LocalName == "lockElements") { + LockElements.SetFromList (reader.Value); + } + else if (reader.LocalName == "lockItem") { + LockItem = (reader.Value.ToLowerInvariant () == "true"); + } + else if (reader.LocalName == "xmlns") { + /* ignore */ + } + else if (!OnDeserializeUnrecognizedAttribute (reader.LocalName, reader.Value)) throw new ConfigurationException ("Unrecognized attribute '" + reader.LocalName + "'."); + continue; } if (readProps.ContainsKey (prop)) throw new ConfigurationException ("The attribute '" + prop.Name + "' may only appear once in this element."); - - prop.SetStringValue (reader.Value); + + string value = null; + try { + value = reader.Value; + ValidateValue (prop.Property, value); + prop.SetStringValue (value); + } catch (ConfigurationErrorsException) { + throw; + } catch (ConfigurationException) { + throw; + } catch (Exception ex) { + string msg = String.Format ("The value of the property '{0}' cannot be parsed.", prop.Name); + throw new ConfigurationErrorsException (msg, ex, reader); + } readProps [prop] = prop.Name; } reader.MoveToElement (); if (reader.IsEmptyElement) { reader.Skip (); - } - else { + } else { + int depth = reader.Depth; + reader.ReadStartElement (); reader.MoveToContent (); - - while (reader.NodeType != XmlNodeType.EndElement) - { + + do { if (reader.NodeType != XmlNodeType.Element) { reader.Skip (); continue; @@ -284,13 +344,12 @@ namespace System.Configuration PropertyInformation prop = ElementInformation.Properties [reader.LocalName]; if (prop == null || (serializeCollectionKey && !prop.IsKey)) { - if (prop == null) { - ConfigurationElementCollection c = GetDefaultCollection (); - if (c != null && c.OnDeserializeUnrecognizedElement (reader.LocalName, reader)) - continue; - } - if (!OnDeserializeUnrecognizedElement (reader.LocalName, reader)) { + if (prop == null) { + ConfigurationElementCollection c = GetDefaultCollection (); + if (c != null && c.OnDeserializeUnrecognizedElement (reader.LocalName, reader)) + continue; + } throw new ConfigurationException ("Unrecognized element '" + reader.LocalName + "'."); } continue; @@ -305,13 +364,19 @@ namespace System.Configuration ConfigurationElement val = (ConfigurationElement) prop.Value; val.DeserializeElement (reader, serializeCollectionKey); readProps [prop] = prop.Name; - } + + reader.Read(); + + } while (depth < reader.Depth); + + if (reader.NodeType == XmlNodeType.EndElement) + reader.Read (); } modified = false; foreach (PropertyInformation prop in ElementInformation.Properties) - if (prop.IsRequired && !readProps.ContainsKey (prop)) { + if (!String.IsNullOrEmpty(prop.Name) && prop.IsRequired && !readProps.ContainsKey (prop)) { object val = OnRequiredPropertyNotFound (prop.Name); if (!object.Equals (val, prop.DefaultValue)) { prop.Value = val; @@ -409,9 +474,8 @@ namespace System.Configuration continue; ConfigurationElement val = (ConfigurationElement) prop.Value; - if (val != null && val.HasValues ()) { + if (val != null) wroteData = val.SerializeToXmlElement (writer, prop.Name) || wroteData; - } } return wroteData; } @@ -419,9 +483,14 @@ namespace System.Configuration protected internal virtual bool SerializeToXmlElement ( XmlWriter writer, string elementName) { - writer.WriteStartElement (elementName); + if (!HasValues ()) + return false; + + if (elementName != null && elementName != "") + writer.WriteStartElement (elementName); bool res = SerializeElement (writer, false); - writer.WriteEndElement (); + if (elementName != null && elementName != "") + writer.WriteEndElement (); return res; } @@ -475,114 +544,98 @@ namespace System.Configuration PropertyInformation info = ElementInformation.Properties [propName]; return info != null && info.ValueOrigin == PropertyValueOrigin.SetHere; } + + void ValidateValue (ConfigurationProperty p, string value) + { + ConfigurationValidatorBase validator; + if (p == null || (validator = p.Validator) == null) + return; + + if (!validator.CanValidate (p.Type)) + throw new ConfigurationException ( + String.Format ("Validator does not support type {0}", p.Type)); + validator.Validate (p.ConvertFromString (value)); + } } internal class ElementMap { - static Hashtable elementMaps = new Hashtable (); - - ConfigurationPropertyCollection properties; - ConfigurationPropertyCollection keyProperties; - ConfigurationProperty defaultCollectionProperty; +#if TARGET_JVM + const string elementMapsKey = "ElementMap_elementMaps"; + static Hashtable elementMaps + { + get + { + Hashtable tbl = (Hashtable) AppDomain.CurrentDomain.GetData (elementMapsKey); + if (tbl == null) { + lock (typeof (ElementMap)) { + tbl = (Hashtable) AppDomain.CurrentDomain.GetData (elementMapsKey); + if (tbl == null) { + tbl = Hashtable.Synchronized (new Hashtable ()); + AppDomain.CurrentDomain.SetData (elementMapsKey, tbl); + } + } + } + return tbl; + } + } +#else + static readonly Hashtable elementMaps = Hashtable.Synchronized (new Hashtable ()); +#endif + + readonly ConfigurationPropertyCollection properties; + readonly ConfigurationCollectionAttribute collectionAttribute; - ConfigurationCollectionAttribute collectionAttribute; - public static ElementMap GetMap (Type t) { - lock (elementMaps) { - ElementMap map = elementMaps [t] as ElementMap; - if (map != null) return map; - map = new ElementMap (t); - elementMaps [t] = map; - return map; - } + ElementMap map = elementMaps [t] as ElementMap; + if (map != null) return map; + map = new ElementMap (t); + elementMaps [t] = map; + return map; } public ElementMap (Type t) { - ReflectProperties (t); - } + properties = new ConfigurationPropertyCollection (); - protected void ReflectProperties (Type t) - { collectionAttribute = Attribute.GetCustomAttribute (t, typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute; - PropertyInfo[] props = t.GetProperties (); + PropertyInfo[] props = t.GetProperties (BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.Instance); foreach (PropertyInfo prop in props) { ConfigurationPropertyAttribute at = Attribute.GetCustomAttribute (prop, typeof(ConfigurationPropertyAttribute)) as ConfigurationPropertyAttribute; if (at == null) continue; string name = at.Name != null ? at.Name : prop.Name; - if ( - /* if we have no default value, don't bother to check further */ - at.DefaultValue != null && at.DefaultValue != ConfigurationProperty.NoDefaultValue - ) - { - try { - Convert.ChangeType (at.DefaultValue, prop.PropertyType); - } - catch { - throw new ConfigurationErrorsException (String.Format ("The default value for property '{0}' has a different type than the one of the property itself", - name)); - } - } + ConfigurationValidatorAttribute validatorAttr = Attribute.GetCustomAttribute (prop, typeof (ConfigurationValidatorAttribute)) as ConfigurationValidatorAttribute; + ConfigurationValidatorBase validator = validatorAttr != null ? validatorAttr.ValidatorInstance : null; - ConfigurationValidatorAttribute validatorAttr = Attribute.GetCustomAttribute (t, typeof(ConfigurationValidatorAttribute)) as ConfigurationValidatorAttribute; - ConfigurationValidatorBase validator = validatorAttr != null ? validatorAttr.ValidatorInstance : new DefaultValidator(); - - TypeConverter converter = TypeDescriptor.GetConverter (prop.PropertyType); + TypeConverterAttribute convertAttr = (TypeConverterAttribute) Attribute.GetCustomAttribute (prop, typeof (TypeConverterAttribute)); + TypeConverter converter = convertAttr != null ? (TypeConverter) Activator.CreateInstance (Type.GetType (convertAttr.ConverterTypeName), true) : null; ConfigurationProperty cp = new ConfigurationProperty (name, prop.PropertyType, at.DefaultValue, converter, validator, at.Options); - - cp.CollectionAttribute = Attribute.GetCustomAttribute (prop, typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute; - - if (properties == null) properties = new ConfigurationPropertyCollection (); + + cp.CollectionAttribute = Attribute.GetCustomAttribute (prop, typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute; properties.Add (cp); } } + + public ConfigurationCollectionAttribute CollectionAttribute + { + get { return collectionAttribute; } + } public bool HasProperties { - get { return properties != null && properties.Count > 0; } + get { return properties.Count > 0; } } public ConfigurationPropertyCollection Properties { get { - if (properties == null) properties = new ConfigurationPropertyCollection (); return properties; } } - - public ConfigurationPropertyCollection KeyProperties { - get { - if (keyProperties == null) { - keyProperties = new ConfigurationPropertyCollection (); - - if (properties != null) - foreach (ConfigurationProperty p in properties) - if (p.IsKey) keyProperties.Add (p); - } - return keyProperties; - } - } - - public ConfigurationCollectionAttribute CollectionAttribute { - get { return collectionAttribute; } - } - - public ConfigurationProperty DefaultCollectionProperty { - get { - if (defaultCollectionProperty == null) { - if (properties != null) - foreach (ConfigurationProperty p in properties) { - if (p.IsDefaultCollection) defaultCollectionProperty = p; - break; - } - } - return defaultCollectionProperty; - } - } } }