2 // System.Web.Services.Configuration.WebServicesConfigurationSectionHandler
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2003 Ximian, Inc (http://www.ximian.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
32 using System.Collections;
33 using System.Configuration;
36 namespace System.Web.Services.Configuration
44 Documentation = 1 << 3,
46 HttpPostLocalhost = 1 << 5,
47 AnyHttpSoap = HttpSoap | HttpSoap12,
54 volatile static WSConfig instance;
56 static WSConfig instance {
58 return (WSConfig)AppDomain.CurrentDomain.GetData("WSConfig.instance");
61 AppDomain.CurrentDomain.SetData("WSConfig.instance", value);
69 ArrayList extensionTypes = new ArrayList();
70 ArrayList extensionImporterTypes = new ArrayList();
71 ArrayList extensionReflectorTypes = new ArrayList();
72 ArrayList formatExtensionTypes = new ArrayList();
73 static readonly object lockobj = new object ();
75 public WSConfig (WSConfig parent, object context)
80 protocols = parent.protocols;
81 wsdlHelpPage = parent.wsdlHelpPage;
82 if (wsdlHelpPage != null)
83 filePath = parent.filePath;
85 filePath = context as string;
88 static WSProtocol ParseProtocol (string protoName, out string error)
96 protoName = "HttpSoap12";
104 proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
106 error = "Invalid protocol name";
113 // Methods to modify configuration values
114 public bool AddProtocol (string protoName, out string error)
116 if (protoName == "All") {
117 error = "Invalid protocol name";
121 WSProtocol proto = ParseProtocol (protoName, out error);
129 public bool RemoveProtocol (string protoName, out string error)
131 if (protoName == "All") {
132 error = "Invalid protocol name";
136 WSProtocol proto = ParseProtocol (protoName, out error);
144 public void ClearProtocol ()
149 // Methods to query/get configuration
150 public static bool IsSupported (WSProtocol proto)
152 return ((Instance.protocols & proto) == proto && (proto != 0) && (proto != WSProtocol.All));
156 public string WsdlHelpPage {
157 get { return wsdlHelpPage; }
158 set { wsdlHelpPage = value; }
161 public string ConfigFilePath {
162 get { return filePath; }
163 set { filePath = value; }
166 static public WSConfig Instance {
168 //TODO: use HttpContext to get the configuration
169 if (instance != null)
173 if (instance != null)
176 instance = (WSConfig) ConfigurationSettings.GetConfig ("system.web/webServices");
183 public ArrayList ExtensionTypes {
184 get { return extensionTypes; }
187 public ArrayList ExtensionImporterTypes {
188 get { return extensionImporterTypes; }
191 public ArrayList ExtensionReflectorTypes {
192 get { return extensionReflectorTypes; }
195 public ArrayList FormatExtensionTypes {
196 get { return formatExtensionTypes; }
201 enum WSExtensionGroup
207 class WSExtensionConfig
211 WSExtensionGroup group;
213 public Exception SetType (string typeName)
215 Exception exc = null;
218 type = Type.GetType (typeName, true);
219 } catch (Exception e) {
226 public Exception SetPriority (string prio)
228 if (prio == null || prio == "")
231 Exception exc = null;
233 priority = Int32.Parse (prio);
234 } catch (Exception e) {
241 public Exception SetGroup (string grp)
243 if (grp == null || grp == "")
246 Exception exc = null;
248 group = (WSExtensionGroup) Int32.Parse (grp);
249 if (group < WSExtensionGroup.High || group > WSExtensionGroup.Low)
250 throw new ArgumentOutOfRangeException ("group", "Must be 0 or 1");
251 } catch (Exception e) {
263 public int Priority {
264 get { return priority; }
267 public WSExtensionGroup Group {
268 get { return group; }
272 class WebServicesConfigurationSectionHandler : IConfigurationSectionHandler
274 public object Create (object parent, object context, XmlNode section)
276 WSConfig config = new WSConfig (parent as WSConfig, context);
278 if (section.Attributes != null && section.Attributes.Count != 0)
279 ThrowException ("Unrecognized attribute", section);
281 XmlNodeList nodes = section.ChildNodes;
282 foreach (XmlNode child in nodes) {
283 XmlNodeType ntype = child.NodeType;
284 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
287 if (ntype != XmlNodeType.Element)
288 ThrowException ("Only elements allowed", child);
290 string name = child.Name;
291 if (name == "protocols") {
292 ConfigProtocols (child, config);
296 if (name == "soapExtensionTypes") {
297 ConfigSoapExtensionTypes (child, config.ExtensionTypes);
301 if (name == "soapExtensionReflectorTypes") {
302 ConfigSoapExtensionTypes (child, config.ExtensionReflectorTypes);
306 if (name == "soapExtensionImporterTypes") {
307 ConfigSoapExtensionTypes (child, config.ExtensionImporterTypes);
311 if (name == "serviceDescriptionFormatExtensionTypes") {
312 ConfigFormatExtensionTypes (child, config);
316 if (name == "wsdlHelpGenerator") {
317 string href = AttValue ("href", child, false);
318 if (child.Attributes != null && child.Attributes.Count != 0)
319 HandlersUtil.ThrowException ("Unrecognized attribute", child);
321 config.ConfigFilePath = context as string;
322 config.WsdlHelpPage = href;
326 ThrowException ("Unexpected element", child);
332 static void ConfigProtocols (XmlNode section, WSConfig config)
334 if (section.Attributes != null && section.Attributes.Count != 0)
335 ThrowException ("Unrecognized attribute", section);
337 XmlNodeList nodes = section.ChildNodes;
338 foreach (XmlNode child in nodes) {
339 XmlNodeType ntype = child.NodeType;
340 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
343 if (ntype != XmlNodeType.Element)
344 ThrowException ("Only elements allowed", child);
346 string name = child.Name;
349 string protoName = AttValue ("name", child, false);
350 if (child.Attributes != null && child.Attributes.Count != 0)
351 HandlersUtil.ThrowException ("Unrecognized attribute", child);
353 if (!config.AddProtocol (protoName, out error))
354 ThrowException (error, child);
359 if (name == "remove") {
360 string protoName = AttValue ("name", child, false);
361 if (child.Attributes != null && child.Attributes.Count != 0)
362 HandlersUtil.ThrowException ("Unrecognized attribute", child);
364 if (!config.RemoveProtocol (protoName, out error))
365 ThrowException (error, child);
370 if (name == "clear") {
371 if (child.Attributes != null && child.Attributes.Count != 0)
372 HandlersUtil.ThrowException ("Unrecognized attribute", child);
374 config.ClearProtocol ();
378 ThrowException ("Unexpected element", child);
382 static void ConfigSoapExtensionTypes (XmlNode section, ArrayList extensions)
384 if (section.Attributes != null && section.Attributes.Count != 0)
385 ThrowException ("Unrecognized attribute", section);
387 XmlNodeList nodes = section.ChildNodes;
388 foreach (XmlNode child in nodes) {
389 XmlNodeType ntype = child.NodeType;
390 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
393 if (ntype != XmlNodeType.Element)
394 ThrowException ("Only elements allowed", child);
396 string name = child.Name;
398 string seType = AttValue ("type", child, false);
399 string priority = AttValue ("priority", child);
400 string group = AttValue ("group", child);
401 if (child.Attributes != null && child.Attributes.Count != 0)
402 HandlersUtil.ThrowException ("Unrecognized attribute", child);
404 WSExtensionConfig wse = new WSExtensionConfig ();
405 Exception e = wse.SetType (seType);
407 ThrowException (e.Message, child);
409 e = wse.SetPriority (priority);
411 ThrowException (e.Message, child);
413 e = wse.SetGroup (group);
415 ThrowException (e.Message, child);
417 extensions.Add (wse);
421 ThrowException ("Unexpected element", child);
425 static void ConfigFormatExtensionTypes (XmlNode section, WSConfig config)
427 if (section.Attributes != null && section.Attributes.Count != 0)
428 ThrowException ("Unrecognized attribute", section);
430 XmlNodeList nodes = section.ChildNodes;
431 foreach (XmlNode child in nodes) {
432 XmlNodeType ntype = child.NodeType;
433 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
436 if (ntype != XmlNodeType.Element)
437 ThrowException ("Only elements allowed", child);
439 string name = child.Name;
441 string typeName = AttValue ("name", child, false);
442 if (child.Attributes != null && child.Attributes.Count != 0)
443 HandlersUtil.ThrowException ("Unrecognized attribute", child);
446 config.FormatExtensionTypes.Add (Type.GetType (typeName, true));
447 } catch (Exception e) {
448 ThrowException (e.Message, child);
453 ThrowException ("Unexpected element", child);
457 // To save some typing...
458 static string AttValue (string name, XmlNode node, bool optional)
460 return HandlersUtil.ExtractAttributeValue (name, node, optional);
463 static string AttValue (string name, XmlNode node)
465 return HandlersUtil.ExtractAttributeValue (name, node, true);
468 static void ThrowException (string message, XmlNode node)
470 HandlersUtil.ThrowException (message, node);
477 private HandlersUtil ()
481 static internal string ExtractAttributeValue (string attKey, XmlNode node)
483 return ExtractAttributeValue (attKey, node, false);
486 static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
488 if (node.Attributes == null) {
492 ThrowException ("Required attribute not found: " + attKey, node);
495 XmlNode att = node.Attributes.RemoveNamedItem (attKey);
499 ThrowException ("Required attribute not found: " + attKey, node);
502 string value = att.Value;
503 if (value == String.Empty) {
504 string opt = optional ? "Optional" : "Required";
505 ThrowException (opt + " attribute is empty: " + attKey, node);
511 static internal void ThrowException (string msg, XmlNode node)
513 if (node != null && node.Name != String.Empty)
514 msg = msg + " (node name: " + node.Name + ") ";
515 throw new ConfigurationException (msg, node);