WebServicesConfigurationSectionHandler.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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. string filePath;
  30. ArrayList extensionTypes = new ArrayList();
  31. ArrayList extensionImporterTypes = new ArrayList();
  32. ArrayList extensionReflectorTypes = new ArrayList();
  33. ArrayList formatExtensionTypes = new ArrayList();
  34. public WSConfig (WSConfig parent, object context)
  35. {
  36. if (parent == null)
  37. return;
  38. protocols = parent.protocols;
  39. wsdlHelpPage = parent.wsdlHelpPage;
  40. if (wsdlHelpPage != null)
  41. filePath = parent.filePath;
  42. else
  43. filePath = context as string;
  44. }
  45. static WSProtocol ParseProtocol (string protoName, out string error)
  46. {
  47. WSProtocol proto;
  48. error = null;
  49. try {
  50. proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
  51. } catch {
  52. error = "Invalid protocol name";
  53. return 0;
  54. }
  55. return proto;
  56. }
  57. // Methods to modify configuration values
  58. public bool AddProtocol (string protoName, out string error)
  59. {
  60. if (protoName == "All") {
  61. error = "Invalid protocol name";
  62. return false;
  63. }
  64. WSProtocol proto = ParseProtocol (protoName, out error);
  65. if (error != null)
  66. return false;
  67. protocols |= proto;
  68. return true;
  69. }
  70. public bool RemoveProtocol (string protoName, out string error)
  71. {
  72. if (protoName == "All") {
  73. error = "Invalid protocol name";
  74. return false;
  75. }
  76. WSProtocol proto = ParseProtocol (protoName, out error);
  77. if (error != null)
  78. return false;
  79. protocols &= ~proto;
  80. return true;
  81. }
  82. public void ClearProtocol ()
  83. {
  84. protocols = 0;
  85. }
  86. // Methods to query/get configuration
  87. public static bool IsSupported (WSProtocol proto)
  88. {
  89. return ((Instance.protocols & proto) == proto && (proto != 0) && (proto != WSProtocol.All));
  90. }
  91. // Properties
  92. public string WsdlHelpPage {
  93. get { return wsdlHelpPage; }
  94. set { wsdlHelpPage = value; }
  95. }
  96. public string ConfigFilePath {
  97. get { return filePath; }
  98. set { filePath = value; }
  99. }
  100. static public WSConfig Instance {
  101. get {
  102. //TODO: use HttpContext to get the configuration
  103. if (instance != null)
  104. return instance;
  105. lock (typeof (WSConfig)) {
  106. if (instance != null)
  107. return instance;
  108. instance = (WSConfig) ConfigurationSettings.GetConfig ("system.web/webServices");
  109. }
  110. return instance;
  111. }
  112. }
  113. public ArrayList ExtensionTypes {
  114. get { return extensionTypes; }
  115. }
  116. public ArrayList ExtensionImporterTypes {
  117. get { return extensionImporterTypes; }
  118. }
  119. public ArrayList ExtensionReflectorTypes {
  120. get { return extensionReflectorTypes; }
  121. }
  122. public ArrayList FormatExtensionTypes {
  123. get { return formatExtensionTypes; }
  124. }
  125. }
  126. enum WSExtensionGroup
  127. {
  128. High,
  129. Low
  130. }
  131. class WSExtensionConfig
  132. {
  133. Type type;
  134. int priority;
  135. WSExtensionGroup group;
  136. public Exception SetType (string typeName)
  137. {
  138. Exception exc = null;
  139. try {
  140. type = Type.GetType (typeName, true);
  141. } catch (Exception e) {
  142. exc = e;
  143. }
  144. return exc;
  145. }
  146. public Exception SetPriority (string prio)
  147. {
  148. if (prio == null || prio == "")
  149. return null;
  150. Exception exc = null;
  151. try {
  152. priority = Int32.Parse (prio);
  153. } catch (Exception e) {
  154. exc = e;
  155. }
  156. return exc;
  157. }
  158. public Exception SetGroup (string grp)
  159. {
  160. if (grp == null || grp == "")
  161. return null;
  162. Exception exc = null;
  163. try {
  164. group = (WSExtensionGroup) Int32.Parse (grp);
  165. if (group < WSExtensionGroup.High || group > WSExtensionGroup.Low)
  166. throw new ArgumentOutOfRangeException ("group", "Must be 0 or 1");
  167. } catch (Exception e) {
  168. exc = e;
  169. }
  170. return exc;
  171. }
  172. // Getters
  173. public Type Type {
  174. get { return type; }
  175. }
  176. public int Priority {
  177. get { return priority; }
  178. }
  179. public WSExtensionGroup Group {
  180. get { return group; }
  181. }
  182. }
  183. class WebServicesConfigurationSectionHandler : IConfigurationSectionHandler
  184. {
  185. public object Create (object parent, object context, XmlNode section)
  186. {
  187. WSConfig config = new WSConfig (parent as WSConfig, context);
  188. if (section.Attributes != null && section.Attributes.Count != 0)
  189. ThrowException ("Unrecognized attribute", section);
  190. XmlNodeList nodes = section.ChildNodes;
  191. foreach (XmlNode child in nodes) {
  192. XmlNodeType ntype = child.NodeType;
  193. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  194. continue;
  195. if (ntype != XmlNodeType.Element)
  196. ThrowException ("Only elements allowed", child);
  197. string name = child.Name;
  198. if (name == "protocols") {
  199. ConfigProtocols (child, config);
  200. continue;
  201. }
  202. if (name == "soapExtensionTypes") {
  203. ConfigSoapExtensionTypes (child, config.ExtensionTypes);
  204. continue;
  205. }
  206. if (name == "soapExtensionReflectorTypes") {
  207. ConfigSoapExtensionTypes (child, config.ExtensionReflectorTypes);
  208. continue;
  209. }
  210. if (name == "soapExtensionImporterTypes") {
  211. ConfigSoapExtensionTypes (child, config.ExtensionImporterTypes);
  212. continue;
  213. }
  214. if (name == "serviceDescriptionFormatExtensionTypes") {
  215. ConfigFormatExtensionTypes (child, config);
  216. continue;
  217. }
  218. if (name == "wsdlHelpGenerator") {
  219. string href = AttValue ("href", child, false);
  220. if (child.Attributes != null && child.Attributes.Count != 0)
  221. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  222. config.ConfigFilePath = context as string;
  223. config.WsdlHelpPage = href;
  224. continue;
  225. }
  226. ThrowException ("Unexpected element", child);
  227. }
  228. return config;
  229. }
  230. static void ConfigProtocols (XmlNode section, WSConfig config)
  231. {
  232. if (section.Attributes != null && section.Attributes.Count != 0)
  233. ThrowException ("Unrecognized attribute", section);
  234. XmlNodeList nodes = section.ChildNodes;
  235. foreach (XmlNode child in nodes) {
  236. XmlNodeType ntype = child.NodeType;
  237. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  238. continue;
  239. if (ntype != XmlNodeType.Element)
  240. ThrowException ("Only elements allowed", child);
  241. string name = child.Name;
  242. string error;
  243. if (name == "add") {
  244. string protoName = AttValue ("name", child, false);
  245. if (child.Attributes != null && child.Attributes.Count != 0)
  246. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  247. if (!config.AddProtocol (protoName, out error))
  248. ThrowException (error, child);
  249. continue;
  250. }
  251. if (name == "remove") {
  252. string protoName = AttValue ("name", child, false);
  253. if (child.Attributes != null && child.Attributes.Count != 0)
  254. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  255. if (!config.RemoveProtocol (protoName, out error))
  256. ThrowException (error, child);
  257. continue;
  258. }
  259. if (name == "clear") {
  260. if (child.Attributes != null && child.Attributes.Count != 0)
  261. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  262. config.ClearProtocol ();
  263. continue;
  264. }
  265. ThrowException ("Unexpected element", child);
  266. }
  267. }
  268. static void ConfigSoapExtensionTypes (XmlNode section, ArrayList extensions)
  269. {
  270. if (section.Attributes != null && section.Attributes.Count != 0)
  271. ThrowException ("Unrecognized attribute", section);
  272. XmlNodeList nodes = section.ChildNodes;
  273. foreach (XmlNode child in nodes) {
  274. XmlNodeType ntype = child.NodeType;
  275. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  276. continue;
  277. if (ntype != XmlNodeType.Element)
  278. ThrowException ("Only elements allowed", child);
  279. string name = child.Name;
  280. string error;
  281. if (name == "add") {
  282. string seType = AttValue ("type", child, false);
  283. string priority = AttValue ("priority", child);
  284. string group = AttValue ("group", child);
  285. if (child.Attributes != null && child.Attributes.Count != 0)
  286. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  287. WSExtensionConfig wse = new WSExtensionConfig ();
  288. Exception e = wse.SetType (seType);
  289. if (e != null)
  290. ThrowException (e.Message, child);
  291. e = wse.SetPriority (priority);
  292. if (e != null)
  293. ThrowException (e.Message, child);
  294. e = wse.SetGroup (group);
  295. if (e != null)
  296. ThrowException (e.Message, child);
  297. extensions.Add (wse);
  298. continue;
  299. }
  300. ThrowException ("Unexpected element", child);
  301. }
  302. }
  303. static void ConfigFormatExtensionTypes (XmlNode section, WSConfig config)
  304. {
  305. if (section.Attributes != null && section.Attributes.Count != 0)
  306. ThrowException ("Unrecognized attribute", section);
  307. XmlNodeList nodes = section.ChildNodes;
  308. foreach (XmlNode child in nodes) {
  309. XmlNodeType ntype = child.NodeType;
  310. if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
  311. continue;
  312. if (ntype != XmlNodeType.Element)
  313. ThrowException ("Only elements allowed", child);
  314. string name = child.Name;
  315. string error;
  316. if (name == "add") {
  317. string typeName = AttValue ("name", child, false);
  318. if (child.Attributes != null && child.Attributes.Count != 0)
  319. HandlersUtil.ThrowException ("Unrecognized attribute", child);
  320. try {
  321. config.FormatExtensionTypes.Add (Type.GetType (typeName, true));
  322. } catch (Exception e) {
  323. ThrowException (e.Message, child);
  324. }
  325. continue;
  326. }
  327. ThrowException ("Unexpected element", child);
  328. }
  329. }
  330. // To save some typing...
  331. static string AttValue (string name, XmlNode node, bool optional)
  332. {
  333. return HandlersUtil.ExtractAttributeValue (name, node, optional);
  334. }
  335. static string AttValue (string name, XmlNode node)
  336. {
  337. return HandlersUtil.ExtractAttributeValue (name, node, true);
  338. }
  339. static void ThrowException (string message, XmlNode node)
  340. {
  341. HandlersUtil.ThrowException (message, node);
  342. }
  343. //
  344. }
  345. class HandlersUtil
  346. {
  347. private HandlersUtil ()
  348. {
  349. }
  350. static internal string ExtractAttributeValue (string attKey, XmlNode node)
  351. {
  352. return ExtractAttributeValue (attKey, node, false);
  353. }
  354. static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
  355. {
  356. if (node.Attributes == null) {
  357. if (optional)
  358. return null;
  359. ThrowException ("Required attribute not found: " + attKey, node);
  360. }
  361. XmlNode att = node.Attributes.RemoveNamedItem (attKey);
  362. if (att == null) {
  363. if (optional)
  364. return null;
  365. ThrowException ("Required attribute not found: " + attKey, node);
  366. }
  367. string value = att.Value;
  368. if (value == String.Empty) {
  369. string opt = optional ? "Optional" : "Required";
  370. ThrowException (opt + " attribute is empty: " + attKey, node);
  371. }
  372. return value;
  373. }
  374. static internal void ThrowException (string msg, XmlNode node)
  375. {
  376. if (node != null && node.Name != String.Empty)
  377. msg = msg + " (node name: " + node.Name + ") ";
  378. throw new ConfigurationException (msg, node);
  379. }
  380. }
  381. }