WebServicesConfigurationSectionHandler.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. //
  2. // System.Web.Services.Configuration.WebServicesConfigurationSectionHandler
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. //
  7. // (C) 2003 Ximian, Inc (http://www.ximian.com)
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Configuration;
  12. using System.Xml;
  13. namespace System.Web.Services.Configuration
  14. {
  15. [Flags]
  16. enum WSProtocol
  17. {
  18. HttpSoap = 1,
  19. HttpPost = 1 << 1,
  20. HttpGet = 1 << 2,
  21. Documentation = 1 << 3,
  22. All = 0x0F
  23. }
  24. class WSConfig
  25. {
  26. static WSConfig instance;
  27. WSProtocol protocols;
  28. string wsdlHelpPage;
  29. ArrayList extensionTypes;
  30. public WSConfig (WSConfig parent)
  31. {
  32. if (parent == null)
  33. return;
  34. protocols = parent.protocols;
  35. wsdlHelpPage = parent.wsdlHelpPage;
  36. }
  37. static WSProtocol ParseProtocol (string protoName, out string error)
  38. {
  39. WSProtocol proto;
  40. error = null;
  41. try {
  42. proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
  43. } catch {
  44. error = "Invalid protocol name";
  45. return 0;
  46. }
  47. return proto;
  48. }
  49. // Methods to modify configuration values
  50. public bool AddProtocol (string protoName, out string error)
  51. {
  52. if (protoName == "All") {
  53. error = "Invalid protocol name";
  54. return false;
  55. }
  56. WSProtocol proto = ParseProtocol (protoName, out error);
  57. if (error != null)
  58. return false;
  59. protocols |= proto;
  60. return true;
  61. }
  62. public bool RemoveProtocol (string protoName, out string error)
  63. {
  64. if (protoName == "All") {
  65. error = "Invalid protocol name";
  66. return false;
  67. }
  68. WSProtocol proto = ParseProtocol (protoName, out error);
  69. if (error != null)
  70. return false;
  71. protocols &= ~proto;
  72. return true;
  73. }
  74. public void ClearProtocol ()
  75. {
  76. protocols = 0;
  77. }
  78. public void AddExtensionType (WSExtensionConfig wsExtension)
  79. {
  80. if (extensionTypes == null)
  81. extensionTypes = new ArrayList ();
  82. extensionTypes.Add (wsExtension);
  83. }
  84. // Methods to query/get configuration
  85. public static bool IsSupported (WSProtocol proto)
  86. {
  87. return ((Instance.protocols & proto) == proto && (proto != 0) && (proto != WSProtocol.All));
  88. }
  89. // Properties
  90. public string WsdlHelpPage {
  91. get { return wsdlHelpPage; }
  92. set { wsdlHelpPage = value; }
  93. }
  94. static public WSConfig Instance {
  95. get {
  96. //TODO: use HttpContext to get the configuration
  97. if (instance != null)
  98. return instance;
  99. lock (typeof (WSConfig)) {
  100. if (instance != null)
  101. return instance;
  102. instance = (WSConfig) ConfigurationSettings.GetConfig ("system.web/webServices");
  103. }
  104. return instance;
  105. }
  106. }
  107. public ArrayList ExtensionTypes {
  108. get { return extensionTypes; }
  109. }
  110. }
  111. enum WSExtensionGroup
  112. {
  113. High,
  114. Low
  115. }
  116. class WSExtensionConfig
  117. {
  118. Type type;
  119. int priority;
  120. WSExtensionGroup group;
  121. public Exception SetType (string typeName)
  122. {
  123. Exception exc = null;
  124. try {
  125. type = Type.GetType (typeName, true);
  126. } catch (Exception e) {
  127. exc = e;
  128. }
  129. return exc;
  130. }
  131. public Exception SetPriority (string prio)
  132. {
  133. if (prio == null || prio == "")
  134. return null;
  135. Exception exc = null;
  136. try {
  137. priority = Int32.Parse (prio);
  138. } catch (Exception e) {
  139. exc = e;
  140. }
  141. return exc;
  142. }
  143. public Exception SetGroup (string grp)
  144. {
  145. if (grp == null || grp == "")
  146. return null;
  147. Exception exc = null;
  148. try {
  149. group = (WSExtensionGroup) Int32.Parse (grp);
  150. if (group < WSExtensionGroup.Low || group > WSExtensionGroup.High)
  151. throw new ArgumentOutOfRangeException ("group", "Must be 0 or 1");
  152. } catch (Exception e) {
  153. exc = e;
  154. }
  155. return exc;
  156. }
  157. // Getters
  158. public Type Type {
  159. get { return type; }
  160. }
  161. public int Priority {
  162. get { return priority; }
  163. }
  164. public WSExtensionGroup Group {
  165. get { return group; }
  166. }
  167. }
  168. class WebServicesConfigurationSectionHandler : IConfigurationSectionHandler
  169. {
  170. [MonoTODO("Some nodes not supported, see below")]
  171. public object Create (object parent, object context, XmlNode section)
  172. {
  173. WSConfig config = new WSConfig (parent as WSConfig);
  174. if (section.Attributes != null && section.Attributes.Count != 0)
  175. ThrowException ("Unrecognized attribute", section);
  176. XmlNodeList nodes = section.ChildNodes;
  177. foreach (XmlNode child in nodes) {
  178. XmlNodeType ntype = child.NodeType;
  179. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  180. continue;
  181. if (ntype != XmlNodeType.Element)
  182. ThrowException ("Only elements allowed", child);
  183. string name = child.Name;
  184. if (name == "protocols") {
  185. ConfigProtocols (child, config);
  186. continue;
  187. }
  188. if (name == "soapExtensionTypes") {
  189. ConfigSoapExtensionTypes (child, config);
  190. continue;
  191. }
  192. if (name == "soapExtensionReflectorTypes") {
  193. //TODO: Not supported by now
  194. continue;
  195. }
  196. if (name == "soapExtensionImporterTypes") {
  197. //TODO: Not supported by now
  198. continue;
  199. }
  200. if (name == "serviceDescriptionFormatExtensionTypes") {
  201. //TODO: Not supported by now
  202. continue;
  203. }
  204. if (name == "wsdlHelpGenerator") {
  205. string href = AttValue ("href", child, false);
  206. if (child.Attributes != null && child.Attributes.Count != 0)
  207. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  208. config.WsdlHelpPage = href;
  209. continue;
  210. }
  211. ThrowException ("Unexpected element", child);
  212. }
  213. return config;
  214. }
  215. static void ConfigProtocols (XmlNode section, WSConfig config)
  216. {
  217. if (section.Attributes != null && section.Attributes.Count != 0)
  218. ThrowException ("Unrecognized attribute", section);
  219. XmlNodeList nodes = section.ChildNodes;
  220. foreach (XmlNode child in nodes) {
  221. XmlNodeType ntype = child.NodeType;
  222. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  223. continue;
  224. if (ntype != XmlNodeType.Element)
  225. ThrowException ("Only elements allowed", child);
  226. string name = child.Name;
  227. string error;
  228. if (name == "add") {
  229. string protoName = AttValue ("name", child, false);
  230. if (child.Attributes != null && child.Attributes.Count != 0)
  231. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  232. if (!config.AddProtocol (protoName, out error))
  233. ThrowException (error, child);
  234. continue;
  235. }
  236. if (name == "remove") {
  237. string protoName = AttValue ("name", child, false);
  238. if (child.Attributes != null && child.Attributes.Count != 0)
  239. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  240. if (!config.RemoveProtocol (protoName, out error))
  241. ThrowException (error, child);
  242. continue;
  243. }
  244. if (name == "clear") {
  245. if (child.Attributes != null && child.Attributes.Count != 0)
  246. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  247. config.ClearProtocol ();
  248. continue;
  249. }
  250. ThrowException ("Unexpected element", child);
  251. }
  252. }
  253. static void ConfigSoapExtensionTypes (XmlNode section, WSConfig config)
  254. {
  255. if (section.Attributes != null && section.Attributes.Count != 0)
  256. ThrowException ("Unrecognized attribute", section);
  257. XmlNodeList nodes = section.ChildNodes;
  258. foreach (XmlNode child in nodes) {
  259. XmlNodeType ntype = child.NodeType;
  260. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  261. continue;
  262. if (ntype != XmlNodeType.Element)
  263. ThrowException ("Only elements allowed", child);
  264. string name = child.Name;
  265. string error;
  266. if (name == "add") {
  267. string seType = AttValue ("type", child, false);
  268. string priority = AttValue ("priority", child);
  269. string group = AttValue ("group", child);
  270. if (child.Attributes != null && child.Attributes.Count != 0)
  271. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  272. WSExtensionConfig wse = new WSExtensionConfig ();
  273. Exception e = wse.SetType (seType);
  274. if (e != null)
  275. ThrowException (e.Message, child);
  276. e = wse.SetPriority (priority);
  277. if (e != null)
  278. ThrowException (e.Message, child);
  279. e = wse.SetGroup (group);
  280. if (e != null)
  281. ThrowException (e.Message, child);
  282. config.AddExtensionType (wse);
  283. continue;
  284. }
  285. ThrowException ("Unexpected element", child);
  286. }
  287. }
  288. // To save some typing...
  289. static string AttValue (string name, XmlNode node, bool optional)
  290. {
  291. return HandlersUtil.ExtractAttributeValue (name, node, optional);
  292. }
  293. static string AttValue (string name, XmlNode node)
  294. {
  295. return HandlersUtil.ExtractAttributeValue (name, node, true);
  296. }
  297. static void ThrowException (string message, XmlNode node)
  298. {
  299. HandlersUtil.ThrowException (message, node);
  300. }
  301. //
  302. }
  303. class HandlersUtil
  304. {
  305. private HandlersUtil ()
  306. {
  307. }
  308. static internal string ExtractAttributeValue (string attKey, XmlNode node)
  309. {
  310. return ExtractAttributeValue (attKey, node, false);
  311. }
  312. static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
  313. {
  314. if (node.Attributes == null) {
  315. if (optional)
  316. return null;
  317. ThrowException ("Required attribute not found: " + attKey, node);
  318. }
  319. XmlNode att = node.Attributes.RemoveNamedItem (attKey);
  320. if (att == null) {
  321. if (optional)
  322. return null;
  323. ThrowException ("Required attribute not found: " + attKey, node);
  324. }
  325. string value = att.Value;
  326. if (value == String.Empty) {
  327. string opt = optional ? "Optional" : "Required";
  328. ThrowException (opt + " attribute is empty: " + attKey, node);
  329. }
  330. return value;
  331. }
  332. static internal void ThrowException (string msg, XmlNode node)
  333. {
  334. if (node != null && node.Name != String.Empty)
  335. msg = msg + " (node name: " + node.Name + ") ";
  336. throw new ConfigurationException (msg, node);
  337. }
  338. }
  339. }