Merge pull request #2025 from sawachika-kenji/patch-1
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.MetadataServices / MetaDataExporter.cs
index 3296bbc77ee1844e260d365d9dbdacd78af0defe..a23d2a0d725550cd5e8e1afdd18faa36d1920aba 100644 (file)
@@ -7,6 +7,27 @@
 // (C) 2003 Novell, Inc
 //
 
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System.Collections;
 using System.IO;
 using System.Text;
@@ -29,7 +50,10 @@ namespace System.Runtime.Remoting.MetadataServices
                        if (servicetypes.Length == 0) return;
                        Type maint = servicetypes [0].ObjectType;
                        
-                       ArrayList services = FindServices (servicetypes);
+                       Hashtable dataTypes = new Hashtable (); 
+                       ArrayList services = new ArrayList ();
+                       FindTypes (servicetypes, dataTypes, services);
+                       
                        if (services.Count > 0)
                                maint = ((ServiceType) services[0]).ObjectType;
                        
@@ -49,7 +73,6 @@ namespace System.Runtime.Remoting.MetadataServices
                        tw.WriteAttributeString ("xmlns", "soap", MetaData.XmlnsNamespace, MetaData.SoapNamespace);
                        
                        int nums = 0;
-                       Hashtable dataTypes = FindDataTypes (servicetypes);
                        foreach (DictionaryEntry entry in dataTypes)
                        {
                                string ns = (string) entry.Key;
@@ -107,7 +130,6 @@ namespace System.Runtime.Remoting.MetadataServices
 
                        foreach (ServiceType st in services)
                        {
-//                             if (st.Url == null) continue;
                                WriteServiceType (tw, st);
                        }
                        tw.WriteEndElement ();
@@ -123,9 +145,14 @@ namespace System.Runtime.Remoting.MetadataServices
                        tw.WriteStartElement ("port", MetaData.WsdlNamespace);
                        tw.WriteAttributeString ("name", GetPortName (st.ObjectType));
                        tw.WriteAttributeString ("binding", "tns:" + GetBindingName (st.ObjectType));
-                       tw.WriteStartElement ("soap","address", MetaData.SoapNamespace);
-                       tw.WriteAttributeString ("location", st.Url);
-                       tw.WriteEndElement ();
+                       
+                       if (st.Url != null)
+                       {
+                               tw.WriteStartElement ("soap","address", MetaData.SoapNamespace);
+                               tw.WriteAttributeString ("location", st.Url);
+                               tw.WriteEndElement ();
+                       }
+                       
                        tw.WriteEndElement ();
                }
                
@@ -221,7 +248,7 @@ namespace System.Runtime.Remoting.MetadataServices
                        WriteTypeSuds (tw, type);
                        
                        SchemaInfo sinfo = (SchemaInfo) dataTypes [GetXmlNamespace (type,null)];
-                       if (!sinfo.SudsGenerated)
+                       if (sinfo != null && !sinfo.SudsGenerated)
                        {
                                foreach (Type dt in sinfo.Types)
                                        WriteTypeSuds (tw, dt);
@@ -371,7 +398,7 @@ namespace System.Runtime.Remoting.MetadataServices
                {
                        tw.WriteStartElement ("simpleType", MetaData.SchemaNamespace);
                        tw.WriteAttributeString ("name", GetXmlType (type));
-                       tw.WriteAttributeString ("suds", "enumType", MetaData.SudsNamespace, GetQualifiedXmlType (tw, type.UnderlyingSystemType, null));
+                       tw.WriteAttributeString ("suds", "enumType", MetaData.SudsNamespace, GetQualifiedXmlType (tw, EnumToUnderlying (type), null));
                        tw.WriteStartElement ("restriction", MetaData.SchemaNamespace);
                        tw.WriteAttributeString ("base", "xsd:string");
                        
@@ -530,15 +557,25 @@ namespace System.Runtime.Remoting.MetadataServices
                        return t.Name + "Binding";
                }
                
-               Hashtable FindDataTypes (ServiceType[] servicetypes)
+               void FindTypes (ServiceType[] servicetypes, Hashtable dataTypes, ArrayList services)
                {
-                       Hashtable types = new Hashtable ();
+                       ArrayList mbrTypes = new ArrayList();
+                       
                        foreach (ServiceType st in servicetypes)
-                               FindDataTypes (st.ObjectType, null, types);
-                       return types;
+                               FindDataTypes (st.ObjectType, null, dataTypes, mbrTypes);
+                               
+                       foreach (Type mbrType in mbrTypes)
+                       {
+                               ServiceType stFound = null;
+                               foreach (ServiceType st in servicetypes)
+                                       if (mbrType == st.ObjectType) stFound = st;
+                                       
+                               if (stFound != null) services.Add (stFound);
+                               else services.Add (new ServiceType (mbrType));
+                       }
                }
                
-               void FindDataTypes (Type t, Type containerType, Hashtable types)
+               void FindDataTypes (Type t, Type containerType, Hashtable types, ArrayList services)
                {
                        if (IsSystemType (t))
                        {
@@ -569,20 +606,21 @@ namespace System.Runtime.Remoting.MetadataServices
                                {
                                        string fns = GetXmlNamespace (fi.FieldType, t);
                                        if (!sinfo.Imports.Contains (fns)) sinfo.Imports.Add (fns);
-                                       FindDataTypes (fi.FieldType, t, types);
+                                       FindDataTypes (fi.FieldType, t, types, services);
                                }
                        }
                        else
                        {
+                               if (services.Contains (t)) return;
+                               services.Add (t);
+                               
                                foreach (MethodInfo met in t.GetMethods (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
                                {
                                        ParameterInfo[] pars = met.GetParameters ();
                                        foreach (ParameterInfo par in pars)
-                                               if (!par.ParameterType.IsMarshalByRef)
-                                                       FindDataTypes (par.ParameterType, t, types);
+                                               FindDataTypes (par.ParameterType, t, types, services);
                                                        
-                                       if (!met.ReturnType.IsMarshalByRef)
-                                               FindDataTypes (met.ReturnType, t, types);
+                                       FindDataTypes (met.ReturnType, t, types, services);
                                }
                        }
                }
@@ -627,6 +665,38 @@ namespace System.Runtime.Remoting.MetadataServices
                                
                        return null;
                }
+               
+               //
+               // This is needed, because enumerations from assemblies
+               // do not report their underlyingtype, but they report
+               // themselves
+               //
+               public static Type EnumToUnderlying (Type t)
+               {
+                       TypeCode tc = Type.GetTypeCode (t);
+       
+                       switch (tc){
+                       case TypeCode.Boolean:
+                               return typeof (bool);
+                       case TypeCode.Byte:
+                               return typeof (byte);
+                       case TypeCode.SByte:
+                               return typeof (sbyte);
+                       case TypeCode.Int16:
+                               return typeof (short);
+                       case TypeCode.UInt16:
+                               return typeof (ushort);
+                       case TypeCode.Int32:
+                               return typeof (int);
+                       case TypeCode.UInt32:
+                               return typeof (uint);
+                       case TypeCode.Int64:
+                               return typeof (long);
+                       case TypeCode.UInt64:
+                               return typeof (ulong);
+                       }
+                       throw new Exception ("Unhandled typecode in enum " + tc + " from " + t.AssemblyQualifiedName);
+               }
        }
        
        class SchemaInfo