**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Web.Services / System.Web.Services.Configuration / WebServicesConfigurationSectionHandler.cs
blob10fe7602f9ed14c8763b3538472d3f78a456c808
1 //
2 // System.Web.Services.Configuration.WebServicesConfigurationSectionHandler
3 //
4 // Authors:
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2003 Ximian, Inc (http://www.ximian.com)
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Collections;
33 using System.Configuration;
34 using System.Xml;
36 namespace System.Web.Services.Configuration
38 [Flags]
39 enum WSProtocol
41 HttpSoap = 1,
42 HttpPost = 1 << 1,
43 HttpGet = 1 << 2,
44 Documentation = 1 << 3,
45 All = 0x0F
48 class WSConfig
50 static WSConfig instance;
51 WSProtocol protocols;
52 string wsdlHelpPage;
53 string filePath;
54 ArrayList extensionTypes = new ArrayList();
55 ArrayList extensionImporterTypes = new ArrayList();
56 ArrayList extensionReflectorTypes = new ArrayList();
57 ArrayList formatExtensionTypes = new ArrayList();
59 public WSConfig (WSConfig parent, object context)
61 if (parent == null)
62 return;
64 protocols = parent.protocols;
65 wsdlHelpPage = parent.wsdlHelpPage;
66 if (wsdlHelpPage != null)
67 filePath = parent.filePath;
68 else
69 filePath = context as string;
72 static WSProtocol ParseProtocol (string protoName, out string error)
74 WSProtocol proto;
75 error = null;
76 try {
77 proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
78 } catch {
79 error = "Invalid protocol name";
80 return 0;
83 return proto;
86 // Methods to modify configuration values
87 public bool AddProtocol (string protoName, out string error)
89 if (protoName == "All") {
90 error = "Invalid protocol name";
91 return false;
94 WSProtocol proto = ParseProtocol (protoName, out error);
95 if (error != null)
96 return false;
98 protocols |= proto;
99 return true;
102 public bool RemoveProtocol (string protoName, out string error)
104 if (protoName == "All") {
105 error = "Invalid protocol name";
106 return false;
109 WSProtocol proto = ParseProtocol (protoName, out error);
110 if (error != null)
111 return false;
113 protocols &= ~proto;
114 return true;
117 public void ClearProtocol ()
119 protocols = 0;
122 // Methods to query/get configuration
123 public static bool IsSupported (WSProtocol proto)
125 return ((Instance.protocols & proto) == proto && (proto != 0) && (proto != WSProtocol.All));
128 // Properties
129 public string WsdlHelpPage {
130 get { return wsdlHelpPage; }
131 set { wsdlHelpPage = value; }
134 public string ConfigFilePath {
135 get { return filePath; }
136 set { filePath = value; }
139 static public WSConfig Instance {
140 get {
141 //TODO: use HttpContext to get the configuration
142 if (instance != null)
143 return instance;
145 lock (typeof (WSConfig)) {
146 if (instance != null)
147 return instance;
149 instance = (WSConfig) ConfigurationSettings.GetConfig ("system.web/webServices");
152 return instance;
156 public ArrayList ExtensionTypes {
157 get { return extensionTypes; }
160 public ArrayList ExtensionImporterTypes {
161 get { return extensionImporterTypes; }
164 public ArrayList ExtensionReflectorTypes {
165 get { return extensionReflectorTypes; }
168 public ArrayList FormatExtensionTypes {
169 get { return formatExtensionTypes; }
174 enum WSExtensionGroup
176 High,
180 class WSExtensionConfig
182 Type type;
183 int priority;
184 WSExtensionGroup group;
186 public Exception SetType (string typeName)
188 Exception exc = null;
190 try {
191 type = Type.GetType (typeName, true);
192 } catch (Exception e) {
193 exc = e;
196 return exc;
199 public Exception SetPriority (string prio)
201 if (prio == null || prio == "")
202 return null;
204 Exception exc = null;
205 try {
206 priority = Int32.Parse (prio);
207 } catch (Exception e) {
208 exc = e;
211 return exc;
214 public Exception SetGroup (string grp)
216 if (grp == null || grp == "")
217 return null;
219 Exception exc = null;
220 try {
221 group = (WSExtensionGroup) Int32.Parse (grp);
222 if (group < WSExtensionGroup.High || group > WSExtensionGroup.Low)
223 throw new ArgumentOutOfRangeException ("group", "Must be 0 or 1");
224 } catch (Exception e) {
225 exc = e;
228 return exc;
231 // Getters
232 public Type Type {
233 get { return type; }
236 public int Priority {
237 get { return priority; }
240 public WSExtensionGroup Group {
241 get { return group; }
245 class WebServicesConfigurationSectionHandler : IConfigurationSectionHandler
247 public object Create (object parent, object context, XmlNode section)
249 WSConfig config = new WSConfig (parent as WSConfig, context);
251 if (section.Attributes != null && section.Attributes.Count != 0)
252 ThrowException ("Unrecognized attribute", section);
254 XmlNodeList nodes = section.ChildNodes;
255 foreach (XmlNode child in nodes) {
256 XmlNodeType ntype = child.NodeType;
257 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
258 continue;
260 if (ntype != XmlNodeType.Element)
261 ThrowException ("Only elements allowed", child);
263 string name = child.Name;
264 if (name == "protocols") {
265 ConfigProtocols (child, config);
266 continue;
269 if (name == "soapExtensionTypes") {
270 ConfigSoapExtensionTypes (child, config.ExtensionTypes);
271 continue;
274 if (name == "soapExtensionReflectorTypes") {
275 ConfigSoapExtensionTypes (child, config.ExtensionReflectorTypes);
276 continue;
279 if (name == "soapExtensionImporterTypes") {
280 ConfigSoapExtensionTypes (child, config.ExtensionImporterTypes);
281 continue;
284 if (name == "serviceDescriptionFormatExtensionTypes") {
285 ConfigFormatExtensionTypes (child, config);
286 continue;
289 if (name == "wsdlHelpGenerator") {
290 string href = AttValue ("href", child, false);
291 if (child.Attributes != null && child.Attributes.Count != 0)
292 HandlersUtil.ThrowException ("Unrecognized attribute", child);
294 config.ConfigFilePath = context as string;
295 config.WsdlHelpPage = href;
296 continue;
299 ThrowException ("Unexpected element", child);
302 return config;
305 static void ConfigProtocols (XmlNode section, WSConfig config)
307 if (section.Attributes != null && section.Attributes.Count != 0)
308 ThrowException ("Unrecognized attribute", section);
310 XmlNodeList nodes = section.ChildNodes;
311 foreach (XmlNode child in nodes) {
312 XmlNodeType ntype = child.NodeType;
313 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
314 continue;
316 if (ntype != XmlNodeType.Element)
317 ThrowException ("Only elements allowed", child);
319 string name = child.Name;
320 string error;
321 if (name == "add") {
322 string protoName = AttValue ("name", child, false);
323 if (child.Attributes != null && child.Attributes.Count != 0)
324 HandlersUtil.ThrowException ("Unrecognized attribute", child);
326 if (!config.AddProtocol (protoName, out error))
327 ThrowException (error, child);
329 continue;
332 if (name == "remove") {
333 string protoName = AttValue ("name", child, false);
334 if (child.Attributes != null && child.Attributes.Count != 0)
335 HandlersUtil.ThrowException ("Unrecognized attribute", child);
337 if (!config.RemoveProtocol (protoName, out error))
338 ThrowException (error, child);
340 continue;
343 if (name == "clear") {
344 if (child.Attributes != null && child.Attributes.Count != 0)
345 HandlersUtil.ThrowException ("Unrecognized attribute", child);
347 config.ClearProtocol ();
348 continue;
351 ThrowException ("Unexpected element", child);
355 static void ConfigSoapExtensionTypes (XmlNode section, ArrayList extensions)
357 if (section.Attributes != null && section.Attributes.Count != 0)
358 ThrowException ("Unrecognized attribute", section);
360 XmlNodeList nodes = section.ChildNodes;
361 foreach (XmlNode child in nodes) {
362 XmlNodeType ntype = child.NodeType;
363 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
364 continue;
366 if (ntype != XmlNodeType.Element)
367 ThrowException ("Only elements allowed", child);
369 string name = child.Name;
370 if (name == "add") {
371 string seType = AttValue ("type", child, false);
372 string priority = AttValue ("priority", child);
373 string group = AttValue ("group", child);
374 if (child.Attributes != null && child.Attributes.Count != 0)
375 HandlersUtil.ThrowException ("Unrecognized attribute", child);
377 WSExtensionConfig wse = new WSExtensionConfig ();
378 Exception e = wse.SetType (seType);
379 if (e != null)
380 ThrowException (e.Message, child);
382 e = wse.SetPriority (priority);
383 if (e != null)
384 ThrowException (e.Message, child);
386 e = wse.SetGroup (group);
387 if (e != null)
388 ThrowException (e.Message, child);
390 extensions.Add (wse);
391 continue;
394 ThrowException ("Unexpected element", child);
398 static void ConfigFormatExtensionTypes (XmlNode section, WSConfig config)
400 if (section.Attributes != null && section.Attributes.Count != 0)
401 ThrowException ("Unrecognized attribute", section);
403 XmlNodeList nodes = section.ChildNodes;
404 foreach (XmlNode child in nodes) {
405 XmlNodeType ntype = child.NodeType;
406 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
407 continue;
409 if (ntype != XmlNodeType.Element)
410 ThrowException ("Only elements allowed", child);
412 string name = child.Name;
413 if (name == "add") {
414 string typeName = AttValue ("name", child, false);
415 if (child.Attributes != null && child.Attributes.Count != 0)
416 HandlersUtil.ThrowException ("Unrecognized attribute", child);
418 try {
419 config.FormatExtensionTypes.Add (Type.GetType (typeName, true));
420 } catch (Exception e) {
421 ThrowException (e.Message, child);
423 continue;
426 ThrowException ("Unexpected element", child);
430 // To save some typing...
431 static string AttValue (string name, XmlNode node, bool optional)
433 return HandlersUtil.ExtractAttributeValue (name, node, optional);
436 static string AttValue (string name, XmlNode node)
438 return HandlersUtil.ExtractAttributeValue (name, node, true);
441 static void ThrowException (string message, XmlNode node)
443 HandlersUtil.ThrowException (message, node);
448 class HandlersUtil
450 private HandlersUtil ()
454 static internal string ExtractAttributeValue (string attKey, XmlNode node)
456 return ExtractAttributeValue (attKey, node, false);
459 static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
461 if (node.Attributes == null) {
462 if (optional)
463 return null;
465 ThrowException ("Required attribute not found: " + attKey, node);
468 XmlNode att = node.Attributes.RemoveNamedItem (attKey);
469 if (att == null) {
470 if (optional)
471 return null;
472 ThrowException ("Required attribute not found: " + attKey, node);
475 string value = att.Value;
476 if (value == String.Empty) {
477 string opt = optional ? "Optional" : "Required";
478 ThrowException (opt + " attribute is empty: " + attKey, node);
481 return value;
484 static internal void ThrowException (string msg, XmlNode node)
486 if (node != null && node.Name != String.Empty)
487 msg = msg + " (node name: " + node.Name + ") ";
488 throw new ConfigurationException (msg, node);