SoapDocumentationHandler.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //
  2. // System.Web.Services.Protocols.SoapDocumentationHandler.cs
  3. //
  4. // Author:
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // Copyright (C) Ximian, Inc. 2003
  8. //
  9. using System;
  10. using System.Web;
  11. using System.IO;
  12. using System.Xml.Serialization;
  13. using System.Xml.Schema;
  14. using System.Web.Services.Description;
  15. using System.Web.Services.Configuration;
  16. using System.CodeDom;
  17. using System.CodeDom.Compiler;
  18. using Microsoft.CSharp;
  19. using System.Web.UI;
  20. namespace System.Web.Services.Protocols
  21. {
  22. internal class SoapDocumentationHandler: WebServiceHandler
  23. {
  24. SoapTypeStubInfo _typeStubInfo;
  25. ServiceDescriptionCollection _descriptions;
  26. XmlSchemas _schemas;
  27. string _url;
  28. IHttpHandler _pageHandler = null;
  29. public SoapDocumentationHandler (Type type, HttpContext context): base (type)
  30. {
  31. _url = context.Request.Url.ToString();
  32. int i = _url.LastIndexOf ('?');
  33. if (i != -1) _url = _url.Substring (0,i);
  34. _typeStubInfo = (SoapTypeStubInfo) TypeStubManager.GetTypeStub (ServiceType, "Soap");
  35. HttpRequest req = context.Request;
  36. string key = null;
  37. if (req.QueryString.Count == 1)
  38. key = req.QueryString.GetKey(0).ToLower();
  39. if (key == "wsdl" || key == "schema" || key == "code")
  40. return;
  41. string help = WSConfig.Instance.WsdlHelpPage;
  42. string path = Path.GetDirectoryName (WSConfig.Instance.ConfigFilePath);
  43. string file = Path.GetFileName (WSConfig.Instance.ConfigFilePath);
  44. string appPath = AppDomain.CurrentDomain.GetData (".appPath").ToString ();
  45. string vpath;
  46. if (path.StartsWith (appPath)) {
  47. vpath = path.Substring (appPath.Length);
  48. vpath = vpath.Replace ("\\", "/");
  49. } else {
  50. vpath = "/";
  51. }
  52. if (vpath.EndsWith ("/"))
  53. vpath += help;
  54. else
  55. vpath += "/" + help;
  56. string physPath = Path.Combine (path, help);
  57. if (!File.Exists (physPath))
  58. throw new InvalidOperationException ("Documentation page '" + physPath + "' not found");
  59. _pageHandler = PageParser.GetCompiledPageInstance (vpath, physPath, context);
  60. }
  61. public override bool IsReusable
  62. {
  63. get { return false; }
  64. }
  65. public override void ProcessRequest (HttpContext context)
  66. {
  67. if (_pageHandler != null)
  68. {
  69. context.Items["wsdls"] = GetDescriptions ();
  70. context.Items["schemas"] = GetSchemas ();
  71. _pageHandler.ProcessRequest (context);
  72. }
  73. else
  74. {
  75. HttpRequest req = context.Request;
  76. string key = req.QueryString.GetKey(0).ToLower();
  77. if (key == "wsdl") GenerateWsdlDocument (context, req.QueryString ["wsdl"]);
  78. else if (key == "schema") GenerateSchema (context, req.QueryString ["schema"]);
  79. else if (key == "code") GenerateCode (context, req.QueryString ["code"]);
  80. else throw new Exception ("This should never happen");
  81. }
  82. }
  83. void GenerateWsdlDocument (HttpContext context, string wsdlId)
  84. {
  85. int di = 0;
  86. if (wsdlId != null && wsdlId != "") di = int.Parse (wsdlId);
  87. context.Response.ContentType = "text/xml; charset=utf-8";
  88. GetDescriptions() [di].Write (context.Response.OutputStream);
  89. }
  90. void GenerateSchema (HttpContext context, string schemaId)
  91. {
  92. int di = 0;
  93. if (schemaId != null && schemaId != "") di = int.Parse (schemaId);
  94. context.Response.ContentType = "text/xml; charset=utf-8";
  95. GetSchemas() [di].Write (context.Response.OutputStream);
  96. }
  97. void GenerateCode (HttpContext context, string langId)
  98. {
  99. context.Response.ContentType = "text/plain; charset=utf-8";
  100. CodeNamespace codeNamespace = new CodeNamespace();
  101. CodeCompileUnit codeUnit = new CodeCompileUnit();
  102. codeUnit.Namespaces.Add (codeNamespace);
  103. ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
  104. foreach (ServiceDescription sd in GetDescriptions ())
  105. importer.AddServiceDescription(sd, null, null);
  106. foreach (XmlSchema sc in GetSchemas())
  107. importer.Schemas.Add (sc);
  108. importer.Import(codeNamespace, codeUnit);
  109. if (langId == null || langId == "") langId = "cs";
  110. CodeDomProvider provider = GetProvider (langId);
  111. ICodeGenerator generator = provider.CreateGenerator();
  112. CodeGeneratorOptions options = new CodeGeneratorOptions();
  113. generator.GenerateCodeFromCompileUnit(codeUnit, context.Response.Output, options);
  114. }
  115. private CodeDomProvider GetProvider(string langId)
  116. {
  117. // FIXME these should be loaded dynamically using reflection
  118. CodeDomProvider provider;
  119. switch (langId.ToUpper())
  120. {
  121. case "CS":
  122. provider = new CSharpCodeProvider();
  123. break;
  124. default:
  125. throw new Exception("Unknown language: " + langId);
  126. }
  127. return provider;
  128. }
  129. internal ServiceDescriptionCollection GetDescriptions ()
  130. {
  131. if (_descriptions == null)
  132. {
  133. ServiceDescriptionReflector reflector = new ServiceDescriptionReflector ();
  134. reflector.Reflect (ServiceType,_url);
  135. _schemas = reflector.Schemas;
  136. _descriptions = reflector.ServiceDescriptions;
  137. }
  138. return _descriptions;
  139. }
  140. internal XmlSchemas GetSchemas()
  141. {
  142. GetDescriptions();
  143. return _schemas;
  144. }
  145. }
  146. }