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,
47 HttpPostLocalhost = 1 << 5,
48 AnyHttpSoap = HttpSoap | HttpSoap12,
56 volatile static WSConfig instance;
58 static WSConfig instance {
60 return (WSConfig)AppDomain.CurrentDomain.GetData("WSConfig.instance");
63 AppDomain.CurrentDomain.SetData("WSConfig.instance", value);
71 ArrayList extensionTypes = new ArrayList();
72 ArrayList extensionImporterTypes = new ArrayList();
73 ArrayList extensionReflectorTypes = new ArrayList();
74 ArrayList formatExtensionTypes = new ArrayList();
75 static readonly object lockobj = new object ();
77 public WSConfig (WSConfig parent, object context)
82 protocols = parent.protocols;
83 wsdlHelpPage = parent.wsdlHelpPage;
84 if (wsdlHelpPage != null)
85 filePath = parent.filePath;
87 filePath = context as string;
90 static WSProtocol ParseProtocol (string protoName, out string error)
98 protoName = "HttpSoap12";
106 proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
108 error = "Invalid protocol name";
115 // Methods to modify configuration values
116 public bool AddProtocol (string protoName, out string error)
118 if (protoName == "All") {
119 error = "Invalid protocol name";
123 WSProtocol proto = ParseProtocol (protoName, out error);
131 public bool RemoveProtocol (string protoName, out string error)
133 if (protoName == "All") {
134 error = "Invalid protocol name";
138 WSProtocol proto = ParseProtocol (protoName, out error);
146 public void ClearProtocol ()
151 // Methods to query/get configuration
152 public static bool IsSupported (WSProtocol proto)
154 return ((Instance.protocols & proto) == proto && (proto != 0) && (proto != WSProtocol.All));
158 public string WsdlHelpPage {
159 get { return wsdlHelpPage; }
160 set { wsdlHelpPage = value; }
163 public string ConfigFilePath {
164 get { return filePath; }
165 set { filePath = value; }
168 static public WSConfig Instance {
170 //TODO: use HttpContext to get the configuration
171 if (instance != null)
175 if (instance != null)
178 instance = (WSConfig) ConfigurationSettings.GetConfig ("system.web/webServices");
185 public ArrayList ExtensionTypes {
186 get { return extensionTypes; }
189 public ArrayList ExtensionImporterTypes {
190 get { return extensionImporterTypes; }
193 public ArrayList ExtensionReflectorTypes {
194 get { return extensionReflectorTypes; }
197 public ArrayList FormatExtensionTypes {
198 get { return formatExtensionTypes; }
203 enum WSExtensionGroup
209 class WSExtensionConfig
213 WSExtensionGroup group;
215 public Exception SetType (string typeName)
217 Exception exc = null;
220 type = Type.GetType (typeName, true);
221 } catch (Exception e) {
228 public Exception SetPriority (string prio)
230 if (prio == null || prio == "")
233 Exception exc = null;
235 priority = Int32.Parse (prio);
236 } catch (Exception e) {
243 public Exception SetGroup (string grp)
245 if (grp == null || grp == "")
248 Exception exc = null;
250 group = (WSExtensionGroup) Int32.Parse (grp);
251 if (group < WSExtensionGroup.High || group > WSExtensionGroup.Low)
252 throw new ArgumentOutOfRangeException ("group", "Must be 0 or 1");
253 } catch (Exception e) {
265 public int Priority {
266 get { return priority; }
269 public WSExtensionGroup Group {
270 get { return group; }
274 class WebServicesConfigurationSectionHandler : IConfigurationSectionHandler
276 public object Create (object parent, object context, XmlNode section)
278 WSConfig config = new WSConfig (parent as WSConfig, context);
280 if (section.Attributes != null && section.Attributes.Count != 0)
281 ThrowException ("Unrecognized attribute", section);
283 XmlNodeList nodes = section.ChildNodes;
284 foreach (XmlNode child in nodes) {
285 XmlNodeType ntype = child.NodeType;
286 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
289 if (ntype != XmlNodeType.Element)
290 ThrowException ("Only elements allowed", child);
292 string name = child.Name;
293 if (name == "protocols") {
294 ConfigProtocols (child, config);
298 if (name == "soapExtensionTypes") {
299 ConfigSoapExtensionTypes (child, config.ExtensionTypes);
303 if (name == "soapExtensionReflectorTypes") {
304 ConfigSoapExtensionTypes (child, config.ExtensionReflectorTypes);
308 if (name == "soapExtensionImporterTypes") {
309 ConfigSoapExtensionTypes (child, config.ExtensionImporterTypes);
313 if (name == "serviceDescriptionFormatExtensionTypes") {
314 ConfigFormatExtensionTypes (child, config);
318 if (name == "wsdlHelpGenerator") {
319 string href = AttValue ("href", child, false);
320 if (child.Attributes != null && child.Attributes.Count != 0)
321 HandlersUtil.ThrowException ("Unrecognized attribute", child);
323 config.ConfigFilePath = context as string;
324 config.WsdlHelpPage = href;
328 ThrowException ("Unexpected element", child);
334 static void ConfigProtocols (XmlNode section, WSConfig config)
336 if (section.Attributes != null && section.Attributes.Count != 0)
337 ThrowException ("Unrecognized attribute", section);
339 XmlNodeList nodes = section.ChildNodes;
340 foreach (XmlNode child in nodes) {
341 XmlNodeType ntype = child.NodeType;
342 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
345 if (ntype != XmlNodeType.Element)
346 ThrowException ("Only elements allowed", child);
348 string name = child.Name;
351 string protoName = AttValue ("name", child, false);
352 if (child.Attributes != null && child.Attributes.Count != 0)
353 HandlersUtil.ThrowException ("Unrecognized attribute", child);
355 if (!config.AddProtocol (protoName, out error))
356 ThrowException (error, child);
361 if (name == "remove") {
362 string protoName = AttValue ("name", child, false);
363 if (child.Attributes != null && child.Attributes.Count != 0)
364 HandlersUtil.ThrowException ("Unrecognized attribute", child);
366 if (!config.RemoveProtocol (protoName, out error))
367 ThrowException (error, child);
372 if (name == "clear") {
373 if (child.Attributes != null && child.Attributes.Count != 0)
374 HandlersUtil.ThrowException ("Unrecognized attribute", child);
376 config.ClearProtocol ();
380 ThrowException ("Unexpected element", child);
384 static void ConfigSoapExtensionTypes (XmlNode section, ArrayList extensions)
386 if (section.Attributes != null && section.Attributes.Count != 0)
387 ThrowException ("Unrecognized attribute", section);
389 XmlNodeList nodes = section.ChildNodes;
390 foreach (XmlNode child in nodes) {
391 XmlNodeType ntype = child.NodeType;
392 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
395 if (ntype != XmlNodeType.Element)
396 ThrowException ("Only elements allowed", child);
398 string name = child.Name;
400 string seType = AttValue ("type", child, false);
401 string priority = AttValue ("priority", child);
402 string group = AttValue ("group", child);
403 if (child.Attributes != null && child.Attributes.Count != 0)
404 HandlersUtil.ThrowException ("Unrecognized attribute", child);
406 WSExtensionConfig wse = new WSExtensionConfig ();
407 Exception e = wse.SetType (seType);
409 ThrowException (e.Message, child);
411 e = wse.SetPriority (priority);
413 ThrowException (e.Message, child);
415 e = wse.SetGroup (group);
417 ThrowException (e.Message, child);
419 extensions.Add (wse);
423 ThrowException ("Unexpected element", child);
427 static void ConfigFormatExtensionTypes (XmlNode section, WSConfig config)
429 if (section.Attributes != null && section.Attributes.Count != 0)
430 ThrowException ("Unrecognized attribute", section);
432 XmlNodeList nodes = section.ChildNodes;
433 foreach (XmlNode child in nodes) {
434 XmlNodeType ntype = child.NodeType;
435 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
438 if (ntype != XmlNodeType.Element)
439 ThrowException ("Only elements allowed", child);
441 string name = child.Name;
443 string typeName = AttValue ("name", child, false);
444 if (child.Attributes != null && child.Attributes.Count != 0)
445 HandlersUtil.ThrowException ("Unrecognized attribute", child);
448 config.FormatExtensionTypes.Add (Type.GetType (typeName, true));
449 } catch (Exception e) {
450 ThrowException (e.Message, child);
455 ThrowException ("Unexpected element", child);
459 // To save some typing...
460 static string AttValue (string name, XmlNode node, bool optional)
462 return HandlersUtil.ExtractAttributeValue (name, node, optional);
465 static string AttValue (string name, XmlNode node)
467 return HandlersUtil.ExtractAttributeValue (name, node, true);
470 static void ThrowException (string message, XmlNode node)
472 HandlersUtil.ThrowException (message, node);
479 private HandlersUtil ()
483 static internal string ExtractAttributeValue (string attKey, XmlNode node)
485 return ExtractAttributeValue (attKey, node, false);
488 static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
490 if (node.Attributes == null) {
494 ThrowException ("Required attribute not found: " + attKey, node);
497 XmlNode att = node.Attributes.RemoveNamedItem (attKey);
501 ThrowException ("Required attribute not found: " + attKey, node);
504 string value = att.Value;
505 if (value == String.Empty) {
506 string opt = optional ? "Optional" : "Required";
507 ThrowException (opt + " attribute is empty: " + attKey, node);
513 static internal void ThrowException (string msg, XmlNode node)
515 if (node != null && node.Name != String.Empty)
516 msg = msg + " (node name: " + node.Name + ") ";
517 throw new ConfigurationException (msg, node);