Merge pull request #4169 from evincarofautumn/fix-xmm-scanning-mac-x86
[mono.git] / mcs / class / System / System.Configuration / SettingValueElement.cs
1 //
2 // System.Web.UI.WebControls.SettingValueElement.cs
3 //
4 // Authors:
5 //      Chris Toshok (toshok@ximian.com)
6 //
7 // (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Reflection;
31 #if (XML_DEP)
32 using System.Xml;
33 #endif
34
35 namespace System.Configuration
36 {
37         public sealed class SettingValueElement
38 #if (CONFIGURATION_DEP)
39                 : ConfigurationElement
40 #endif
41         {
42 #if XML_DEP
43                 XmlNode node;
44
45 #if (CONFIGURATION_DEP)
46                 XmlNode original;
47 #endif
48
49 #endif
50
51                 [MonoTODO]
52                 public SettingValueElement ()
53                 {
54                 }
55
56 #if (CONFIGURATION_DEP)
57                 [MonoTODO]
58                 protected override ConfigurationPropertyCollection Properties {
59                         get {
60                                 return base.Properties;
61                         }
62                 }
63 #endif
64
65 #if (XML_DEP)
66                 public XmlNode ValueXml {
67                         get { return node; }
68                         set { node = value; }
69                 }
70
71 #if (CONFIGURATION_DEP)
72                 [MonoTODO]
73                 protected override void DeserializeElement (XmlReader reader, bool serializeCollectionKey)
74                 {
75                         original = new XmlDocument ().ReadNode (reader);
76                         node = original.CloneNode (true);
77                 }
78 #endif
79 #endif
80
81                 public override bool Equals (object settingValue)
82                 {
83                         throw new NotImplementedException ();
84                 }
85
86                 public override int GetHashCode ()
87                 {
88                         throw new NotImplementedException ();
89                 }
90
91 #if (CONFIGURATION_DEP)
92                 protected override bool IsModified ()
93                 {
94                         return original != node;
95                 }
96
97                 protected override void Reset (ConfigurationElement parentElement)
98                 {
99                         node = null;
100                 }
101
102                 protected override void ResetModified ()
103                 {
104                         node = original;
105                 }
106 #endif
107
108 #if (XML_DEP) && (CONFIGURATION_DEP)
109                 protected override bool SerializeToXmlElement (XmlWriter writer, string elementName)
110                 {
111                         if (node == null)
112                                 return false;
113                         node.WriteTo (writer);
114                         return true;
115                 }
116 #endif
117
118 #if (CONFIGURATION_DEP)
119                 protected override void Unmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
120                 {
121                         if (parentElement != null && sourceElement.GetType() != parentElement.GetType())
122                                 throw new ConfigurationErrorsException ("Can't unmerge two elements of different type");
123
124                         bool isMinimalOrModified = saveMode == ConfigurationSaveMode.Minimal ||
125                                 saveMode == ConfigurationSaveMode.Modified;
126
127                         foreach (PropertyInformation prop in sourceElement.ElementInformation.Properties)
128                         {
129                                 if (prop.ValueOrigin == PropertyValueOrigin.Default)
130                                         continue;
131                                 
132                                 PropertyInformation unmergedProp = ElementInformation.Properties [prop.Name];
133                                 
134                                 object sourceValue = prop.Value;
135                                 if (parentElement == null || !HasValue (parentElement, prop.Name)) {
136                                         unmergedProp.Value = sourceValue;
137                                         continue;
138                                 }
139
140                                 if (sourceValue == null)
141                                         continue;
142
143                                 object parentValue = GetItem (parentElement, prop.Name);
144                                 if (!PropertyIsElement (prop)) {
145                                         if (!object.Equals (sourceValue, parentValue) || 
146                                             (saveMode == ConfigurationSaveMode.Full) ||
147                                             (saveMode == ConfigurationSaveMode.Modified && prop.ValueOrigin == PropertyValueOrigin.SetHere))
148                                                 unmergedProp.Value = sourceValue;
149                                         continue;
150                                 }
151
152                                 var sourceElem = (ConfigurationElement) sourceValue;
153                                 if (isMinimalOrModified && !ElementIsModified (sourceElem))
154                                         continue;
155                                 if (parentValue == null) {
156                                         unmergedProp.Value = sourceValue;
157                                         continue;
158                                 }
159
160                                 var parentElem = (ConfigurationElement) parentValue;
161                                 ConfigurationElement copy = (ConfigurationElement) unmergedProp.Value;
162                                 ElementUnmerge (copy, sourceElem, parentElem, saveMode);
163                         }
164                 }
165
166                 bool HasValue (ConfigurationElement element, string propName)
167                 {
168                         PropertyInformation info = element.ElementInformation.Properties [propName];
169                         return info != null && info.ValueOrigin != PropertyValueOrigin.Default;
170                 }
171
172                 object GetItem (ConfigurationElement element, string property)
173                 {
174                         PropertyInformation pi = ElementInformation.Properties [property];
175                         if (pi == null)
176                                 throw new InvalidOperationException ("Property '" + property + "' not found in configuration element");
177
178                         return pi.Value;
179                 }
180                 
181                 bool PropertyIsElement (PropertyInformation prop)
182                 {
183                         return (typeof(ConfigurationElement).IsAssignableFrom (prop.Type));
184                 }
185                 
186                 bool ElementIsModified (ConfigurationElement element)
187                 {
188                         return (bool) element.GetType ().GetMethod ("IsModified", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (element, new object [0]);
189                 }
190                 
191                 void ElementUnmerge (ConfigurationElement target, ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
192                 {
193                         target.GetType ().GetMethod ("Unmerge", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (target, new object [] {sourceElement, parentElement, saveMode});
194                 }
195 #endif
196         }
197
198 }
199