// (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;
using System.Xml;
using System.Reflection;
using System.Net;
-using System.Web.Services.Description;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Metadata;
+using System.Runtime.Serialization;
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;
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;
WriteServiceBinding (tw, st);
*/
foreach (ServiceType st in services)
- WriteServiceBinding (tw, st);
+ WriteServiceBinding (tw, st, dataTypes);
// Service element
foreach (ServiceType st in services)
{
-// if (st.Url == null) continue;
WriteServiceType (tw, st);
}
tw.WriteEndElement ();
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 ();
}
- void WriteServiceBinding (XmlTextWriter tw, ServiceType st)
+ void WriteServiceBinding (XmlTextWriter tw, ServiceType st, Hashtable dataTypes)
{
Type type = st.ObjectType;
string typeName = type.Name;
if (sb.Length != 0) sb.Append (" ");
sb.Append (par.Name);
}
- tw.WriteAttributeString ("parameterOreder", sb.ToString ());
+ tw.WriteAttributeString ("parameterOrder", sb.ToString ());
tw.WriteStartElement ("input", MetaData.WsdlNamespace);
tw.WriteAttributeString ("name", met.Name + "Request");
tw.WriteAttributeString ("transport", "http://schemas.xmlsoap.org/soap/http");
tw.WriteEndElement ();
- if (type.IsInterface)
- {
- tw.WriteStartElement ("suds", "interface", MetaData.SudsNamespace);
- tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
- if (type.BaseType != null && type.BaseType != typeof(object))
- tw.WriteAttributeString ("extends", GetQualifiedXmlType (tw, type.BaseType, null));
- }
- else
+ WriteTypeSuds (tw, type);
+
+ SchemaInfo sinfo = (SchemaInfo) dataTypes [GetXmlNamespace (type,null)];
+ if (sinfo != null && !sinfo.SudsGenerated)
{
- tw.WriteStartElement ("suds", "class", MetaData.SudsNamespace);
- tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
-
- if (isService)
- {
- if (type.IsMarshalByRef) {
- tw.WriteAttributeString ("rootType", "MarshalByRefObject");
- }
- else {
- tw.WriteAttributeString ("rootType", "Delegate");
- }
-
- if (type.BaseType != typeof(MarshalByRefObject))
- tw.WriteAttributeString ("extends", GetQualifiedXmlType (tw, type.BaseType, null));
- }
+ foreach (Type dt in sinfo.Types)
+ WriteTypeSuds (tw, dt);
+ sinfo.SudsGenerated = true;
}
- tw.WriteEndElement ();
if (isService)
{
tw.WriteEndElement (); // binding
}
+ void WriteTypeSuds (XmlTextWriter tw, Type type)
+ {
+ if (type.IsArray || type.IsEnum)
+ {
+ return;
+ }
+ else if (type.IsInterface)
+ {
+ tw.WriteStartElement ("suds", "interface", MetaData.SudsNamespace);
+ tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
+ foreach (Type interf in type.GetInterfaces ()) {
+ tw.WriteStartElement ("suds","extends", MetaData.SudsNamespace);
+ tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, interf, null));
+ tw.WriteEndElement ();
+ }
+ }
+ else if (type.IsValueType)
+ {
+ tw.WriteStartElement ("suds", "struct", MetaData.SudsNamespace);
+ tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
+ if (type.BaseType != typeof(ValueType))
+ tw.WriteAttributeString ("extends", GetQualifiedXmlType (tw, type.BaseType, null));
+ }
+ else
+ {
+ tw.WriteStartElement ("suds", "class", MetaData.SudsNamespace);
+ tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, type, null));
+
+ if (IsService (type))
+ {
+ if (type.IsMarshalByRef)
+ tw.WriteAttributeString ("rootType", "MarshalByRefObject");
+ else
+ tw.WriteAttributeString ("rootType", "Delegate");
+
+ if (type.BaseType != typeof(MarshalByRefObject))
+ tw.WriteAttributeString ("extends", GetQualifiedXmlType (tw, type.BaseType, null));
+
+ if (type.IsMarshalByRef) {
+ foreach (Type interf in type.GetInterfaces ()) {
+ tw.WriteStartElement ("suds","implements", MetaData.SudsNamespace);
+ tw.WriteAttributeString ("type", GetQualifiedXmlType (tw, interf, null));
+ tw.WriteEndElement ();
+ }
+ }
+ }
+ else if (typeof(ISerializable).IsAssignableFrom (type))
+ tw.WriteAttributeString ("rootType", "ISerializable");
+
+ }
+ tw.WriteEndElement (); // suds
+ }
+
void WriteMessageBindingBody (XmlTextWriter tw, Type t)
{
tw.WriteStartElement ("soap", "body", MetaData.SoapNamespace);
tw.WriteStartElement ("complexType", MetaData.SchemaNamespace);
tw.WriteAttributeString ("name", GetXmlType (type));
- if (type.BaseType != null && type.BaseType != typeof(object))
+ if (type.BaseType != null && type.BaseType != typeof(object) && type.BaseType != typeof(ValueType))
tw.WriteAttributeString ("base", GetQualifiedXmlType (tw, type.BaseType, null));
FieldInfo[] fields = type.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
}
else
{
- name = GetXsdType (type);
+ name = GetXsdType (type);
if (name != null) return "xsd:" + name;
if (!SoapServices.GetXmlTypeForInteropType (type, out name, out ns))
{
string name = null, ns;
- if (!type.IsEnum)
- name = GetXsdType (type);
-
+ name = GetXsdType (type);
if (name != null) return name;
if (SoapServices.GetXmlTypeForInteropType (type, out name, out ns))
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))
{
if (!IsService (t))
{
+ if (!t.IsSerializable) return;
+
string ns = GetXmlNamespace (t, containerType);
SchemaInfo sinfo = (SchemaInfo) types [ns];
if (sinfo == null)
{
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);
}
}
}
static string GetXsdType (Type type)
{
+ if (type.IsEnum) return null;
+
switch (Type.GetTypeCode (type))
{
case TypeCode.Boolean: return "boolean";
{
public ArrayList Types = new ArrayList ();
public ArrayList Imports = new ArrayList ();
+ public bool SudsGenerated;
}
}