[mono/mono] 40d5064d: hack SettingValueElement.Unmerge().

"Atsushi Eno ([email protected])" <[email protected]> Sat, 2 Nov 2013 07:55:45 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014217cf8689-09098cc1-0dca-4728-9db4-fd289cc2d504-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/36cf9822229b...40d5064d0497

   Commit: 40d5064d049749213401777d112e931835a86e9c
   Author: Atsushi Eno <[email protected]> (atsushieno)
     Date: 2013-11-02 07:54:09 GMT
      URL: https://github.com/mono/mono/commit/40d5064d049749213401777d112e931835a86e9c

hack SettingValueElement.Unmerge().

Changed paths:
  M mcs/class/System/System.Configuration/SettingValueElement.cs

Modified: mcs/class/System/System.Configuration/SettingValueElement.cs
===================================================================
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Reflection;
 #if (XML_DEP)
 using System.Xml;
 #endif
@@ -112,7 +113,79 @@ protected override bool SerializeToXmlElement (XmlWriter writer, string elementN
 #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
 	}


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches