Merge pull request #1296 from directhex/master
[mono.git] / mcs / tools / wsdl / MonoWSDL.cs
old mode 100755 (executable)
new mode 100644 (file)
index 2a1957d..430b225
@@ -7,7 +7,10 @@
 /// Copyright (C) 2003, Erik LeBel,\r
 ///\r
 \r
+#if !NET_2_0\r
+\r
 using System;\r
+using System.Collections.Specialized;\r
 using System.Xml;\r
 using System.Xml.Schema;\r
 using System.Collections;\r
@@ -17,6 +20,7 @@ using System.IO;
 using System.Net;\r
 using System.Web.Services.Description;\r
 using System.Web.Services.Discovery;\r
+using System.Reflection;\r
 \r
 using Microsoft.CSharp;\r
 \r
@@ -149,21 +153,25 @@ namespace Mono.WebServices
                                        Console.WriteLine ("WARNING: At least one operation is of an unsupported type and has been ignored");\r
                                hasWarnings = true;\r
                        }\r
-                       
-                       ServiceDescription rootDesc = null;
-                       foreach (ServiceDescription desc in descriptions) {
-                               if (desc.Services.Count > 0) {
-                                       rootDesc = desc;
-                                       break;
-                               }
-                       }
-                               \r
-                       if (rootDesc != null)\r
+                       \r
+                       string fileName = null;\r
+                       bool hasBindings = false;\r
+                       \r
+                       foreach (ServiceDescription desc in descriptions)\r
                        {\r
-                               string serviceName = rootDesc.Services[0].Name;\r
-                               WriteCodeUnit(codeUnit, serviceName);\r
+                               if (fileName == null && desc.Services.Count > 0)\r
+                                       fileName = desc.Services[0].Name;\r
+\r
+                               if (desc.Bindings.Count > 0 || desc.Services.Count > 0)\r
+                                       hasBindings = true;\r
                        }\r
                        \r
+                       if (fileName == null)\r
+                               fileName = "output";\r
+                       \r
+                       if (hasBindings)\r
+                               WriteCodeUnit (codeUnit, fileName);\r
+                       \r
                        return hasWarnings;\r
                }\r
                \r
@@ -212,23 +220,30 @@ namespace Mono.WebServices
                ///\r
                private CodeDomProvider GetProvider()\r
                {\r
-                       // FIXME these should be loaded dynamically using reflection\r
                        CodeDomProvider provider;\r
+                       Type type;\r
                        \r
-                       switch (language.ToUpper())\r
-                       {\r
-                           case "CS":\r
-                                   provider = new CSharpCodeProvider();\r
-                                   break;\r
-                           \r
-                               case "VB":\r
-                                       provider = new Microsoft.VisualBasic.VBCodeProvider();\r
-                                       break;\r
-                                       \r
-                           default:\r
-                                   throw new Exception("Unknow language");\r
+                       switch (language.ToUpper ()) {\r
+                       case "CS":\r
+                               provider = new CSharpCodeProvider ();\r
+                               break;\r
+                       case "VB":\r
+                               provider = new Microsoft.VisualBasic.VBCodeProvider ();\r
+                               break;\r
+                       case "BOO":\r
+                               type = Type.GetType("Boo.Lang.CodeDom.BooCodeProvider, Boo.Lang.CodeDom, Version=1.0.0.0, Culture=neutral, PublicKeyToken=32c39770e9a21a67");\r
+                               if (type != null){\r
+                                       return (CodeDomProvider) Activator.CreateInstance (type);\r
+                               }\r
+                               throw new Exception ("Boo.Lang.CodeDom.BooCodeProvider not available");\r
+                                                        \r
+                       default:\r
+                               type = Type.GetType(language);\r
+                               if (type != null) {\r
+                                       return (CodeDomProvider) Activator.CreateInstance (type);\r
+                               }       \r
+                               throw new Exception ("Unknown language");\r
                        }\r
-\r
                        return provider;\r
                }\r
        }\r
@@ -246,7 +261,9 @@ namespace Mono.WebServices
                        "wsdl [options] {path | URL} \n\n"\r
                        + "   -d, -domain:domain           Domain of username for server authentication.\n"\r
                        + "   -l, -language:language       Language of generated code. Allowed CS (default)\n"\r
-                       + "                                and VB.\n"\r
+                       + "                                and VB. You can also specify the fully qualified\n"\r
+                       + "                                name of a class that implements the\n"\r
+                       + "                                System.CodeDom.Compiler.CodeDomProvider Class.\n"\r
                        + "   -n, -namespace:ns            The namespace of the generated code, default\n"\r
                        + "                                namespace if none.\n"\r
                        + "   -nologo                      Surpress the startup logo.\n"\r
@@ -264,6 +281,9 @@ namespace Mono.WebServices
                        + "                                url for the generated WS proxy.\n"\r
                        + "   -baseurl, -appsettingbaseurl:url Base url to use when constructing the\n"\r
                        + "                                service url.\n"\r
+                       + "   -type:typename,assembly      Generate a proxy for a compiled web service\n"\r
+                       + "                                class. The URL parameter can be used to provide\n"\r
+                       + "                                the location of the service.\n"\r
                        + "   -sample:[binding/]operation  Display a sample SOAP request and response.\n"\r
                        + "   -?                           Display this message\n"\r
                        + "\n"\r
@@ -287,7 +307,8 @@ namespace Mono.WebServices
                string password;\r
                string domain;\r
                \r
-               string url;\r
+               StringCollection urls = new StringCollection ();\r
+               string className;\r
 \r
                ///\r
                /// <summary>\r
@@ -320,7 +341,7 @@ namespace Mono.WebServices
                        else\r
                        {\r
                                hasURL = true;\r
-                               url = argument;\r
+                               urls.Add (argument);\r
                                return;\r
                        }\r
                        \r
@@ -415,13 +436,24 @@ namespace Mono.WebServices
                                case "sample":\r
                                        sampleSoap = value;\r
                                        break;\r
-\r
+                                       \r
+                               case "type":\r
+                               case "t":\r
+                                       className = value;\r
+                                       break;\r
+                                       \r
                                case "?":\r
                                    help = true;\r
                                    break;\r
 \r
                                default:\r
-                                   throw new Exception("Unknown option " + option);\r
+                                       if (argument.StartsWith ("/") && argument.IndexOfAny (Path.InvalidPathChars) == -1) {\r
+                                               hasURL = true;\r
+                                               urls.Add (argument);\r
+                                               break;\r
+                                       }\r
+                                       else\r
+                                           throw new Exception("Unknown option '" + option + "'");\r
                        }\r
                }\r
                \r
@@ -490,28 +522,55 @@ namespace Mono.WebServices
                                if (noLogo == false)\r
                                        Console.WriteLine(ProductId);\r
                                \r
-                               if (help || !hasURL)\r
+                               if (help || (!hasURL && className == null))\r
                                {\r
                                        Console.WriteLine(UsageMessage);\r
                                        return 0;\r
                                }\r
                                \r
-                               DiscoveryClientProtocol dcc = CreateClient ();\r
-                                                               \r
-                               dcc.DiscoverAny (url);\r
-                               dcc.ResolveAll ();\r
-                               \r
-                               foreach (object doc in dcc.Documents.Values)\r
-                               {\r
-                                       if (doc is ServiceDescription)\r
-                                               descriptions.Add ((ServiceDescription)doc);\r
-                                       else if (doc is XmlSchema)\r
-                                               schemas.Add ((XmlSchema)doc);\r
+                               if (className == null) {\r
+                                       DiscoveryClientProtocol dcc = CreateClient ();\r
+\r
+                                       foreach (string urlEntry in urls) {\r
+                                               string url = urlEntry;\r
+                                               dcc.AllowAutoRedirect = true;\r
+                                               if (!url.StartsWith ("http://") && !url.StartsWith ("https://") && !url.StartsWith ("file://"))\r
+                                                       url = new Uri (Path.GetFullPath (url)).ToString ();\r
+                                                       \r
+                                               dcc.DiscoverAny (url);\r
+                                               dcc.ResolveAll ();\r
+                                       }\r
+\r
+                                       foreach (object doc in dcc.Documents.Values) {\r
+                                               if (doc is ServiceDescription)\r
+                                                       descriptions.Add ((ServiceDescription) doc);\r
+                                               else if (doc is XmlSchema)\r
+                                                       schemas.Add ((XmlSchema) doc);\r
+                                       }\r
+\r
+                                       if (descriptions.Count == 0) {\r
+                                               Console.WriteLine ("Warning: no classes were generated.");\r
+                                               return 0;\r
+                                       }\r
+                               } else {\r
+                                       string[] names = className.Split (',');\r
+                                       if (names.Length != 2) throw new Exception ("Invalid parameter value for 'type'");\r
+                                       string cls = names[0].Trim ();\r
+                                       string assembly = names[1].Trim ();\r
+                                       \r
+                                       Assembly asm = Assembly.LoadFrom (assembly);\r
+                                       Type t = asm.GetType (cls);\r
+                                       if (t == null) throw new Exception ("Type '" + cls + "' not found in assembly " + assembly);\r
+                                       ServiceDescriptionReflector reflector = new ServiceDescriptionReflector ();\r
+                                       foreach (string url in urls)\r
+                                               reflector.Reflect (t, url);\r
+                                       foreach (XmlSchema s in reflector.Schemas)\r
+                                               schemas.Add (s);\r
+                                               \r
+                                       foreach (ServiceDescription sd in reflector.ServiceDescriptions)\r
+                                               descriptions.Add (sd);\r
                                }\r
                                \r
-                               if (descriptions.Count == 0)\r
-                                       throw new Exception ("No WSDL document was found at the url " + url);\r
-                               \r
                                if (sampleSoap != null)\r
                                {\r
                                        ConsoleSampleGenerator.Generate (descriptions, schemas, sampleSoap, generator.Protocol);\r
@@ -519,10 +578,18 @@ namespace Mono.WebServices
                                }\r
                                \r
                                // generate the code\r
-                               if (generator.GenerateCode (descriptions, schemas))\r
-                                       return 1;\r
-                               else\r
-                                       return 0;\r
+                               generator.GenerateCode (descriptions, schemas);\r
+                               return 0;\r
+                       }\r
+                       catch (NullReferenceException e)\r
+                       {\r
+                               Console.WriteLine (e);\r
+                               return 2;\r
+                       }\r
+                       catch (InvalidCastException e)\r
+                       {\r
+                               Console.WriteLine (e);\r
+                               return 2;\r
                        }\r
                        catch (Exception exception)\r
                        {\r
@@ -544,4 +611,6 @@ namespace Mono.WebServices
                        return d.Run(args);\r
                }\r
        }\r
-}
+}\r
+\r
+#endif\r