2010-05-27 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Web.Services / System.Web.Services.Configuration / WebServicesConfigurationSectionHandler.cs
blobe9cb549316c9beabaed5ff269dc4bf6e8728812b
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 #if NET_1_1
46 HttpSoap12 = 1 << 4,
47 HttpPostLocalhost = 1 << 5,
48 AnyHttpSoap = HttpSoap | HttpSoap12,
49 #endif
50 All = 0xFF
53 class WSConfig
55 #if !TARGET_JVM
56 volatile static WSConfig instance;
57 #else
58 static WSConfig instance {
59 get {
60 return (WSConfig)AppDomain.CurrentDomain.GetData("WSConfig.instance");
62 set {
63 AppDomain.CurrentDomain.SetData("WSConfig.instance", value);
67 #endif
68 WSProtocol protocols;
69 string wsdlHelpPage;
70 string filePath;
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)
79 if (parent == null)
80 return;
82 protocols = parent.protocols;
83 wsdlHelpPage = parent.wsdlHelpPage;
84 if (wsdlHelpPage != null)
85 filePath = parent.filePath;
86 else
87 filePath = context as string;
90 static WSProtocol ParseProtocol (string protoName, out string error)
92 WSProtocol proto;
93 error = null;
95 #if ONLY_1_1
96 switch (protoName) {
97 case "HttpSoap1.2":
98 protoName = "HttpSoap12";
99 break;
100 case "HttpSoap12":
101 protoName = null;
102 break;
104 #endif
105 try {
106 proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
107 } catch {
108 error = "Invalid protocol name";
109 return 0;
112 return proto;
115 // Methods to modify configuration values
116 public bool AddProtocol (string protoName, out string error)
118 if (protoName == "All") {
119 error = "Invalid protocol name";
120 return false;
123 WSProtocol proto = ParseProtocol (protoName, out error);
124 if (error != null)
125 return false;
127 protocols |= proto;
128 return true;
131 public bool RemoveProtocol (string protoName, out string error)
133 if (protoName == "All") {
134 error = "Invalid protocol name";
135 return false;
138 WSProtocol proto = ParseProtocol (protoName, out error);
139 if (error != null)
140 return false;
142 protocols &= ~proto;
143 return true;
146 public void ClearProtocol ()
148 protocols = 0;
151 // Methods to query/get configuration
152 public static bool IsSupported (WSProtocol proto)
154 return ((Instance.protocols & proto) == proto && (proto != 0) && (proto != WSProtocol.All));
157 // Properties
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 {
169 get {
170 //TODO: use HttpContext to get the configuration
171 if (instance != null)
172 return instance;
174 lock (lockobj) {
175 if (instance != null)
176 return instance;
178 instance = (WSConfig) ConfigurationSettings.GetConfig ("system.web/webServices");
181 return instance;
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
205 High,
209 class WSExtensionConfig
211 Type type;
212 int priority;
213 WSExtensionGroup group;
215 public Exception SetType (string typeName)
217 Exception exc = null;
219 try {
220 type = Type.GetType (typeName, true);
221 } catch (Exception e) {
222 exc = e;
225 return exc;
228 public Exception SetPriority (string prio)
230 if (prio == null || prio == "")
231 return null;
233 Exception exc = null;
234 try {
235 priority = Int32.Parse (prio);
236 } catch (Exception e) {
237 exc = e;
240 return exc;
243 public Exception SetGroup (string grp)
245 if (grp == null || grp == "")
246 return null;
248 Exception exc = null;
249 try {
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) {
254 exc = e;
257 return exc;
260 // Getters
261 public Type Type {
262 get { return type; }
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)
287 continue;
289 if (ntype != XmlNodeType.Element)
290 ThrowException ("Only elements allowed", child);
292 string name = child.Name;
293 if (name == "protocols") {
294 ConfigProtocols (child, config);
295 continue;
298 if (name == "soapExtensionTypes") {
299 ConfigSoapExtensionTypes (child, config.ExtensionTypes);
300 continue;
303 if (name == "soapExtensionReflectorTypes") {
304 ConfigSoapExtensionTypes (child, config.ExtensionReflectorTypes);
305 continue;
308 if (name == "soapExtensionImporterTypes") {
309 ConfigSoapExtensionTypes (child, config.ExtensionImporterTypes);
310 continue;
313 if (name == "serviceDescriptionFormatExtensionTypes") {
314 ConfigFormatExtensionTypes (child, config);
315 continue;
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;
325 continue;
328 ThrowException ("Unexpected element", child);
331 return config;
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)
343 continue;
345 if (ntype != XmlNodeType.Element)
346 ThrowException ("Only elements allowed", child);
348 string name = child.Name;
349 string error;
350 if (name == "add") {
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);
358 continue;
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);
369 continue;
372 if (name == "clear") {
373 if (child.Attributes != null && child.Attributes.Count != 0)
374 HandlersUtil.ThrowException ("Unrecognized attribute", child);
376 config.ClearProtocol ();
377 continue;
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)
393 continue;
395 if (ntype != XmlNodeType.Element)
396 ThrowException ("Only elements allowed", child);
398 string name = child.Name;
399 if (name == "add") {
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);
408 if (e != null)
409 ThrowException (e.Message, child);
411 e = wse.SetPriority (priority);
412 if (e != null)
413 ThrowException (e.Message, child);
415 e = wse.SetGroup (group);
416 if (e != null)
417 ThrowException (e.Message, child);
419 extensions.Add (wse);
420 continue;
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)
436 continue;
438 if (ntype != XmlNodeType.Element)
439 ThrowException ("Only elements allowed", child);
441 string name = child.Name;
442 if (name == "add") {
443 string typeName = AttValue ("name", child, false);
444 if (child.Attributes != null && child.Attributes.Count != 0)
445 HandlersUtil.ThrowException ("Unrecognized attribute", child);
447 try {
448 config.FormatExtensionTypes.Add (Type.GetType (typeName, true));
449 } catch (Exception e) {
450 ThrowException (e.Message, child);
452 continue;
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);
477 class HandlersUtil
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) {
491 if (optional)
492 return null;
494 ThrowException ("Required attribute not found: " + attKey, node);
497 XmlNode att = node.Attributes.RemoveNamedItem (attKey);
498 if (att == null) {
499 if (optional)
500 return null;
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);
510 return value;
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);