1 //
2 // System.Configuration.SectionInfo.cs
3 //
4 // Authors:
5 //	Lluis Sanchez (lluis@novell.com)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 //
26 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
27 //
28 
29 using System;
30 using System.Collections;
31 using System.Collections.Specialized;
32 using System.Xml;
33 using System.Text;
34 using System.IO;
35 
36 namespace System.Configuration
37 {
38 	internal class SectionInfo: ConfigInfo
39 	{
40 		bool allowLocation = true;
41 		bool requirePermission = true;
42 		bool restartOnExternalChanges;
43 		ConfigurationAllowDefinition allowDefinition = ConfigurationAllowDefinition.Everywhere;
44 		ConfigurationAllowExeDefinition allowExeDefinition = ConfigurationAllowExeDefinition.MachineToApplication;
45 
SectionInfo()46 		public SectionInfo ()
47 		{
48 		}
49 
SectionInfo(string sectionName, SectionInformation info)50 		public SectionInfo (string sectionName, SectionInformation info)
51 		{
52 			Name = sectionName;
53 			TypeName = info.Type;
54 			this.allowLocation = info.AllowLocation;
55 			this.allowDefinition = info.AllowDefinition;
56 			this.allowExeDefinition = info.AllowExeDefinition;
57 			this.requirePermission = info.RequirePermission;
58 			this.restartOnExternalChanges = info.RestartOnExternalChanges;
59 		}
60 
CreateInstance()61 		public override object CreateInstance ()
62 		{
63 			object ob = base.CreateInstance ();
64 			ConfigurationSection sec = ob as ConfigurationSection;
65 			if (sec != null) {
66 				sec.SectionInformation.AllowLocation = allowLocation;
67 				sec.SectionInformation.AllowDefinition = allowDefinition;
68 				sec.SectionInformation.AllowExeDefinition = allowExeDefinition;
69 				sec.SectionInformation.RequirePermission = requirePermission;
70 				sec.SectionInformation.RestartOnExternalChanges = restartOnExternalChanges;
71 				sec.SectionInformation.SetName (Name);
72 			}
73 			return ob;
74 		}
75 
HasDataContent(Configuration config)76 		public override bool HasDataContent (Configuration config)
77 		{
78 			return config.GetSectionInstance (this, false) != null || config.GetSectionXml (this) != null;
79 		}
80 
HasConfigContent(Configuration cfg)81 		public override bool HasConfigContent (Configuration cfg)
82 		{
83 			return StreamName == cfg.FileName;
84 		}
85 
ReadConfig(Configuration cfg, string streamName, XmlReader reader)86 		public override void ReadConfig (Configuration cfg, string streamName, XmlReader reader)
87 		{
88 			StreamName = streamName;
89 			ConfigHost = cfg.ConfigHost;
90 
91 			while (reader.MoveToNextAttribute ()) {
92 				switch (reader.Name)
93 				{
94 					case "allowLocation":
95 						string allowLoc = reader.Value;
96 						allowLocation = (allowLoc == "true");
97 						if (!allowLocation && allowLoc != "false")
98 							ThrowException ("Invalid attribute value", reader);
99 						break;
100 
101 					case "allowDefinition":
102 						string allowDef = reader.Value;
103 						try {
104 							allowDefinition = (ConfigurationAllowDefinition) Enum.Parse (
105 									   typeof (ConfigurationAllowDefinition), allowDef);
106 						} catch {
107 							ThrowException ("Invalid attribute value", reader);
108 						}
109 						break;
110 
111 					case "allowExeDefinition":
112 						string allowExeDef = reader.Value;
113 						try {
114 							allowExeDefinition = (ConfigurationAllowExeDefinition) Enum.Parse (
115 									   typeof (ConfigurationAllowExeDefinition), allowExeDef);
116 						} catch {
117 							ThrowException ("Invalid attribute value", reader);
118 						}
119 						break;
120 
121 					case "type":
122 						TypeName = reader.Value;
123 						break;
124 
125 					case "name":
126 						Name = reader.Value;
127 						if (Name == "location")
128 							ThrowException ("location is a reserved section name", reader);
129 						break;
130 
131 					case "requirePermission":
132 						string reqPerm = reader.Value;
133 						bool reqPermValue = (reqPerm == "true");
134 						if (!reqPermValue && reqPerm != "false")
135 							ThrowException ("Invalid attribute value", reader);
136 						requirePermission = reqPermValue;
137 						break;
138 
139 					case "restartOnExternalChanges":
140 						string restart = reader.Value;
141 						bool restartValue = (restart == "true");
142 						if (!restartValue && restart != "false")
143 							ThrowException ("Invalid attribute value", reader);
144 						restartOnExternalChanges = restartValue;
145 						break;
146 
147 					default:
148 						ThrowException (String.Format ("Unrecognized attribute: {0}", reader.Name), reader);
149 						break;
150 				}
151 			}
152 
153 			if (Name == null || TypeName == null)
154 				ThrowException ("Required attribute missing", reader);
155 
156 			reader.MoveToElement();
157 			reader.Skip ();
158 		}
159 
WriteConfig(Configuration cfg, XmlWriter writer, ConfigurationSaveMode mode)160 		public override void WriteConfig (Configuration cfg, XmlWriter writer, ConfigurationSaveMode mode)
161 		{
162 			writer.WriteStartElement ("section");
163 			writer.WriteAttributeString ("name", Name);
164 			writer.WriteAttributeString ("type", TypeName);
165 			if (!allowLocation)
166 				writer.WriteAttributeString ("allowLocation", "false");
167 			if (allowDefinition != ConfigurationAllowDefinition.Everywhere)
168 				writer.WriteAttributeString ("allowDefinition", allowDefinition.ToString ());
169 			if (allowExeDefinition != ConfigurationAllowExeDefinition.MachineToApplication)
170 				writer.WriteAttributeString ("allowExeDefinition", allowExeDefinition.ToString ());
171 			if (!requirePermission)
172 				writer.WriteAttributeString ("requirePermission", "false");
173 			writer.WriteEndElement ();
174 		}
175 
ReadData(Configuration config, XmlReader reader, bool overrideAllowed)176 		public override void ReadData (Configuration config, XmlReader reader, bool overrideAllowed)
177 		{
178 			if (!config.HasFile && !allowLocation)
179 				throw new ConfigurationErrorsException ("The configuration section <" + Name + "> cannot be defined inside a <location> element.", reader);
180 			if (!config.ConfigHost.IsDefinitionAllowed (config.ConfigPath, allowDefinition, allowExeDefinition)) {
181 				object ctx = allowExeDefinition != ConfigurationAllowExeDefinition.MachineToApplication ? (object) allowExeDefinition : (object) allowDefinition;
182 				throw new ConfigurationErrorsException ("The section <" + Name + "> can't be defined in this configuration file (the allowed definition context is '" + ctx + "').", reader);
183 			}
184 			if (config.GetSectionXml (this) != null)
185 				ThrowException ("The section <" + Name + "> is defined more than once in the same configuration file.", reader);
186 			config.SetSectionXml (this, reader.ReadOuterXml ());
187 		}
188 
WriteData(Configuration config, XmlWriter writer, ConfigurationSaveMode mode)189 		public override void WriteData (Configuration config, XmlWriter writer, ConfigurationSaveMode mode)
190 		{
191 			string xml;
192 
193 			ConfigurationSection section = config.GetSectionInstance (this, false);
194 			if (section != null) {
195 				ConfigurationSection parentSection = config.Parent != null ? config.Parent.GetSectionInstance (this, false) : null;
196 				xml = section.SerializeSection (parentSection, Name, mode);
197 
198 				string externalDataXml = section.ExternalDataXml;
199 				string filePath = config.FilePath;
200 
201 				if (!String.IsNullOrEmpty (filePath) && !String.IsNullOrEmpty (externalDataXml)) {
202 					string path = Path.Combine (Path.GetDirectoryName (filePath), section.SectionInformation.ConfigSource);
203 					using (StreamWriter sw = new StreamWriter (path)) {
204 						sw.Write (externalDataXml);
205 					}
206 				}
207 
208 				if (section.SectionInformation.IsProtected) {
209 					StringBuilder sb = new StringBuilder ();
210 					sb.AppendFormat ("<{0} configProtectionProvider=\"{1}\">\n",
211 							 Name,
212 							 section.SectionInformation.ProtectionProvider.Name);
213 					sb.Append (config.ConfigHost.EncryptSection (xml,
214 										     section.SectionInformation.ProtectionProvider,
215 										     ProtectedConfiguration.Section));
216 					sb.AppendFormat ("</{0}>", Name);
217 					xml = sb.ToString ();
218 				}
219 			}
220 			else {
221 				xml = config.GetSectionXml (this);
222 			}
223 
224 			if (!string.IsNullOrEmpty (xml)) {
225 				writer.WriteRaw (xml);
226 /*				XmlTextReader tr = new XmlTextReader (new StringReader (xml));
227 				writer.WriteNode (tr, true);
228 				tr.Close ();*/
229 			}
230 		}
231 
Merge(ConfigInfo data)232 		internal override void Merge (ConfigInfo data)
233 		{}
234 
HasValues(Configuration config, ConfigurationSaveMode mode)235 		internal override bool HasValues (Configuration config, ConfigurationSaveMode mode)
236 		{
237 			var section = config.GetSectionInstance (this, false);
238 			if (section == null)
239 				return false;
240 
241 			var parent = config.Parent != null ? config.Parent.GetSectionInstance (this, false) : null;
242 			return section.HasValues (parent, mode);
243 		}
244 
ResetModified(Configuration config)245 		internal override void ResetModified (Configuration config)
246 		{
247 			ConfigurationSection section = config.GetSectionInstance (this, false);
248 			if (section != null)
249 				section.ResetModified ();
250 		}
251 	}
252 }
253 
254