Merge pull request #4195 from lateralusX/jlorenss/win-build-dependency
[mono.git] / mcs / class / System / System.Configuration / SettingValueElement.cs
index 0836218edabc0be0bd14e668d6d5a8f96a792c40..57f0ee07406d1748e8372f905f2c7e3eaa693eb8 100644 (file)
@@ -26,8 +26,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
 using System;
+using System.Reflection;
 #if (XML_DEP)
 using System.Xml;
 #endif
@@ -41,6 +41,11 @@ namespace System.Configuration
        {
 #if XML_DEP
                XmlNode node;
+
+#if (CONFIGURATION_DEP)
+               XmlNode original;
+#endif
+
 #endif
 
                [MonoTODO]
@@ -52,7 +57,7 @@ namespace System.Configuration
                [MonoTODO]
                protected override ConfigurationPropertyCollection Properties {
                        get {
-                               throw new NotImplementedException ();
+                               return base.Properties;
                        }
                }
 #endif
@@ -67,7 +72,8 @@ namespace System.Configuration
                [MonoTODO]
                protected override void DeserializeElement (XmlReader reader, bool serializeCollectionKey)
                {
-                       node = new XmlDocument ().ReadNode (reader);
+                       original = new XmlDocument ().ReadNode (reader);
+                       node = original.CloneNode (true);
                }
 #endif
 #endif
@@ -85,35 +91,109 @@ namespace System.Configuration
 #if (CONFIGURATION_DEP)
                protected override bool IsModified ()
                {
-                       throw new NotImplementedException ();
+                       return original != node;
                }
 
                protected override void Reset (ConfigurationElement parentElement)
                {
-                       throw new NotImplementedException ();
+                       node = null;
                }
 
                protected override void ResetModified ()
                {
-                       throw new NotImplementedException ();
+                       node = original;
                }
 #endif
 
 #if (XML_DEP) && (CONFIGURATION_DEP)
                protected override bool SerializeToXmlElement (XmlWriter writer, string elementName)
                {
-                       throw new NotImplementedException ();
+                       if (node == null)
+                               return false;
+                       node.WriteTo (writer);
+                       return true;
                }
 #endif
 
 #if (CONFIGURATION_DEP)
                protected override void Unmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
                {
-                       throw new NotImplementedException ();
+                       if (parentElement != null && sourceElement.GetType() != parentElement.GetType())
+                               throw new ConfigurationErrorsException ("Can't unmerge two elements of different type");
+
+                       bool isMinimalOrModified = saveMode == ConfigurationSaveMode.Minimal ||
+                               saveMode == ConfigurationSaveMode.Modified;
+
+                       foreach (PropertyInformation prop in sourceElement.ElementInformation.Properties)
+                       {
+                               if (prop.ValueOrigin == PropertyValueOrigin.Default)
+                                       continue;
+                               
+                               PropertyInformation unmergedProp = ElementInformation.Properties [prop.Name];
+                               
+                               object sourceValue = prop.Value;
+                               if (parentElement == null || !HasValue (parentElement, prop.Name)) {
+                                       unmergedProp.Value = sourceValue;
+                                       continue;
+                               }
+
+                               if (sourceValue == null)
+                                       continue;
+
+                               object parentValue = GetItem (parentElement, prop.Name);
+                               if (!PropertyIsElement (prop)) {
+                                       if (!object.Equals (sourceValue, parentValue) || 
+                                           (saveMode == ConfigurationSaveMode.Full) ||
+                                           (saveMode == ConfigurationSaveMode.Modified && prop.ValueOrigin == PropertyValueOrigin.SetHere))
+                                               unmergedProp.Value = sourceValue;
+                                       continue;
+                               }
+
+                               var sourceElem = (ConfigurationElement) sourceValue;
+                               if (isMinimalOrModified && !ElementIsModified (sourceElem))
+                                       continue;
+                               if (parentValue == null) {
+                                       unmergedProp.Value = sourceValue;
+                                       continue;
+                               }
+
+                               var parentElem = (ConfigurationElement) parentValue;
+                               ConfigurationElement copy = (ConfigurationElement) unmergedProp.Value;
+                               ElementUnmerge (copy, sourceElem, parentElem, saveMode);
+                       }
+               }
+
+               bool HasValue (ConfigurationElement element, string propName)
+               {
+                       PropertyInformation info = element.ElementInformation.Properties [propName];
+                       return info != null && info.ValueOrigin != PropertyValueOrigin.Default;
+               }
+
+               object GetItem (ConfigurationElement element, string property)
+               {
+                       PropertyInformation pi = ElementInformation.Properties [property];
+                       if (pi == null)
+                               throw new InvalidOperationException ("Property '" + property + "' not found in configuration element");
+
+                       return pi.Value;
+               }
+               
+               bool PropertyIsElement (PropertyInformation prop)
+               {
+                       return (typeof(ConfigurationElement).IsAssignableFrom (prop.Type));
+               }
+               
+               bool ElementIsModified (ConfigurationElement element)
+               {
+                       return (bool) element.GetType ().GetMethod ("IsModified", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (element, new object [0]);
+               }
+               
+               void ElementUnmerge (ConfigurationElement target, ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
+               {
+                       target.GetType ().GetMethod ("Unmerge", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (target, new object [] {sourceElement, parentElement, saveMode});
                }
 #endif
        }
 
 }
 
-#endif